码迷,mamicode.com
首页 > 其他好文 > 详细

排序算法总结之归并排序

时间:2014-09-07 19:50:35      阅读:244      评论:0      收藏:0      [点我收藏+]

标签:归并排序   java   排序算法   

基本思想

设归并排序的当前区间是R[low..high],分治法的三个步骤是:
①分解:将当前区间一分为二,即求分裂点
                 bubuko.com,布布扣
②求解:递归地对两个子区间R[low..mid]和R[mid+1..high]进行归并排序;
③组合:将已排序的两个子区间R[low..mid]和R[mid+1..high]归并为一个有序的区间R[low..high]。
  递归的终结条件:子区间长度为1(一个记录自然有序)。

 

将两个有序序列合并成一个新的有序序列。

①把 n 个记录看成 n 个长度为 1的有序子表;
②进行两两归并使记录关键字有序,得到 n/2 个长度为 2 的有序子表;
③重复第②步直到所有记录归并成一个长度为 n 的有序表为止。

bubuko.com,布布扣


重点:

1.分治的实现

2.合并的实现

分治,就是把整个集合的元素一直除2化分,一直化为到没有两个元素开始合并。

对于归并排序,其关键就在于“合并”,即如何将两个有序序列合并成一个新的有序序列。

合并的实现

  1. 定义变量i,j从0开始,分别指向A、B子序列的第一个数据;
  2. 比较i、j处的元素值,将较小的复制到一个临时数组
  3. 若i处的小,则i++;否则j处的小,则j++

bubuko.com,布布扣

排序动态效果:

bubuko.com,布布扣


Java实现代码:

 

package com.liuhao.sort;

import java.util.Arrays;

/**
 * @author liuhao
 * 归并排序的Java实现
 */

public class MergeSort {

	public static void mergeSort(DataWrap[] data){
		sort(data, 0, data.length - 1);
	}
	
	/**
	 * 对数组data从left到right范围内的数据进行归并排序
	 * @param data 待排序数组
	 * @param left 
	 * @param right
	 */
	private static void sort(DataWrap[] data, int left, int right){
		if(left < right){
			//找到中间索引
			int center = (left + right) / 2;
			//对左边数组递归排序
			sort(data, left, center);
			//对右边数组递归排序
			sort(data, center+1, right);
			
			//合并
			merge(data, left, center, right);
		}
	}

	/**
	 * 将两个数组进行合并,归并前两个数组已经有序,归并后依然有序
	 * @param data 数组对象
	 * @param left 左数组的第一个索引
	 * @param center 左数组的最后一个元素索引,center+1是右数组的第一个元素索引
	 * @param right 右数租的最后一个元素索引
	 */
	private static void merge(DataWrap[] data, int left, int center, int right) {
		DataWrap[] tmpArr = new DataWrap[data.length];//用来存放比较的数组,用完复制回到原来的数组
		int mid = center + 1; //右数组的第一个元素索引
		//third记录中间数组的索引
		int third = left;
		int tmp = left;
		
		while(left <= center && mid <= right){
			//将两个数组中较小的放入临时数组
			if(data[left].compareTo(data[mid]) <= 0){
				tmpArr[third++] = data[left++];
			}
			else{
				tmpArr[third++] = data[mid++];
			}
		}
		
		//剩余部分依次放入中间数组
		while(mid <= right){
			tmpArr[third++] = data[mid++];
		}
		while(left <= center){
			tmpArr[third++] = data[left++];
		}
		
		//将中间数组中的内容复制到原数组
		while(tmp <= right){
			data[tmp] = tmpArr[tmp++];
		}
		
	}
	
	public static void main(String[] args) {
		DataWrap[] data = {
				new DataWrap(9, "")
				,new DataWrap(-16, "")
				,new DataWrap(21, "")
				,new DataWrap(23, "*")
				,new DataWrap(-30, "")
				,new DataWrap(-49, "")
				,new DataWrap(21, "")
				,new DataWrap(30, "")
				,new DataWrap(3, "")
				,new DataWrap(67, "")
				,new DataWrap(35, "")
				,new DataWrap(5, "")
		};
		
		System.out.println("排序之前:" + Arrays.toString(data));
		mergeSort(data);
		System.out.println("排序之后:" + Arrays.toString(data));
	}
	
}

代码实现效果:

bubuko.com,布布扣


算法分析

1、稳定性
     归并排序是一种稳定的排序。
2、存储结构要求
    可用顺序存储结构。也易于在链表上实现。
3、时间复杂度
    对长度为n的文件,需进行bubuko.com,布布扣 趟二路归并,每趟归并的时间为O(n),故其时间复杂度无论是在最好情况下还是在最坏情况下均是O(nlgn)。
4、空间复杂度
    需要一个辅助向量来暂存两有序子文件归并的结果,故其辅助空间复杂度为O(n),显然它不是就地排序。

排序算法总结之归并排序

标签:归并排序   java   排序算法   

原文地址:http://blog.csdn.net/bruce_6/article/details/39121643

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!