排序算法(五)--归并排序

归并排序
归并排序是一种借助归并进行排序的方法,归并的含义是将两个或两个以上的有序序列归并成一个有序序列的过程。
归并排序的主要思想是:将若干个有序序列逐步归并,最终成为一个有序序列.
二路归并排序是归并排序中最简单的排序方法,其基本思想是:将若干个有序序列进行两两归并,直至所有有序序列都在一个序列中为止。
假设待排序序列中有n个记录,则可将整个序列看成是长度为1的n个有序序列.其中一次归并的算法如下:

一次归并算法Merge

void Merge(int r[], int r1[], int s, int m, int t)
{
	int i = s;
	int j = m+1;
	int k = s;
	while (i<=m && j<=t)
	{
		if (r[i] > r[j])
		{
			r1[s++] = r[j++];
		}else
		{
			r1[s++] = r[i++];
		}
	}
	if (i <= m)
	{
		for (i; i<=m; i++)
		{
			r1[s++] = r[i];
		}
	}
	if (j <= t)
	{
		for (j; j<=t; j++)
		{
			r1[s++] = r[j];
		}
	}
}
如何确定一趟归并的结束?在一趟归并中,除最后一个有序序列外,其他有序序列长度相同,用h表示.现在是把若干个长度
为h的有序序列和最后一个长度可能小于h序列两两归并,将结果存放到r1[0]~r1[n-1]中.
初始时i=0,显然归并的步长为2h.
若此时有i+2h<=n,则可以进行下一次归并.i<=n-2h
若此时有i<n-h,则仍有两个有序序列,一个长度为h,一个长度小于h.完成一次并归.
若有i>=n-h,则表明只剩下一个有序序列,则将其放到相应位置.

// 一趟归并算法MergePass
// r[]带排数组,r1[]存放归并后的数组,n数组长度,归并步长
void MergePass(int r[], int r1[], int n, int h)
{
	int i = 0;
	while (i<=n-2*h) // 可以保证两个h长度的数组归并
	{
		Merge(r, r1, i, i+h-1, i+2*h-1);
		i += 2*h;
	}
	// 如果仍有两个有序序列
	if (i<n-h)
	{
		Merge(r, r1, i, i+h-1, n-1);
	}else // 否则直接放入数组
	{
		for (int k = i; k<n; k++)
		{
			r1[k] = r[k];
		}
	}
}
// 如何确定归并结束?
// 初始步长为1,结束时有序序列长度为n.可以用步长控制归并结束.
void MergeSort(int r[], int r1[], int n)
{
	int h = 1;
	int k = 0;
	while (h<n)
	{
		MergePass(r, r1, n, h);
		k++;
		h = 2*h;
		MergePass(r1, r, n, h);
		h = 2*h;
		k++;
	}
	if (k%2 != 0) // 利用归并次数奇偶判断排序好的在哪个数组里,并移回r[]
	{
		for (int i = 0; i<n; i++)
		{
			r[i] = r1[i];
		}
	}
}
一趟归并算法需要n/2h次归并,并把结果存放到r1[0]~r1[n-1]中,需要耗费O(n)的时间.这个算法需要进行log2N趟.所以算法的复杂度为O(nlog2n).这是归并排序算法最好,最坏,平均的时间性能.
二路归并排序在归并过程中需要与原始记录序列相同数量的存储空间,以便存放归并结构,因此其空间复杂度为O(n)
二路归并排序是一种稳定的排序方法.



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值