I have implemented a merge sort that counts inversions, based on CLRS Merge Sort pseudo-code, but the answer is not correct, doesn't sort the array and neither does it count the inversions correctly.
Definition of inversion: Let A[1..n] be an array of n distinct whole numbers. If i < j and A[i] > A[j], then the pair (i,j) is called an inversion of A.
I used pass by reference to work with the same vector.
int mergeSortInvCount(vector<int> &arr, int izq, int der);
int mergeInvCount(vector<int> &arr, int izq, int mitad, int der);
void invCountRecursivo(vector<int> &arr, int n){
int numInversiones = mergeSortInvCount(arr, 1, n);
cout << "Num inversiones:" << numInversiones << endl;
for(int i=0; i < n; i++){
cout<<arr[i]<<endl;
}
}
int mergeSortInvCount(vector<int> &arr, int izq, int der){
int invCount = 0;
if(izq < der){
int mitad = (izq + der)/2;
invCount = mergeSortInvCount(arr, izq, mitad);
invCount += mergeSortInvCount(arr, mitad+1, der);
invCount += mergeInvCount(arr, izq, mitad, der);
}
return invCount;
}
int infinito = numeric_limits<int>::max();
int mergeInvCount(vector<int> &arr, int izq, int mitad, int der){
int n1 = mitad - izq + 1;
int n2 = der - mitad;
int invCount = 0;
vector<int> vectorIzq;
vector<int> vectorDer;
for(int k=0;k<n1;k++){
vectorIzq.push_back(arr[izq+k-1]);
}
vectorIzq.push_back(infinito);
for(int k=0;k<n2;k++){
vectorDer.push_back(arr[mitad+k]);
}
vectorDer.push_back(infinito);
int i = 0;
int j = 0;
for(int k = izq; k <= der; k++){
if(vectorIzq[i] <= vectorDer[j]){
arr[k] = vectorIzq[i];
i++;
}
else{
arr[k] = vectorDer[j];
j++;
invCount += (mitad - i);
}
}
return invCount;
}
For input: {4,3,1,8,2} and 5, correct answer is 6 inversions, and sorted array is {1,2,3,4,8}. It returns 5 inversions and {4,4,4,3,4}.