排序算法之归并排序--Java语言

本文详细介绍了一种基于分治法的高效排序算法——归并排序。文章不仅解释了归并排序的基本原理,还提供了完整的Java实现代码,展示了排序过程中序列的变化情况。

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

归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。归并过程为:比较a[i]和b[j]的大小,若a[i]≤b[j],则将第一个有序表中的元素a[i]复制到r[k]中,并令i和k分别加上1;否则将第二个有序表中的元素b[j]复制到r[k]中,并令j和k分别加上1,如此循环下去,直到其中一个有序表取完,然后再将另一个有序表中剩余的元素复制到r中从下标k到下标t的单元。归并排序的算法我们通常用递归实现,先把待排序区间[s,t]以中点二分,接着把左边子区间排序,再把右边子区间排序,最后把左区间和右区间用一次归并操作合并成有序的区间[s,t]。
归并是将两个已排序合并成一个更大的已排序文件的过程,将输入序列分成两部分并递归处理每一部分。当子问题解决后,算法又将子问题的解合并。归并排序是从最小子文件开始并以最大子文件结束的。如下图所示,归并排序,先将序列对半分割,并不断递归对半分割,直到每一部分只剩一个元素,然后进行归并,即对多个子序列进行归并处理。

代码:
public class MergeSort {
	public static int[] mergeSort(int[] A,int[] temp,int left,int right)
	{
		int mid;
		if(right>left)
		{
			mid=left+(right-left)/2;//不直接使用(right+left)/2是防止溢出
			//对mid左右两边的序列进行递归分割
			mergeSort(A,temp,left,mid);
			mergeSort(A,temp,mid+1,right);
			//对分割到不能分割的序列进行归并
			Merge(A,temp,left,mid+1,right);
			print(A);
			
		}
		return A;
	}
	//以下是归并的过程
	private static void Merge(int[] A,int[] temp,int left,int mid,int right)
	{
		//以mid为界将数组分为两个数组,然后通过依次两个数组的数值大小,依次存入临时数组temp实现归并。
		int i,left_end,size,temp_pos;
		left_end=mid-1;
		temp_pos=left;
		size=right-left+1;
		while((left<=left_end)&&(mid<=right))
		{
			if(A[left]<=A[mid])
			{
				temp[temp_pos]=A[left];
				temp_pos=temp_pos+1;
				left=left+1;
			}
			else
			{
				temp[temp_pos]=A[mid];
				temp_pos+=1;
				mid+=1;
			}
		}
		while(left<=left_end)
		{
			temp[temp_pos]=A[left];
			left+=1;
			temp_pos+=1;
		}
		while(mid<=right)
		{
			temp[temp_pos]=A[mid];
			mid+=1;
			temp_pos+=1;
		}
		for(i=0;i<size;i++)
		{
			A[right]=temp[right];
			right-=1;
		}
	}
	private static void print(int[] A)
	{
		int n=A.length;
		for(int i=0;i<n;i++)
			System.out.print(A[i]+" ");
		System.out.println();
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[] A= {9,10,6,4,29,34,25,13,14,17,8,5};
		int n=12;
		int right=11;
		int left=0;
		int[] temp=new int[n];
		System.out.println("归并排序的序列变化:");
		int[] ans=MergeSort.mergeSort(A, temp, left, right);
		System.out.println("归并排序后的序列:");
		for(int i=0;i<n-1;i++)
			System.out.print(ans[i]+" ");
		System.out.print(ans[n-1]);

	}

}


测试结果:
归并排序的序列变化:
9 10 6 4 29 34 25 13 14 17 8 5 
6 9 10 4 29 34 25 13 14 17 8 5 
6 9 10 4 29 34 25 13 14 17 8 5 
6 9 10 4 29 34 25 13 14 17 8 5 
4 6 9 10 29 34 25 13 14 17 8 5 
4 6 9 10 29 34 13 25 14 17 8 5 
4 6 9 10 29 34 13 14 25 17 8 5 
4 6 9 10 29 34 13 14 25 8 17 5 
4 6 9 10 29 34 13 14 25 5 8 17 
4 6 9 10 29 34 5 8 13 14 17 25 
4 5 6 8 9 10 13 14 17 25 29 34 
归并排序后的序列:
4 5 6 8 9 10 13 14 17 25 29 34

归并排序以连续的方式访问数据,适用于链表排序;归并排序对输入的初始次序不敏感。当数据量十分大时,快排、选择等内部排序无法进行时,可以使用外部排序中的多路归并完成排序。归并排序的时间复杂度为O(nlogn),排序的效率较高。
转发请注明:转自http://blog.youkuaiyun.com/carson0408/article/details/78653021
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值