归并排序

算法描述

递归排序是把长度为n的输入序列分成两个长度为n/2的子序列,分别对这两个子序列采用递归排序,将两个排序好的子序列合并成一个最终的排序序列。它包含了分治的思想。

代码演示

public static void mergeSort(int arr[],int left,int right)
{
	if(left<right)
	{ 
		int mid=(left+right)/2;
		mergeSort(arr,left,mid);
		mergeSort(arr,mid+1,right);
		merge(arr,left,mid,right);
	}
}

public static void merge(int[] arr,int l,int m,int r)
{	
	//计算合并的两个子数组的大小
	int n1=m-l+1;
	int n2=r-m;
	//创建两个临时的子数组,存储要合并的两个子数组
	int L[]=new int[n1];
	int R[]=new int[n2];
	
	//拷贝数据
	for(int i=0;i<n1;++i)
		L[i]=arr[l+i];
	for(int j=0;j<n2;++j)
		R[j]=arr[m+1+j];

	//初始化两个临时子数组的下标
	int i=0,j=0;
	//初始化合并后数组的子下标(left)
	int k=l;
	while(i<n1 && j<n2)
	{
		if(L[i]<=R[j])
		{
			arr[k]=L[i];
			i++;
		}
		else
		{
			arr[k]=R[j];
			j++;
		}
		k++;
	}
	//如果L[]有剩余,拷贝
	while(i<n1)
	{
		arr[k]=L[i];
		i++;
		k++;
	}
	//如果R[]中有剩余,拷贝
	while(j<n2)
	{
		arr[k]=R[j];
		j++;
		k++;
	}
}
	

复杂度分析

时间复杂度

归并排序总时间=拆分时间+子数组排好序时间+合并时间
无论每个数组有多少个数都是折半拆分,也就是代码中的int m=(l+r)/2;,所以拆分时间就是个常数o(1),可以忽略不计。
则:归并排序时间=子数组排序时间+合并时间

归并排序的时间复杂度为:

  • 最好情况:T(n) = O(n)
  • 最差情况:T(n) = O(nlogn)
  • 平均情况:T(n) = O(nlogn)

空间复杂度

在合并的时候,我们使用了存储待合并的两个数组元素的空间,这个数组大小依次开辟的就是1,2,3,4,8,…, n/2, 但是开辟了两个,所以可能开辟的空间大小为2,4,8,…,n,归并排序的空间复杂度为o(n)。

稳定性分析

归并排序是稳定的排序算法,归并排序稳定的根本原因在于合并的时候对值相同的两个关键字不存在交换的可能性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值