归并排序

本文详细介绍了归并排序的原理及Java实现方式,归并排序通过不断将数组分成更小的有序部分,再将这些有序部分合并成更大的有序数组,直至整个数组有序。此算法稳定且时间复杂度为O(nlogn),但空间复杂度较高。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

归并排序(Merging Sort)就是利用归并的思想实现的排序方法。它的原理是 假设初始序列含有 n 个记录,则可以看成

是 n 个有序的子序列,每个子序列的长度为 1,然后两两归并,得到 [n/2] ( [x]表示不小于 x 的最小整数 ) 个长度为 2 或 

为 1 的有序子序列;两两归并,……,如此重复,直到得到一个长度为 n 的有序序列为止,这种排序方法称为 2路归并排序。

java实现:

public static void Merge_Sort(int[] arr)
	{
		MSort(arr, arr, 0, arr.length-1);
	}
	public static void MSort(int[] SR, int[] TR1, int s, int t)
	{
		int m;
		int[] TR2 = new int[SR.length];
		if(s == t)
			TR1[s] = SR[s];
		else
		{
			m = (s + t)/2;   //将SR[s..t]平分为SR[s..m] 和 SR[m+1..t]
			MSort(SR, TR2, s, m); //递归将SR[s..m]归并为有序的TR2[s..m]
			MSort(SR, TR2, m+1, t);  //递归将SR[m+1..t]归并为有序TR2[m+1..t]
			Merge(TR2, TR1, s, m, t);  //将TR2[s..m] 和 TR2[m+1..t]归并到TR1[s..t]
		}
	}
	//将有序的SR[i..m] 和 SR[m+1..n] 归并为有序的 TR[i..n]
	public static void Merge(int[] SR, int[] TR, int i, int m, int n)
	{
		int j, k, l;
		for(j = m + 1, k = i; i <= m && j <= n; k++)  //将SR中记录由小到大归并入TR
		{
			if(SR[i] < SR[j])
				TR[k] = SR[i++];
			else
				TR[k] = SR[j++];
		}
		if(i <= m)
		{
			for(l = 0; l <= m - i; l ++)
				TR[k+l] = SR[i+l];    //将剩余的SR[i..m]赋复制到TR
		}
		if(j <= n)
		{
			for(l = 0; l <= n-j; l ++)
				TR[k+l] = SR[j+l];
		}
	}

时间复杂度,一趟归并需要将SR[1]~SR[n]中相邻的长度为 h 的有序序列进行两两归并。并将结果放到 TR1[1]~TR[n]中,

需要将待排序序列中的所有记录扫描一遍,因此耗费 O(n)时间,而由完全二叉树的深度可知,整个归并排序需要

进行 [logn]([x]表示不大于x的最小整数),因此总的时间复杂度为O(nlogn), 而且这是归并排序算法中最好,最坏,平均的时间性能。

由于归并排序在归并过程中需要与原始记录序列同样数量的存储空间存放归并结果以及递归时深度为 log₂n 的栈空间,因此空间复杂度为 O(n+logn)。

另外,Merge函数中有if ( SR[i] < SR[j] )语句,说明taxuyao它需要两两比较,不存在跳跃,因此归并排序是一种稳定的排序算法。归并排序是一种 比较占内存,但却效率高且稳定的算法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值