归并排序:
#include<iostream>
using namespace std;
int const MAX_N = 10000;
void MergeArray(int a[],int first,int mid,int last){
int temp[MAX_N];
int i = first;
int m = mid;
int j = mid + 1;
int n = last;
int k = 0;
//就是把两个已经排好序的数组a1[first - mid]和a2[mid+1 - last]合并成一个有序数组
while(i<=m && j<=n){
if(a[i] <= a[j])
temp[k++] = a[i++];
else
temp[k++] = a[j++];
}
while(i<=m){
temp[k++] = a[i++];
}
while(j<=n){
temp[k++] = a[j++];
}
for(i=0;i<k;i++){
a[first+i] = temp[i];
}
}
void MergeSort(int a[],int first,int last){
if(first<last){
int mid = (first+last)/2;
MergeSort(a,first,mid);
MergeSort(a,mid+1,last);
MergeArray(a,first,mid,last);
}
}
int main()
{
int n;
cin >> n;
int array[MAX_N];
for(int i = 0;i<n;i++){
cin >> array[i];
}
int temp[MAX_N];
MergeSort(array,0,n-1);
for(int i = 0;i<n;i++){
cout << array[i] << " ";
}
cout << endl;
return 0;
}
分治法解决逆序数:
#include<iostream>
using namespace std;
//求逆序数的分治算法就是利用归并排序,在归并排序的时候计算出每一个数的逆序数(或者说是直接加到总和上)
int const MAX_N = 100000;
int MergeArray(int a[],int first,int mid,int last){
int i = first;
int m = mid;
int j = mid+1;
int n = last;
int k = 0;
int num = 0;
int temp[MAX_N];
while(i <= m && j <= n){
if(a[i]>a[j]){
num += mid+1-i;//a[i - mid]的每一个数的逆序数都增加
temp[k++] = a[j++];
}
else{
temp[k++] = a[i++];
}
}
while(i<=m){
temp[k++] = a[i++];
}
while(j<=n){
temp[k++] = a[j++];
}
for(i = 0;i<k;i++){
a[first+i] = temp[i];
}
return num;
}
int MergeSort(int a[],int first,int last){
if(first>=last)
return 0;
int mid = (first+last)/2;
int num1 = MergeSort(a,first,mid);
int num2 = MergeSort(a,mid+1,last);
int temp[MAX_N];
return num1 + num2 + MergeArray(a,first,mid,last);
}
int main()
{
int n;
cin >> n;
int arr[MAX_N];
for(int i=0;i<n;i++){
cin >> arr[i];
}
cout << MergeSort(arr,0,n-1) << endl;
return 0;
}