逆序对的实现,利用逆序对特性

版权声明:本文为博主原创文章,未经博主允许不得转载。 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;
}
网上看到了逆序对在数组中的特性,所以才发现只需要加几点就可以了。

猜你喜欢

转载自blog.csdn.net/Cpp2088671660/article/details/46048955