版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Cpp2088671660/article/details/46048955
#include <iostream>
using namespace std;
int g_count;
template<typename T, unsigned n>
void Merge(T(*arr)[n], size_t left, size_t r, size_t right)
{
if (left == right)
return;
// create new arrays
int lnum = r - left + 1, rnum = right - r;
T* pLarr = new int[lnum]();//这里并没有使用哨兵
T* pRarr = new int[rnum]();
int i, j = 0;
for (i = 0; i < lnum; ++i)
pLarr[i] = (*arr)[left + i];
for (i = 0; i < rnum; ++i)
pRarr[i] = (*arr)[r + 1 + i];
i = j;
int k;
for (k = left; k < right; ++k)
{
if (pLarr[i] > pRarr[j])
{
(*arr)[k] = pLarr[i];
++i;
//归并实现逆序对加了下面的一句话
g_count += rnum - j;//因为归并排序后是个有序的数组,那么如果这个逆序对条件成立则这个数组后到right的所有的都可以成为逆序对,i表示left数组的成立元素,j则表示right数组成立的元素其后面所有数据都成立,因为已经排好序
}
else
{
(*arr)[k] = pRarr[j];
++j;
}
}
for (;
i != lnum; ++i, ++k)
(*arr)[k] = pLarr[i];
for (;
j != rnum; ++j, ++k)
(*arr)[k] = pRarr[j];
delete[] pLarr;
delete[] pRarr;
}
template<typename T, unsigned n>
void MergeSort(T(*arr)[n], size_t left, size_t right = n)
{
if (left >= right)
{
return;
}
int r = (right + left) / 2;
MergeSort(arr, left, r);
MergeSort(arr, r + 1, right);
Merge(arr, left, r, right);
}
int main()
{
int arr1[] = { 7, 6, 5, 4, 3, 2, 1 };
MergeSort(&arr1, 0);
//归并实现逆序对加了下面的一句话
g_count -= sizeof(arr1) / sizeof(int);//这个可能是没有使用哨兵的原故导致总是多出数组大小
cout << g_count << endl;
return 0;
}
网上看到了逆序对在数组中的特性,所以才发现只需要加几点就可以了。