# Count Inversions in an array | Set 1 (Using Merge Sort)

Inversion Count for an array indicates – how far (or close) the array is from being sorted. If array is already sorted then inversion count is 0. If array is sorted in reverse order that inversion count is the maximum.
Formally speaking, two elements a[i] and a[j] form an inversion if a[i] > a[j] and i < j

Example:
The sequence 2, 4, 1, 3, 5 has three inversions (2, 1), (4, 1), (4, 3).

METHOD 1 (Simple)
For each element, count number of elements which are on right side of it and are smaller than it.

```#include <bits/stdc++.h>
int getInvCount(int arr[], int n)
{
int inv_count = 0;
for (int i = 0; i < n - 1; i++)
for (int j = i+1; j < n; j++)
if (arr[i] > arr[j])
inv_count++;

return inv_count;
}

/* Driver progra to test above functions */
int main(int argv, char** args)
{
int arr[] = {1, 20, 6, 4, 5};
int n = sizeof(arr)/sizeof(arr[0]);
printf(" Number of inversions are %d \n", getInvCount(arr, n));
return 0;
}
```

Output:

`Number of inversions are 5`

Time Complexity: O(n^2)
METHOD 2(Enhance Merge Sort)
Suppose we know the number of inversions in the left half and right half of the array (let be inv1 and inv2), what kinds of inversions are not accounted for in Inv1 + Inv2? The answer is – the inversions we have to count during the merge step. Therefore, to get number of inversions, we need to add number of inversions in left subarray, right subarray and merge().

How to get number of inversions in merge()?
In merge process, let i is used for indexing left sub-array and j for right sub-array. At any step in merge(), if a[i] is greater than a[j], then there are (mid – i) inversions. because left and right subarrays are sorted, so all the remaining elements in left-subarray (a[i+1], a[i+2] … a[mid]) will be greater than a[j]

The complete picture:

Implementation:

```#include <bits/stdc++.h>

int  _mergeSort(int arr[], int temp[], int left, int right);
int merge(int arr[], int temp[], int left, int mid, int right);

/* This function sorts the input array and returns the
number of inversions in the array */
int mergeSort(int arr[], int array_size)
{
int *temp = (int *)malloc(sizeof(int)*array_size);
return _mergeSort(arr, temp, 0, array_size - 1);
}

/* An auxiliary recursive function that sorts the input array and
returns the number of inversions in the array. */
int _mergeSort(int arr[], int temp[], int left, int right)
{
int mid, inv_count = 0;
if (right > left)
{
/* Divide the array into two parts and call _mergeSortAndCountInv()
for each of the parts */
mid = (right + left)/2;

/* Inversion count will be sum of inversions in left-part, right-part
and number of inversions in merging */
inv_count  = _mergeSort(arr, temp, left, mid);
inv_count += _mergeSort(arr, temp, mid+1, right);

/*Merge the two parts*/
inv_count += merge(arr, temp, left, mid+1, right);
}
return inv_count;
}

/* This funt merges two sorted arrays and returns inversion count in
the arrays.*/
int merge(int arr[], int temp[], int left, int mid, int right)
{
int i, j, k;
int inv_count = 0;

i = left; /* i is index for left subarray*/
j = mid;  /* i is index for right subarray*/
k = left; /* i is index for resultant merged subarray*/
while ((i <= mid - 1) && (j <= right))
{
if (arr[i] <= arr[j])
{
temp[k++] = arr[i++];
}
else
{
temp[k++] = arr[j++];

/*this is tricky -- see above explanation/diagram for merge()*/
inv_count = inv_count + (mid - i);
}
}

/* Copy the remaining elements of left subarray
(if there are any) to temp*/
while (i <= mid - 1)
temp[k++] = arr[i++];

/* Copy the remaining elements of right subarray
(if there are any) to temp*/
while (j <= right)
temp[k++] = arr[j++];

/*Copy back the merged elements to original array*/
for (i=left; i <= right; i++)
arr[i] = temp[i];

return inv_count;
}

/* Driver progra to test above functions */
int main(int argv, char** args)
{
int arr[] = {1, 20, 6, 4, 5};
printf(" Number of inversions are %d \n", mergeSort(arr, 5));
getchar();
return 0;
}
```

