现在的位置: 首页 > 综合 > 正文

归并排序及其应用

2013年10月28日 ⁄ 综合 ⁄ 共 2488字 ⁄ 字号 评论关闭

归并排序(Merge Sort):

归并排序(Merge Sort)的基本思想是:“归并”的含义是将两个或两个以上的有序表组合成一个新的有序表。因此归并排序就是利用归并的思想来实现的,假设初始序列含有n个记录,则可以看成是n个有序的子序列,每个子序列的长度为1,然后两两归并,得到 (n+1)/2个长度为2或1的有序子序列;再两两归并,….,如此重复,直至得到一个长度为n的有序序列位置,这种排序方法称为2路归并排序。

例题:假设现在我们要对数组{50, 10, 90, 30, 70, 40, 80, 60, 20}进行排序。算法实现如下:

#include <iostream>
using namespace std;

const int maxSize = 100;

/*
函数名:	Merge
函数功能:	将有序的SR[begin, middle]和SR[middle+1, end]排序后存储到TR中。
函数参数:	int SR	原数组
			int TR	目标数组
*/
void Merge(int SR[], int TR[], int begin, int middle, int end)
{
	int i, j, k;
	i = begin;
	j = middle + 1;
	k = begin;
	while (i <= middle && j <= end)
	{
		if (SR[i] <= SR[j])
		{
			TR[k] = SR[i];
			k++;
			i++;
		}
		else
		{
			TR[k] = SR[j];
			k++;
			j++;
		}
	}

	while (i <= middle)
	{
		TR[k] = SR[i];
		k++;
		i++;
	}

	while (j <= end)
	{
		TR[k] = SR[j];
		k++;
		j++;
	}
}

void MergeSort(int SR[], int TR1[], int begin, int end)
{
	if (begin == end)
	{
		TR1[begin] = SR[begin];
	}
	else
	{
		int TR2[maxSize + 1];
		int middle = begin + (end - begin) / 2;		/* 将SR[begin,end]平均分成SR[begin, middle]和SR[middle+1, t] */
		MergeSort(SR, TR2, begin, middle);			/* 递归地将SR[begin, middle]归并为有序的TR2[begin, middle] */
		MergeSort(SR, TR2, middle+1, end);			/* 递归地将SR[middle+1, end]归并为有序的TR2[middle+1, end] */
		Merge(TR2, TR1, begin, middle, end);		/* 将TR2[begin, middle]和TR2[middle+1, end]归并到TR2[begin,end] */
	}
}

int main()
{
	int array[] = {50, 10, 90, 30, 70, 40, 80, 60, 20};
	MergeSort(array, array, 0, 8);
	for (int i = 0; i < 9; i++)
	{
		cout << array[i] << " " ;
	}
	cout << endl;
}

例1:在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。(剑指offer,面试题36,页数:189)

同理,我们将数组分成长度为1的子数组,然后两两结合,合并相邻的子数组,统计逆序对的数目。

也就是在Merge函数里,如果SR[i] > SR[j],则相当于SR[i] > SR[j],SR[j-1],SR[j-2]....SR[middle+1]  故逆序对为 j-middle

#include <iostream>
using namespace std;

const int maxSize = 100;

/*
函数名:	Merge
函数功能:	将有序的SR[begin, middle]和SR[middle+1, end]排序后存储到TR中,并统计逆序对
函数参数:	int SR	原数组
			int TR	目标数组
返回值:	返回逆序对
*/
int Merge(int SR[], int TR[], int begin, int middle, int end)
{
	int i, j, k, InversePairs = 0;
	i = middle;
	j = end;
	k = end;
	while (i >= begin && j >= middle + 1)
	{
		if (SR[i] <= SR[j])
		{
			TR[k] = SR[j];
			k--;
			j--;
		}
		else
		{
			InversePairs += j - middle;
			TR[k] = SR[i];
			k--;
			i--;
		}
	}

	while (i >= begin)
	{
		TR[k] = SR[i];
		k--;
		i--;
	}

	while (j >= middle + 1)
	{
		TR[k] = SR[j];
		k--;
		j--;
	}

	return InversePairs;
}

int MergeSort(int SR[], int TR1[], int begin, int end)
{
	int left = 0, right = 0, current = 0;
	if (begin == end)
	{
		TR1[begin] = SR[begin];
	}
	else
	{
		int TR2[maxSize + 1];
		int middle = begin + (end - begin) / 2;				/* 将SR[begin,end]平均分成SR[begin, middle]和SR[middle+1, t] */
		left = MergeSort(SR, TR2, begin, middle);			/* 递归地将SR[begin, middle]归并为有序的TR2[begin, middle] */
		right = MergeSort(SR, TR2, middle+1, end);			/* 递归地将SR[middle+1, end]归并为有序的TR2[middle+1, end] */
		current = Merge(TR2, TR1, begin, middle, end);		/* 将TR2[begin, middle]和TR2[middle+1, end]归并到TR2[begin,end] */
	}
	return left + right + current;
}

int main()
{
	int array[] = {7, 5, 6, 4};
	cout << MergeSort(array, array, 0, 3) << endl;
}

抱歉!评论已关闭.