排序算法总结之归并排序 Merge Sort

本文详细介绍了归并排序的原理及其实现过程。归并排序是一种采用分治策略的高效排序算法,通过递归将数组分为更小的部分进行排序,再合并已排序的子数组来完成整个数组的排序。

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

算法原理:


归并排序使用分治的思想(divide and conquer):
1. 首先把数组平均分成两个子数组
2. 对两个字数组递归的使用归并排序进行排序
3. 把两个已经排好序的字数组合并得到结果


归并算法的原理图如下:




从图中可以看到归并排序把子问题的规模降低到1的时候停止,一个元素的数组一定是有序的。


算法伪代码:


伪代码来自算法导论归并排序算法部分:

MERGESORT(int[] A, int p, int r)
if(p < r)
then q= (p+r)/2
MERGESORT(A, p, q)
MERGESORT(A, q+1, r)
MERGE(A, p, q, r)

MERGE(int[] A, int p, int q, int r)

n1 = q-p+1

n2 = r-q

create arrays L[1..n1+1] and R[1..n2+1]

for i=1 to n1

L[i] = A[p+i-1]

for j=1 to n2

R[j] = A[q+j]

L[n1+1] = MAX_VALUE                           //此处在数组的最后放上最大的正整数方便在下面合并的时候控制数组的边界,防止越界

R[n2+1] = MAX_VALUE

i = 1

j = 1

for k=p to r

do if L[i] <= R[j]

then A[k] = L[i]

i = i+1

else A[k] = R[j]

j = j+1



算法性能分析:


时间复杂度:O(nlogn)
归并排序的时间复杂度分析使用分治的时间复杂度分析方法。
每次把数组平均分成两个子数组,问题的规模分解为2T(n/2),在含有n个元素的子数组上,合并所需要的时间是n,因此时间复杂度公式为:
T(n) = 2T(n/2) + cn

空间复杂度:O(n)
稳定性:稳定


归并排序的Java版本实现:

	private void sort(int[] A, int start, int end)
	{
		if(start < end)
		{
			int mid = start + (end - start)/2;
			sort(A, start, mid);
			sort(A, mid+1, end);
			merge(A, start, mid, end);
		}
	}
	
	private void merge(int[] A, int p, int q, int r)
	{
		int len1 = q - p +1;
		int len2 = r - q;
		
		int[] left = new int[len1+1];
		int[] right = new int[len2+1];
		left[len1] = Integer.MAX_VALUE;
		right[len2] = Integer.MAX_VALUE;
		for(int i=0;i<len1;i++)
			left[i] = A[p+i];
		for(int j=0;j<len2;j++)
			right[j] = A[q+j+1];
		
		int i=0;
		int j=0;
		for(int k=p;k<=r;k++)
		{
			if(left[i] <= right[j])
			{
				A[k] = left[i];
				i++;
			}
			else
			{
				A[k] = right[j];
				j++;
			}
		}
	}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值