Java版归并排序


归并排序是利用递归与分治技术将数据序列分为越来越小的半子表,再对半子表排序,最后再用递归方法将排好的半子表合并为越来越大的有序序列。

归并排序算法的原理如下:对于给定的一组记录(假设有n个记录),首先将每两个相邻的长度为1的序列进行归并,得到n/2(向上取整数)个长度为2或1的有序子序列,再将其两两合并,反复执行此过程,直到得到一个有序序列。

所以,归并排序的关键就是前两步:

第一步:划分半子表;

第二步:合并半子表。

以数组{49,38,65,97,76,13,27}为例,归并排序的具体步骤如下:

初始关键字:[49] [38][65] [97][76] [13][27]

一趟归并后:[38  49]   [65  97]  [13  76]   [27]

二趟归并后:[38  49   65   97]  [13  27  76  ]

三趟归并后:[13 27  38  49  65  76  97]

程序代码如下:

package chapter8;

public class MergeSortTest {
	
	public static void mergeSort(int[] data){
		sort(data,0,data.length-1);
	}
	public static void sort(int[] data,int left,int right){
		if(left>=right)
			return;
		//找出中间索引
		int center=(left+right)/2;
		//对左边数组进行递归
		sort(data,left,center);
		//对右边数组进行递归
		sort(data,center+1,right);
		//合并
		merge(data,left,center,right);
		print(data);
	}
	/**
	 * 将两个数组进行归并,归并前面2个数字已有序,归并后依然有序
	 * @param data 数组对象
	 * @param left 左数组的第一个元素的作引
	 * @param center 左数组的最后一个元素的作引,center+1是右数组第一个元素的索引
	 * @param right  右数组最后一个元素的索引
	 */
	public static void merge(int[] data,int left,int center,int right){
		//临时数组
		int[] tmpArr=new int[data.length];
		//右数组第一个元素索引
		int mid=center+1;
		//third记录临时数组的索引
		int third=left;
		//缓存左数组第一个元素的索引
		int tmp=left;
		while(left<=center && mid<=right){
			//从两个数组中取出最小的放入临时数组
			if(data[left]<=data[mid]){
				tmpArr[third++]=data[left++];
			}else{
				tmpArr[third++]=data[mid++];
			}
		}
		//剩余部分一次放入临时数组(实际上两个while只会执行其中一个)
		while(mid<=right){
			tmpArr[third++]=data[mid++];
		}
		while(left<=center){
			tmpArr[third++]=data[left++];
		}
		//将临时数组中的内容拷贝回原数组中
		//(原left-right范围的内容被复制回原数组)
		while(tmp<=right){
			data[tmp]=tmpArr[tmp++];
		}
	}
	public static void print(int[] data){
		for(int i=0;i
  
  

程序运行结果:

5	3	6	2	1	9	4	8	7	
3	5	6	2	1	9	4	8	7	
3	5	6	2	1	9	4	8	7	
3	5	6	1	2	9	4	8	7	
1	2	3	5	6	9	4	8	7	
1	2	3	5	6	4	9	8	7	
1	2	3	5	6	4	9	7	8	
1	2	3	5	6	4	7	8	9	
1	2	3	4	5	6	7	8	9	
排序后的数组:
1	2	3	4	5	6	7	8	9


归并排序算法复杂度分析:

最好时间:O(nlogn)

平均时间:O(nlogn)

最坏时间:O(nlogn)

辅助存储:O(n)

稳定性:稳定

备注:n大时较好

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值