# Sort elements by frequency | Set 2

Given an array of integers, sort the array according to frequency of elements. For example, if the input array is {2, 3, 2, 4, 5, 12, 2, 3, 3, 3, 12}, then modify the array to {3, 3, 3, 3, 2, 2, 2, 12, 12, 4, 5}.

In the previous post, we have discussed all methods for sorting according to frequency. In this post, method 2 is discussed in detail and C++ implementation for the same is provided.

Following is detailed algorithm.

- Create a BST and while creating BST maintain the count i,e frequency of each coming element in same BST. This step may take O(nLogn) time if a self balancing BST is used.
- Do Inorder traversal of BST and store every element and count of each element in an auxiliary array. Let us call the auxiliary array as ‘count[]’. Note that every element of this array is element and frequency pair. This step takes O(n) time.
- Sort ‘count[]’ according to frequency of the elements. This step takes O(nLohn) time if a O(nLogn) sorting algorithm is used.
- Traverse through the sorted array ‘count[]’. For each element x, print it ‘freq’ times where ‘freq’ is frequency of x. This step takes O(n) time.

The overall time complexity of the algorithm can be minimum **O(nLogn)** if we use a **O(nLogn)** sorting algorithm and use a self-balancing BST with **O(Logn)** insert operation.

Following is the implementation of the above algorithm.

`// Implementation of above algorithm in C++. ` `#include <iostream> ` `#include <stdlib.h> ` `using` `namespace` `std; ` ` ` `/* A BST node has data, freq, left and right pointers */` `struct` `BSTNode ` `{ ` ` ` `struct` `BSTNode *left; ` ` ` `int` `data; ` ` ` `int` `freq; ` ` ` `struct` `BSTNode *right; ` `}; ` ` ` `// A structure to store data and its frequency ` `struct` `dataFreq ` `{ ` ` ` `int` `data; ` ` ` `int` `freq; ` `}; ` ` ` `/* Function for qsort() implementation. Compare frequencies to ` ` ` `sort the array according to decreasing order of frequency */` `int` `compare(` `const` `void` `*a, ` `const` `void` `*b) ` `{ ` ` ` `return` `( (*(` `const` `dataFreq*)b).freq - (*(` `const` `dataFreq*)a).freq ); ` `} ` ` ` `/* Helper function that allocates a new node with the given data, ` ` ` `frequency as 1 and NULL left and right pointers.*/` `BSTNode* newNode(` `int` `data) ` `{ ` ` ` `struct` `BSTNode* node = ` `new` `BSTNode; ` ` ` `node->data = data; ` ` ` `node->left = NULL; ` ` ` `node->right = NULL; ` ` ` `node->freq = 1; ` ` ` `return` `(node); ` `} ` ` ` `// A utility function to insert a given key to BST. If element ` `// is already present, then increases frequency ` `BSTNode *insert(BSTNode *root, ` `int` `data) ` `{ ` ` ` `if` `(root == NULL) ` ` ` `return` `newNode(data); ` ` ` `if` `(data == root->data) ` `// If already present ` ` ` `root->freq += 1; ` ` ` `else` `if` `(data < root->data) ` ` ` `root->left = insert(root->left, data); ` ` ` `else` ` ` `root->right = insert(root->right, data); ` ` ` `return` `root; ` `} ` ` ` `// Function to copy elements and their frequencies to count[]. ` `void` `store(BSTNode *root, dataFreq count[], ` `int` `*index) ` `{ ` ` ` `// Base Case ` ` ` `if` `(root == NULL) ` `return` `; ` ` ` ` ` `// Recur for left substree ` ` ` `store(root->left, count, index); ` ` ` ` ` `// Store item from root and increment index ` ` ` `count[(*index)].freq = root->freq; ` ` ` `count[(*index)].data = root->data; ` ` ` `(*index)++; ` ` ` ` ` `// Recur for right subtree ` ` ` `store(root->right, count, index); ` `} ` ` ` `// The main function that takes an input array as an argument ` `// and sorts the array items according to frequency ` `void` `sortByFrequency(` `int` `arr[], ` `int` `n) ` `{ ` ` ` `// Create an empty BST and insert all array items in BST ` ` ` `struct` `BSTNode *root = NULL; ` ` ` `for` `(` `int` `i = 0; i < n; ++i) ` ` ` `root = insert(root, arr[i]); ` ` ` ` ` `// Create an auxiliary array 'count[]' to store data and ` ` ` `// frequency pairs. The maximum size of this array would ` ` ` `// be n when all elements are different ` ` ` `dataFreq count[n]; ` ` ` `int` `index = 0; ` ` ` `store(root, count, &index); ` ` ` ` ` `// Sort the count[] array according to frequency (or count) ` ` ` `qsort` `(count, index, ` `sizeof` `(count[0]), compare); ` ` ` ` ` `// Finally, traverse the sorted count[] array and copy the ` ` ` `// i'th item 'freq' times to original array 'arr[]' ` ` ` `int` `j = 0; ` ` ` `for` `(` `int` `i = 0; i < index; i++) ` ` ` `{ ` ` ` `for` `(` `int` `freq = count[i].freq; freq > 0; freq--) ` ` ` `arr[j++] = count[i].data; ` ` ` `} ` `} ` ` ` `// A utility function to print an array of size n ` `void` `printArray(` `int` `arr[], ` `int` `n) ` `{ ` ` ` `for` `(` `int` `i = 0; i < n; i++) ` ` ` `cout << arr[i] << ` `" "` `; ` ` ` `cout << endl; ` `} ` ` ` `/* Driver program to test above functions */` `int` `main() ` `{ ` ` ` `int` `arr[] = {2, 3, 2, 4, 5, 12, 2, 3, 3, 3, 12}; ` ` ` `int` `n = ` `sizeof` `(arr)/` `sizeof` `(arr[0]); ` ` ` `sortByFrequency(arr, n); ` ` ` `printArray(arr, n); ` ` ` `return` `0; ` `} ` |

*chevron_right*

*filter_none*

**Output**:

3 3 3 3 2 2 2 12 12 5 4

**Exercise:**

The above implementation doesn’t guarantee original order of elements with same frequency (for example, 4 comes before 5 in input, but 4 comes after 5 in output). Extend the implementation to maintain original order. For example, if two elements have same frequency then print the one which came 1st in input array.

This article is compiled by **Chandra Prakash**. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above

## Recommended Posts:

- Sort elements by frequency | Set 1
- Sort elements by frequency | Set 5 (using Java Map)
- Sort elements by frequency | Set 4 (Efficient approach using hash)
- Maximum difference between frequency of two elements such that element having greater frequency is also greater
- Sort an array of strings based on the frequency of good words in them
- Insertion sort to sort even and odd positioned elements in different orders
- Sum of all odd frequency elements in an array
- Sum of elements in an array having prime frequency
- Sorting Array Elements By Frequency | Set 3 (Using STL)
- Find the element having different frequency than other array elements
- Array range queries for elements with frequency same as value
- Fill an array based on frequency where elements are in range from 0 to n-1
- Remove elements from the array whose frequency lies in the range [l, r]
- Maximum product from array such that frequency sum of all repeating elements in product is less than or equal to 2 * k
- Replace every elements in the array by its frequency in the array