Output:

`Number of inversions are 5`

Note that above code modifies (or sorts) the input array. If we want to count only inversions then we need to create a copy of original array and call mergeSort() on copy.

Time Complexity:
O(nlogn)

Please write comments if you find any bug in the above program/algorithm or other ways to solve the same problem.

# Company Wise Coding Practice    Topic Wise Coding Practice

• kumar Saurabh

We can simply sort the array in O(nlogn) and finally compare the original array with the sorted one. Count the number of places where the elements are different. The count will be inversion count.

• tweety

no this method doesnt give inversion count. for the same example
2,4,1,3,5 sorted array is
1,2,3,4,5
according to ur method inversion count should be 4 but it is 3

• Zombie!

Clean and elegant :

#include

using namespace std;

// 1 array and count the no. of inversions
// Approached using mergesort

int merge(int * array,int low,int high,int mid)
{

int * newarr = new int[high-low+1];
int p1 = low;
int p2 = mid+1;
int c=0;
int z=0;

while(p1<=mid && p2<=high)
{
if(array[p1]<=array[p2])
newarr = array[p1++];
else
{newarr = array[p2++];
z+= ( mid – p1 + 1 );
}
}

while(p1<=mid)
newarr = array[p1++];

while(p2<=high)
newarr = array[p2++];

for(int i=low;i=high)
return 0;
int mid = (low+high)/2;
return mergesort(array,low,mid)+mergesort(array,mid+1,high)+merge(array,low,high,mid);
}

int invcount(int * array,int n)
{

return mergesort(array,0,n-1);

}

