void merge(int (&a)[8], int left, int mid, int right)
{
#define MAX_NUM 0x7fffffff
int la[100];
int ra[100];
int nla = mid - left + 1;
int nra = right - mid;
for (int i = 0; i < nla; ++i)
{
la[i] = a[left + i];
}
la[nla] = MAX_NUM; //哨兵
for (int i = 0; i < nra; ++i)
{
ra[i] = a[mid + 1 + i];
}
ra[nra] = MAX_NUM; //哨兵
int i = 0;
int j = 0;
for (int k = left; k <= right; ++k)
{
if (la[i] <= ra[j])
{
a[k] = la[i++];
}
else
{
a[k] = ra[j++];
}
}
}
void merge_sort(int (&a)[8], int start_pos, int len)
{
if (start_pos < 0 || len <= 1)
{
return;
}
int half = len / 2;
merge_sort(a, start_pos, half);
merge_sort(a, start_pos + half, len - half);
int mid_pos = 0;
if (len % 2 == 0) //若长度为偶数,中位数取左边的一个, 以方便merge函数处理
{
mid_pos = start_pos + half - 1;
}
else
{
mid_pos = start_pos + half;
}
merge(a, start_pos, mid_pos, start_pos + len - 1);
}
void display(int (&a)[8], int len)
{
for (int i = 0; i < len; ++i)
{
cout << a[i] << " ";
}
cout << endl;
}
int main(int argc, char* argv[])
{
int a[] = { 4,2,5,1,3,4,8,2 };
display(a, 8);
merge_sort(a, 0, 8);
display(a, 8);
getchar();
return 0;
}
逆序对问题定义:假设A[1..n]是一个有n个不同数的数组。若i<j且A[ i ]>A[ j ],则对偶(i, j)称为A的一个逆序对。
用归并排序很好解决这个问题,在merge函数里面,有两个有序数组,左边的有序数组la,右边的有序数组ra。在归并la和ra时判断两数组中元素大小,如果存在la[ i ] > ra[ j ] (i < j),那么逆序对数量就+1。
由于la和ra存在哨兵MAX_NUM,由于哨兵的存在而使得la[ i ] > ra[ j ] (i < j),这种情况不能算作是逆序对。比如: