`
xuela_net
  • 浏览: 495364 次
文章分类
社区版块
存档分类
最新评论

数据结构排序系列详解之七 归并排序

 
阅读更多

在前面说的那几种排序都是将一组记录按关键字大小排成一个有序的序列,而归并排序的思想是:基于合并,将两个或两个以上有序表合并成一个新的有序表

归并排序算法:假设初始序列含有n个记录,首先将这n个记录看成n个有序的子序列,每个子序列长度为1,然后两两归并,得到n/2个长度为2(n为奇数的时候,最后一个序列的长度为1)的有序子序列。在此基础上,再对长度为2的有序子序列进行亮亮归并,得到若干个长度为4的有序子序列。如此重复,直到得到一个长度为n的有序序列为止。这种方法被称作是:2-路归并排序(基本操作是将待排序列中相邻的两个有序子序列合并成一个有序序列)。


算法实现代码如下:


package exp_sort;

public class MergeSort {

	/**
	 * 相邻两个有序子序列的合并算法
	 * 
	 * @param src_array
	 * @param low
	 * @param high
	 * @param des_array
	 */
	public static void Merge(int src_array[], int low, int high,
			int des_array[]) {
		int mid;
		int i, j, k;

		mid = (low + high) / 2;
		i = low;
		k = 0;
		j = mid + 1;

		// compare two list
		while (i <= mid && j <= high) {
			if (src_array[i] <= src_array[j]) {
				des_array[k] = src_array[i];
				i = i + 1;
			} else {
				des_array[k] = src_array[j];
				j = j + 1;
			}

			k = k + 1;
		}

		// if 1 have,cat
		while (i <= mid) {
			des_array[k] = src_array[i];
			k = k + 1;
			i = i + 1;

		}

		while (j <= high) {
			des_array[k] = src_array[j];
			k = k + 1;
			j = j + 1;
		}

		for (i = 0; i < k; i++) {
			src_array[low + i] = des_array[i];
		}

	}

	/**
	 * 2-路归并排序算法,递归实现
	 * 
	 * @param src_array
	 * @param low
	 * @param high
	 * @param des_array
	 */
	public static void mergeSort(int src_array[], int low, int high,
			int des_array[]) {
		int mid;
		if (low < high) {
			mid = (low + high) / 2;
			mergeSort(src_array, low, mid, des_array);
			mergeSort(src_array, mid + 1, high, des_array);
			Merge(src_array, low, high, des_array);
		}
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		int array1[] = { 38, 62, 35, 77, 55, 14, 35, 98 };
		int array2[] = new int[array1.length];
		mergeSort(array1, 0, array1.length - 1, array2);

		System.out.println("\n----------after sort-------------");
		for (int ii = 0; ii < array1.length; ii++) {
			System.out.print(array1[ii] + " ");
		}
		System.out.println("\n");
	}

}



代码解释:

归并排序中一趟归并要多次调用到2-路归并算法,一趟的归并的时间复杂度是O(n),合并两个已经排好序的表的时间显然是线性的,因为最多进行了n-1次比较,其中n是元素的总数。如果有多个数,即n不为1时,递归的将前半部分数据和后半部分数据各自归并排序,得到排序后的两部分数据,再合并到一起。


算法分析:

该算法是建立在归并操作(也叫归并算法,指的是将两个已经排序的序列合并成一个序列的操作)上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用,它将问题分成一些小的问题然后递归求解,而治的阶段则是将分的阶段解得的各个答案修补到一块;分治是递归非常有力的用法。注意:与快速·排序和堆排序比较,归并排序最大的特点就是,它一种稳定的排序方法。速度仅次于快速排序,一般用于对总体无序,但是各子项相对有序的数列。


复杂度:

时间复杂度为:O(nlogn) ——该算法最好、最坏和平均的时间性能。
空间复杂度为 :O(n)
比较操作的次数介于(nlogn) / 2和 nlogn - n + 1之间。
赋值操作的次数是(2nlogn)。归并算法的空间复杂度为:0 (n)
很难用于主存排序(归并排序比较占用内存,主要问题在于合并两个排序的表需要线性附加内存,在整个算法中还要花费将数据拷贝到临时数组再拷贝回来这样的一些附加操作,其结果严重放慢了排序的速度)但是效率很高,主要用于外部排序,对于重要的内部排序应用而言,一般还是选择快速排序。


归并操作的步骤如下:
第一步:申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
第二步:设定两个指针,最初位置分别为两个已经排序序列的起始位置
第三步:比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
重复步骤3直到某一指针达到序列尾
将另一序列剩下的所有元素直接复制到合并序列尾

归并排序的步骤如下(假设序列共有n个元素):
将序列每相邻两个数字进行归并操作(merge),形成floor(n/2)个序列,排序后每个序列包含两个元素
将上述序列再次归并,形成floor(n/4)个序列,每个序列包含四个元素
重复步骤2,直到所有元素排序完毕


分享到:
评论

相关推荐

    java数据结构排序算法之归并排序详解

    主要介绍了java数据结构排序算法之归并排序,结合具体实例形式详细分析了归并排序的原理、实现技巧与相关注意事项,需要的朋友可以参考下

    python数据结构与算法详解与源码

    数据结构与算法(Python) 一、引入概念 1-01算法引入 1-02 时间复杂度与大O表示法 1-03-最坏时间复杂度与计算规则 1-04-常见时间复杂度与大小关系 1-05-代码执行时间测量模块 1-06-Python列表类型不同操作的...

    C语言数据结构 链表与归并排序实例详解

    主要介绍了C语言数据结构 链表与归并排序实例详解的相关资料,需要的朋友可以参考下

    排序-详解-数据结构

    主要知识点 插入排序 直接插入排序 O(n2) 希尔排序 O(n(lbn)2) 选择排序 直接选择排序O(n2) 堆排序O(nlbn) 交换排序 冒泡排序O(n2) 快速排序O(nlbn) 二路归并排序O(nlbn) 基数排序O(mn)

    数据结构之归并排序的实例详解

    主要介绍了数据结构之归并排序的实例详解的相关资料,这里对归并排序进行详细介绍,需要的朋友可以参考下

    数据结构实验1线性表归并及附加题详解

    从键盘输入数据,建立两个有序线性表(每个线性表的输入数据按由小到大次序输入来建立线性表,不必考虑排序算法);输出建好的这两个有序线性表;将这两个有序线性表归并为一个有序线性表;输出归并后的有序线性表。 ...

    考研-数据结构-殷人昆.zip

    8.5 二路归并排序 247 8.6 基数排序 248 8.7 外部排序 252 8.7.1 概念与流程 252 8.7.2 置换-选择排序 253 8.7.3 佳归并树 254 8.7.4 败者树 255 8.7.5 时间与空间复杂度相关问题 257 8.8 排序知识点小结 258 ▲真题...

    JS中的算法与数据结构之常见排序(Sort)算法详解

    主要介绍了JS中的算法与数据结构之常见排序(Sort)算法,结合实例形式详细分析了js常见排序算法中的冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序等算法相关实现技巧与操作注意事项,需要的朋友可以...

    十大基本排序

    数据结构十大排序详解,插入,希尔,冒泡,快速,选择,堆,归并,桶,基数,二分十个排序的应用

    哈工大2012秋数据结构与算法期末考试(答案题解).pdf

    下标从 1 开始,B[k]=1+2+3+…+n-1=n(n-1)/2, 所以选 D 4.D 【详解】本题考查各种排序的算法思想,堆排序、冒泡排序、选择排序第一次元素即在相应 的位置上,只有插入排序有可能如问题所述,所以选D。 5.C 【详解】...

    什么是字典序?字典序详解.md

    许多排序算法,如冒泡排序、插入排序、归并排序等,都可以用于按字典序对字符串进行排序。此外,字典序也常用于数据结构的遍历,如树的遍历算法中经常采用先序遍历(前序遍历)、中序遍历和后序遍历,这些遍历方式都...

    c语言例程大全,帮你学习c编程

    * 数据结构中的所有排序算法(冒泡排序,堆排序,直接插入排序,二路归并排序,快速排序,基数排序,直接选择排序,希尔排序)的例子; * 丰富的数组,位,指针,枚举,结构体,联合体等操作的例子; * 一个...

    C语言例程库(CLEL_v2.2)

    * 数据结构中的所有排序算法(冒泡排序,堆排序,直接插入排序,二路归并排序,快速排序,基数排序,直接选择排序,希尔排序)的例子; * 丰富的数组,位,指针,枚举,结构体,联合体等操作的例子; * 一个...

    C#数据结构

    书中介绍了 算法、线性表、栈和队列、串和数组、树和二叉树、图、排序(直接插入排序、冒泡排序、简单选择排序、堆排序、归并排序....)、查找 看完之后肯定有所提高。

    C++快速排序的分析与优化详解

    相信学过数据结构与算法的朋友对于快速排序应该并不陌生,本文就以实例讲述了C++快速排序的分析与优化,对于C++算法的设计有很好的借鉴价值。具体分析如下: 一、快速排序的介绍 快速排序是一种排序算法,对包含n个...

    最新Python3.5零基础+高级+完整项目(28周全)培训视频学习资料

    最新Python3.5零基础+高级+完整项目(28周全)培训视频学习资料;本资料仅用于学习。 【课程内容】 第1周 开课介绍 python发展介绍 第一个python程序 变量 字符编码与二进制 字符编码的区别与介绍 ...数据结构其他

    LeetCodeLearning:这个仓库主要用于每天一题,大家的自发刷题,大家可以自由的提交和修改

    高度自律多刷题基本数据结构和算法 (后续我会每天找时间补充)链表链表双向链表哈希表/散列表 (Hash Table)散列函数碰撞解决排序算法冒泡排序插入排序选择排序希尔排序快排归并排序堆排序查找算法有序表查找:二分...

    C程序范例宝典(基础代码详解)

    实例133 归并排序 198 4.3 查找算法 199 实例134 顺序查找 199 实例135 二分查找 201 实例136 分块查找 202 实例137 哈希查找 203 4.4 定理与猜想 206 实例138 斐波那契数列 206 实例139 角谷猜想...

Global site tag (gtag.js) - Google Analytics