int main(void)
{
int n;
cin>>n;
int * array = new int[n];
for(int i=0;i>array[i];
cout<<invcount(array,n)<<endl;
return 0;}

• saanvi

very nice thank you

• Rapag

Hello Everybody! I am trying to solve a similar question on codechef.You can see the question here:http://www.codechef.com/problems/INSOMA3.
Here is my code:
#include
#include
using namespace std;
int inversions(int * a,int first,int last);
int combiningfun(int *a,int first,int last);
int main()

{
int inputsize;
cin>>inputsize;
int a[100000];
for(int i=0;i>a[i];}
cout<<inversions(a,0,inputsize-1);
//for(int i=0;i<inputsize;i++){cout<<a[i]<<" ";}
return 0;
}

int inversions(int * a,int first,int last)
{
if(first==last){return 0;}
int mid=(first + last)/2;
int leftmost=inversions(a,first,mid);
int rigthmost=inversions(a,mid+1,last);
int combining=combiningfun(a,first,last);
return (leftmost+rigthmost+combining);
}
int combiningfun(int *a,int first,int last)
{
int mid=(first + last)/2;
sort(a+first,a+last+1);
int f1=first;
int f2=mid+1;
int inv=0;
while(f1<=mid && f2 <= last)
{
if(a[f2]<=a[f1]){inv++;f2++;}
else{f1++;}
}
return inv;
}

• Paramvir Singh

everybody who is facing with the doubt that inversions should be mid-1+j is correct. It’s just that see the merge the function argument passed is mid+1 not mid. Hope this helps.

• Rahul

Its fine! Sorry

• Rahul

It should be j=mid+1

• The Big Idiot

no.
mid+1 is passed for mid so j=mid oly.

• Rahul

I am in a doubt..there should be mid-i+1 inversions.

• Rahul

or j should point to mid+1????

• alam01

If we just need the inversion count then what is the need of array ‘temp’?
Do we need it?

• Akshay Srinivas

i wrote following algorithm, let me know if its good one

#include
static int size = 0;
int inc = 0;
int inversion(int *arr, int num, int n)
{
if(n == 0) {
if(num > arr[0]) {
return 1;
}
return 0;
}
inc += inversion(arr, num, n/2);
if(n %2 != 0 && n > 1) {
if(num > arr[n-1]) {
inc++;
}
}
if(n%2 && n != 1) {
inc += inversion(arr + n , num, n/2);
} else {
int index = 0;
index = (arr +n) – start_address;
if(index 1) {
int index = 0;
index = (arr +n +n -1) – start_address;

if(index (arr + n)[n-1])
inc += 1;
}
return 0;
}

int main()
{
int i =0, inverse = 0;
// int arr[]={100,0,1,23,25};
int arr[]={11,100,0,1,3,20,4,7,0,2,24,5,9,25,11,8,45,78,90,14,21};
int n =0;
size = n = sizeof(arr)/sizeof(arr[0]);
for(i=0;i<n;i++){
printf("%d ", arr[i]);
}
printf("n");

printf("size %dn", size);

for(i=0;i<n-1;i++) {
if((n-1-i)%2)
inversion(arr+i + 1,arr[i],(n-i)/2);
else
inversion(arr+i + 1,arr[i],(n-1-i)/2);
}
printf("total inversions %dn", inc);
}

• feroz

how can i do method one in 2d array c#

• tczf1128

‘inv_count = _mergeSort(arr, temp, left, mid);’ should be ‘+=’

• tczf1128

you are right.sorry

• Murali

We can solve this in O(n) using a stack.

• Upen

we can solve it by using stack but can’t in O(n) time it will cost us O(n^2) …. give me your algorithm if you really think we can solve it in O(n) using stack

• kd111

//Simple modification to mergeSort algorithm

#include
#include

int count = 0;

void mergeAndCount(int *A , int low , int mid , int high){
int n1 = mid – low + 1;
int n2 = high – low;
int *L = (int *) malloc(sizeof(int)*n1);
int *R = (int *) malloc(sizeof(int)*n2);
int i , j , k;
for(i = 0 ; i < n1 ; i++)
L[i] = A[low + i];
for(j = 0 ; j < n2 ; j++)
R[j] = A[mid + 1 + j];
i = 0;
j = 0;
k = low;
while(i < n1 && j < n2){
if(L[i] <= R[j]){
A[k] = L[i];
i++;
k++;
}
else{
count = count + n1 – i;
A[k] = R[j];
j++;
k++;
}
}
while(i < n1){
A[k] = L[i];
i++;
k++;
}
while(j < n2){
A[k] = R[j];
j++;
k++;
}
free(L);
free(R);
}

void mergeSort(int *A , int low , int high){
if( low < high ){
int mid = low + (high – low)/2;
mergeSort(A , low , mid);
mergeSort(A , mid + 1 , high);
mergeAndCount(A , low , mid ,high);
}
}

int main(){
int A[] = {6,5,4,3,2,1};
int size = sizeof(A)/sizeof(A[0]);
printf("Given array :nt");
int i;
for(i = 0 ; i < size ; i++)
printf("%d ",A[i]);
mergeSort(A , 0 , size – 1);
printf("nno. of inversions : %dn",count);
return 0;
}

• Marsha Donna

@geeksforgeeks although not optimal..is the following progm correct to count the number of inversions using bubble sort..just to clarify the concept..

#include

int bubble(int arr[],int n)
{
int i, j,temp,k,inv_count=0;

for(i = 0; i <= n – 2; i++)
for(j = 0; j arr[j+1])
{
temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
inv_count++;
}
return inv_count;
}

void main()
{
int k,count_inv;
int myarray[] = {50,40,30,20,10};
count_inv=bubble(myarray,5);
for(k=0;k<5;k++)
printf("sorted array is %dn",myarray[k]);
printf("the number of inversions is %d",count_inv);
}

• Guest

@geeksforgeeks:disqus although not optimal..is the following progm correct to count the number of inversions using bubble sort..just to clarify the concept..

#include

int bubble(int arr[],int n)
{
int i, j,temp,k,inv_count=0;

for(i = 0; i <= n – 2; i++)
{for(j = 0; j arr[j+1])
{
printf(“n%dt%dn”,arr[j],arr[j+1]);
temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
inv_count++;
// for(k=0;k<n;k++)
// printf("%d",arr[k]);
}

}
printf("nn");
for(k=0;k<n;k++)
printf("%dt",arr[k]);printf("nn");
}
return inv_count;
}

void main()
{int k,count_inv;
int myarray[] = {50,40,30,20,10};
count_inv=bubble(myarray,5);
for(k=0;k<5;k++)
printf("sorted array is %dn",myarray[k]);
printf("the number of inversions is %d",count_inv);
}

• Mohit Garg

I think there exists a simpler solution
sort the array
e.g. 4,5,6,1,2,3 becomes 1,2,3,4,5,6
find the displacement for a given element e.g. 4 which was initially at 0 is now at index 3. Thus displacement is 3.

Total number of inversions should be sum of all the displacement towards right.
Only 4,5,6 are displaced right, total = 3+3+3 = 9

``` ```
/* Paste your code here (You may delete these lines if not writing code) */
``` ```
• piyush

Try using the same technique on 4,5,6,1,3,2:

Its the not displacement towards right that counts, but the relative displacements of elements. e.g. 3 relative to 2 is swapped => add 1, and so on .

• crazy
``` ```
#include<stdio.h>
#define INF 19999999
long long total;
void merge(int a[],int p,int q,int r)
{
int n1,n2,i,k,j;
n1=(q-p)+1;
n2=(r-q);
int left[n1+2],right[n2+2];
for(i=1;i<=n1;i++)
left[i]=a[p+i-1];
for(i=1;i<=n2;i++)
right[i]=a[q+i];
left[n1+1]=right[n2+1]=INF;
i=j=1;
for(k=p;k<=r;k++)
{
if(left[i]<=right[j])
a[k]=left[i++];
else
{
total+=(n1-(i-1));
a[k]=right[j++];
}
}
}
void mergesort(int a[],int p,int r)
{
int q;
if(p<r)
{
q=(p+r)/2;
mergesort(a,p,q);
mergesort(a,q+1,r);
merge(a,p,q,r);
}
}
int main(int argv, char** args)
{
int arr[] = {1, 20, 6, 4, 5};
mergeSort(arr,0,4);
printf(" Number of inversions are %d \n",total);
getchar();
return 0;
}
/* Paste your code here (You may delete these lines if not writing code) */
``` ```
• Venkatesh B

for the algorithm given by geeks for geeks, for this input 4,5,6,1,2,3 number of inversions are 9, is that correct?

• Swapnil R Mehta

Yes its correct.
As inversions: (4,1),(4,2),(4,3),(5,1),(5,2),(5,3),(6,1)(6,2),(6,3).

• ljk

• Venkatesh Fan

Are u the famous Venkatesh B?

• shivi
``` ```
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;

typedef long long llong;
const int MAXN = 500020;
llong tree[MAXN], A[MAXN], B[MAXN];

{
llong sum = 0;
while (idx > 0)
{
sum += tree[idx];
idx -= (idx & -idx);
}
return sum;
}

void update(int idx ,llong val)
{
while (idx <= MAXN)
{
tree[idx] += val;
idx += (idx & -idx);
}
}

int main()
{
int N,t;
// scanf("%d",&t);
t=1;
while(t--)
{
scanf("%d",&N);
memset(tree, 0, sizeof(tree));
for(int i = 0; i < N; ++i)
{
scanf("%lld",&A[i]);
B[i] = A[i];
}

sort(B, B + N);

for(int i = 0; i < N; ++i)
{
int rank = int(lower_bound(B, B + N, A[i]) - B);
A[i] = rank + 1;
}

llong inv_count = 0;

for(int i = N - 1; i >= 0; --i)
{
llong x = read(A[i] - 1);
inv_count += x;
update(A[i], 1);
}
printf("%lld\n",inv_count);
}
return 0;
}
``` ```
• ajiteshpathak

Not sure if any of the above methods have similar implementation but here is my approach. Basically I am using I ,j where I holds the iterator for every element in the array and J just iterates all elements before it.

int inversionCount(int *arr, int n)
{
int i = 0, j = 1;
int count = 0;

while (i < n - 1) { if (arr[j] > arr[i] && j > i)
{
j++;
}
else if (arr[j] < arr[i] && j > i)
{
printf(” (%d, %d) “, arr[i], arr[j]);
j++;
count++;
}

if (j == n)
{
i++;
j = i + 1;
}
}

return count;
}

• lotus

Why can’t we just store sorted array and count how many numbers in the original array are not in their expected position.

``` ```
/* Paste your code here (You may delete these lines if not writing code) */
``` ```
• dew

@GeeksforGeeks Please let us know if there is any mistake in this logic. Creating a temp array in which the elements are sorted. then finding the no of elements that are not in their correct position

• Priso

Consider an sorted array (1,2,3,4) where inversion is 0
now lets swap 1 and 4 so the array is (4,2,3,1)
and the numbers which are not in their expected positions = 2 (number 4 and number 1)

But the number of inversions = 5 i.e., {(4,2),(4,3),(4,1),(2,1),(3,1)}

``` ```
/* Paste your code here (You may delete these lines if not writing code) */
``` ```
• mukesh gupta

void inversion(int a[ ],int n)
{
if(n>1){
int b[n/2],c[n-n/2],i,j=0,k,m;
for(i=0;i<n/2;i++)
b[i]=a[i];
for(i=n/2;i<n;i++)
{ c[j]=a[i];
j++;}
inversion(b,n/2);
inversion(c,n-n/2);
i=0;
j=0;
k=0;
while(i<n/2 && j<(n-n/2))
{ if(b[i]<c[j])
{ a[k]=b[i];
i++;}
else
{ a[k]=c[j];
j++;
for(m=i;m<n/2;m++)
inver++; }
k++;
}
if(i==n/2)
for(i=j;i<n-n/2;i++)
a[k++]=c[i];
else if(j==n-n/2)
for(j=i;j<n/2;j++)
a[k++]=b[j];
}
}

• mukesh gupta

void inversion(int a[ ],int n)
{
if(n>1){
int b[n/2],c[n-n/2],i,j=0,k,m;
for(i=0;i<n/2;i++)
b[i]=a[i];
for(i=n/2;i<n;i++)
{ c[j]=a[i];
j++;}
inversion(b,n/2);
%2

• bartender

If mid = (left+right)/2
The number of inversions should be mid+1-i.
As all elements from A[i] to A[mid] are less than A[j]
which is mid+1-i.

But the code works out as we pass mid+1 into the merge function.So, here mid= (left+right)/2+1 i.e. as explained in code, pointing to the first element in the second sub-array.

• coderAce

You’re right. @Moderators, you should highlight this in the main article.

• Ankit Malhotra

Earlier code was using extra memory. However using array rotation, this can be made inplace as follows :

``` ```

#include <iostream>
using namespace::std;
typedef unsigned long counter;
typedef long long element;

inline void rotate (element term[], counter count, counter jump)
{
element temp;
counter gcd = count, k = jump, i, position;
for (; k != 0; i = k, k = gcd % k, gcd = i);
for (i = 0; i != gcd; ++i)
{
temp = term [i];
position = k = i;
do
{
term [position] = term[k];
position = k;
k -= jump;
if (k < 0) k += count;
}
while (k != i);
term[position] = temp;
}
}

counter mergesort (element term[], counter count)
{
if (count < 2) return 0;
counter mid = count/2, inversions = mergesort (term, mid);
inversions += mergesort (term + mid, count - mid);
counter range, bound;
element * ptr = NULL;
for (counter left = 0, right = mid, movecount = 0;
right != count; right += movecount)
{
for (left += movecount;
left != right && term[left] <= term[right]; ++left);
if ((range = right - left) == 0) break;
for (ptr = term + right, movecount = 1, bound = count - right;
movecount != bound && ptr[movecount] < term[left]; ++movecount);
rotate (term + left, range + movecount, movecount);
inversions += movecount * range;
}
return inversions;
}

``` ```
• Ankit Malhotra

As we are using unsigned for counter which is generally what size_type returns the following replacements need to be done.

``` ```
k -= jump;
if (k < 0) k += count;
``` ```

should be

``` ```
k += jump;
if (k >= count) k -= count;
``` ```
``` ```
rotate (term + left, range + movecount, movecount);``` ```

should be

``` ```
rotate (term + left, range + movecount, range);``` ```
• Arun

You need to change

inv_count += mid – i to
inv_count += (mid-left+1-i);

else, the result coming is not correct.

Thanks,

• GeeksforGeeks

@Arun: Please take a closer look at the code. The value of mid is (left + right)/2. Let us know if you find any case for which the given code doesn’t produce the correct result.

• bartender

We are passing mid+1 into merge routine,so everything works out.Read my other comment for additional details.

• Ankit Malhotra

Simplified the code to a single merge sort function which returns the inversions. This implementation is in place and reduces looping when consecutive elements on the right side need me be moved for a single element on the left.

``` ```
using namespace::std;
typedef unsigned long counter;
typedef long long element;
counter mergesort (element term[], counter count)
{
if (count < 2) return 0;
counter mid = count/2,
inversions = mergesort (term, mid);
inversions += mergesort (term + mid, count - mid);
counter prefix = 0, suffix = mid, range, movecount, bound, j;
element * ptr = NULL;
while (true)
{
for (; prefix != suffix && term[prefix] <= term[suffix]; prefix++);
range = suffix - prefix;
if (!range) break;
for (ptr = term + suffix, movecount = 1, bound = count - suffix;
movecount != bound && ptr[movecount] < term[prefix]; movecount++);
for (ptr = new (element[range]), j = 0; j < range;
ptr[j++] = term [prefix + j]);
for (j = 0; j < movecount; term[prefix + j++] = term[suffix + j]);
for (j = 0; j < range; term[prefix + movecount + j++] = ptr[j]);
delete ptr;
inversions += movecount * range;
suffix += movecount;
if (suffix == count) break;
}
return inversions;
}
``` ```
• Ankit Malhotra

delete ptr should be replaced with delete []ptr

• Ankit Malhotra

if (suffix == count) break;
should also have else statement as follows
else prefix += movecount;

• balanced BST

``` ```
/* Paste your code here (You may delete these lines if not writing code) */
``` ```
• hi

This problem can also be solved using BIT and Segment Tree

• abzx12@gmail.com

Can you suggest the way we can use BIT to solve it?

``` ```
/* Paste your code here (You may delete these lines if not writing code) */
``` ```
• Rahul

There you go

#include
#include
#include

using namespace std;

typedef long long llong;

const int MAXN = 500020;
llong tree[MAXN], A[MAXN], B[MAXN];

llong sum = 0;
while (idx > 0){
sum += tree[idx];
idx -= (idx & -idx);
}
return sum;
}

void update(int idx ,llong val){
while (idx <= MAXN){
tree[idx] += val;
idx += (idx & -idx);
}
}

int main(int argc, char *argv[]) {
int N;
while(1 == scanf("%d",&N)) {
if(!N) break;
memset(tree, 0, sizeof(tree));
for(int i = 0; i < N; ++i) {
scanf("%lld",&A[i]);
B[i] = A[i];
}
sort(B, B + N);
for(int i = 0; i = 0; –i) {
llong x = read(A[i] – 1);
inv_count += x;
update(A[i], 1);
}
printf(“%lld\n”,inv_count);
}
return 0;
}

• Venkatesh

If we use modified insertion sort alg, we see best running time. for partially sorted array insertion sort runs in linear time.

int arr[], array_size, inv_count;

for (int i = 0; i 0; j–)
if (a[j] < a[j-1]))
inv_count ++;
else
break;

• jordi

theres a linear solution that im looking for..

• Algoseekar

@jordi..i dont think we can do it linearly..??

• amit

nice question !

• Naman Goel

We can also use binary search tree method for this
here is the code-

``` ```

#include<iostream>
using namespace std;

struct node{
int data;
node *left;
node *right;
int rc;
};

node *root = NULL;

int get_inv(int val)
{
node *newnode = new node;
newnode -> data = val;
newnode -> left = NULL;
newnode -> right = NULL;
newnode -> rc = 0;

int inv = 0;

if(!root)
{
root = newnode;
return 0;
}

node *ptr = root;
node *pptr = root;
while(ptr)
{
pptr = ptr;
if(val < ptr->data)
{
inv += ptr->rc +1;
ptr = ptr->left;
}
else
{
ptr->rc++;
ptr = ptr->right;
}
}

if(val < pptr->data)
{
pptr->left = newnode;
}
else
{
pptr->right = newnode;
}

return inv;
}

int count_inv(int *array,int n)
{
int inv = 0;
for(int i=0;i<n;i++)
{
inv += get_inv(array[i]);
}
return inv;
}

int main()
{
int array[] = {3,6,1,2,4,5};
cout<<count_inv(array,6)<<endl;
return 0;
}
``` ```
• J

Really cool coding. I must learn to code like this.

• J

Memory is leaked in the above program. You cannot just call new and leave it alone.

• laxman

@nama goel ..hi naman can you explain the algorithm..its awesome program. please write the algo.

Thanks
laxman

• If I understand the logic correctly, we are constructing BST from the array elements and maintaining a count on each node. The idea here is every parent node must maintain the number of nodes that branched on to it’s right side (right count). The above code fails if there are equal element which cause the count to be incremented. Equal nodes won’t participate in inversions. The count (rc) will be used to track the number of inversions.

However, when the array is reverse sorted, the tree will be fully right skewed. While inserting i-th node, we need to visit previous (i-1) nodes, so the worst case complexity is no better than O(n^2).

Where as merge sort procedure doesn’t depend on data to be sorted. What ever may be the permutation of input data, merge sort will sort the array in O(NlogN) time, so the inversion count.

Let me know if I am missing something to understand.

• Decoder

What if we insert equal element to right child of equal element, In this case count won’t be incremented.

``` ```
/* Paste your code here (You may delete these lines if not writing code) */
``` ```
• Decoder

What if we insert equal element to right child of equal element, In this case count won’t be incremented.

• Apoorv

True…worst case complexity looks like O(n*n). But this can be improved using a self balancing binary search tree like a Red Black tree.

• Aashish

@venki,
I have modified the code to handle the case of duplicate items. To avoid the worst time complexity of O(N^2), self balancing BST can be used.
Here is the code:

``` ```
#include <stdio.h>
#include <stdlib.h>

struct node
{
int data;
int freq;
struct node *left,*right;
};

struct node* getNode(int data)
{
struct node* temp=(struct node*)malloc(sizeof(struct node));
temp->left=temp->right=NULL;
temp->data=data;
temp->freq=1;
return temp;
}

int insert(struct node**root,int data)
{
if(!*root)
{
*root=getNode(data);
return 0;
}
else if(data<(*root)->data)
return (*root)->freq + insert(&((*root)->left),data);
else if(data>=(*root)->data)
{
++((*root)->freq);
return insert(&((*root)->right),data);
}
}

void cal(int *arr,int size)
{
struct node *root=NULL;
int i,count=0;
for(i=0;i<size;i++)
{
count+=insert(&root,arr[i]);
}
printf("%d ",count);
}

int main()
{
int arr[]={2, 4, 1, 3, 5},size;
size=sizeof(arr)/sizeof(arr[0]);
cal(arr,size);
return 0;
}
``` ```

Output: http://ideone.com/c2gXM

Let me know if i am missing anything.

• Aashish

A little change, When the value to be inserted already exists, do not insert it in BST.

• mrn

I think , we can’t balance the tree. coz if we do , then e.g. in RR rotation , left subtree no more represents smaller nos. inserted after the new root.
Please correct me if i am wrong.