算法说明:

归并排序的思路就是分而治之,将数组中的数字递归折半进行排序。 递归到最底层就只剩下有两个数字进行比较,再从底层往下进行排序合并。最终得出结果。

同样,语言描述可能对于不知道这个算法的人来说,理解的比较吃力,所以还是举个例子来简单说明一下。

首先,测试数据是int[] arrayData = { 5, 9, 6, 7, 4, 1, 2, 3, 8 }; 一共是9个元素。

然后拿visio画图,来对于归并排序的分而治之进行一下简单的剖析。

整体排序流程大概就是如上图了。 首先先是递归拆分,递归拆分到最底层后,再进行排序,如果参考下边的代码的话,那么Sort方法就是在往最底层递归,Merge方法就是在进行合并。

另外吐个嘈,上边那个图画的很累啊……

时间复杂度:

O(nlgn)

空间复杂度:

O(n+lgn)

代码:

语言:Java

/*
* 归并排序
*/
public class MergeSort {
public static void main(String[] args) {
int[] arrayData = { 5, 9, 6, 7, 4, 1, 2, 3, 8 };
int[] arrayResult = MergeSortMethod(arrayData);
for (int integer : arrayResult) {
System.out.print(integer);
System.out.print(" ");
}
} public static int[] MergeSortMethod(int[] arrayData) {
int[] arrayResult = new int[arrayData.length];
Sort(arrayData, 0, arrayData.length - 1, arrayResult);
return arrayResult;
} public static void Sort(int[] arraySource, int leftIndex, int rightIndex,
int[] arrayResult) {
if (leftIndex < rightIndex) {
int middleIndex = (leftIndex + rightIndex) / 2;
Sort(arraySource, leftIndex, middleIndex, arrayResult);
Sort(arraySource, middleIndex + 1, rightIndex, arrayResult);
Merge(arraySource, leftIndex, middleIndex, rightIndex, arrayResult);
}
} // 进到merge时,leftIndex至middleIndex的数据已被排好序了。
// middleIndex+1至rightIndex的数字也已经被排好序了
// 所以merge就是把排好序的数字合并到arrayResult中
public static void Merge(int[] arraySource, int leftIndex, int middleIndex,
int rightIndex, int[] arrayResult) {
int i = leftIndex;
int j = middleIndex + 1;
int k = 0;
// leftIndex至middleIndex 与 middleIndex+1至rightIndex
// 进行比较,左右两个数组哪个先循环完毕就跳出while
while (i <= middleIndex && j <= rightIndex) {
if (arraySource[i] <= arraySource[j]) {
arrayResult[k++] = arraySource[j++];
} else {
arrayResult[k++] = arraySource[i++];
}
} while (i <= middleIndex) {
arrayResult[k++] = arraySource[i++];
} while (j <= rightIndex) {
arrayResult[k++] = arraySource[j++];
} for (int l = 0; l < k; l++) {
arraySource[leftIndex + l] = arrayResult[l];
}
}
}

结果:

9 8 7 6 5 4 3 2 1

时间复杂度论证:Merge方法的时间复杂度是n ,然后Sort方法因为是二叉树性质的递归,所以时间复杂度是log2n,那么归并排序的复杂度就是O(nlog2n)。  log2n的时间耗费对于数学基础不好的朋友来说可能理解起来很吃力(例如我),所以大家可以参考http://xwrwc.blog.163.com/blog/static/46320003201141582544245/

空间复杂度论证: Merge因为要使用一个临时数组,所以空间复杂度是n。又另因为是递归迭代的,所以递归也占用空间复杂度log2n。所以归并排序的空间复杂度是O(n+log2n)

Hark的数据结构与算法练习之归并排序的更多相关文章

  1. Hark的数据结构与算法练习之多路归并排序

    算法说明 多路归并排序也叫k路归并排序,实际上是归并排序的扩展版,同样也是归并排序的一种,通常的应用场景的针对大数据量的排序. 实现过程: 1.从字面可以看出,多路归并就是将待排的大数据量分成K路,然 ...

  2. JavaScript 数据结构与算法之美 - 归并排序、快速排序、希尔排序、堆排序

    1. 前言 算法为王. 想学好前端,先练好内功,只有内功深厚者,前端之路才会走得更远. 笔者写的 JavaScript 数据结构与算法之美 系列用的语言是 JavaScript ,旨在入门数据结构与算 ...

  3. Hark的数据结构与算法练习之若领图排序ProxymapSort

    算法说明 若领图排序是分布排序的一种. 个人理解,若领图排序算是桶排序+计数排序的变异版,桶排序计数排序理解了,那么若领图排序理解起来就会比较容易.区别其实就是存储中间值的方式做了调整…… 话说,这个 ...

  4. Hark的数据结构与算法练习之珠排序

    ---恢复内容开始--- 算法说明 珠排序是分布排序的一种. 说实在的,这个排序看起来特别的巧妙,同时也特别好理解,不过不太容易写成代码,哈哈. 这里其实分析的特别好了,我就不画蛇添足啦.  大家看一 ...

  5. Hark的数据结构与算法练习之鸽巢排序

    算法说明 鸽巢排序是分布排序的一种,我理解其实鸽巢就是计数排序的简化版,不同之处就是鸽巢是不稳定的,计数排序是稳定的. 逻辑很简单,就是先找出待排数组的最大值maxNum,然后实例一个maxNum+1 ...

  6. Hark的数据结构与算法练习之锦标赛排序

    算法说明 锦标赛排序是选择排序的一种. 实际上堆排序是锦标赛排序的优化版本,它们时间复杂度都是O(nlog2n),不同之处是堆排序的空间复杂度(O(1))远远低于锦标赛的空间复杂度(O(2n-1)) ...

  7. Hark的数据结构与算法练习之圈排序

    算法说明 圈排序是选择排序的一种.其实感觉和快排有一点点像,但根本不同之处就是丫的移动的是当前数字,而不像快排一样移动的是其它数字.根据比较移动到不需要移动时,就代表一圈结束.最终要进行n-1圈的比较 ...

  8. Hark的数据结构与算法练习之梳排序

    算法说明梳排序是交换排序的一种,它其实也是改自冒泡排序,不同之处是冒泡排序的比较步长恒定为1,而梳排序的比较步长是变化的. 步长需要循环以数组长度除以1.3,到最后大于等于1即可. 光说可能比较抽象, ...

  9. Hark的数据结构与算法练习之地精(侏儒)排序

    算法说明 地精排序是交换排序的一种,它是冒泡排序的一种改良,我感觉和鸡尾酒排序挺像的. 不同之处是鸡尾酒排序是从小到大,然后再从大到小切换着排序的.而地精排序是上来先从小到大排序,碰到交换到再从大到小 ...

随机推荐

  1. form表单那点事儿(上) 基础篇

    form表单那点事儿(上) 基础篇 做为html中最为常见,应用最广泛的标签之一,form常伴随前端左右.了解更深,用的更顺. 目录: 表单属性 表单元素 常识 模拟外观 表单属性 这个表单展示了fo ...

  2. centos linux从无到有安装wordpress

    序:本博客从无到有搭建wordpress,包括从服务器和域名购买,会将步骤一步一步记录下来.如果你也是新手,那你有福了,因为我的系统是centos,对号入座啊. 目录 一.准备域名和服务器一.安装ph ...

  3. editplus快捷键大全其他editplus快捷键

    editplus快捷键大全其他editplus快捷键,更多快捷键请参考以下文章:editplus快捷键大全之editplus搜索快捷键 editplus快捷键大全之editplus编辑快捷键 edit ...

  4. 使用 systemd timer 备份数据库

    导读 主要的Linux发行版都改用systemd 来替代 System V启动方式,其中 systemd timer 能替代 crontab 计划任务的大部分功能.本文介绍了用systemd time ...

  5. Awvs如何扫描需要登录的部分

    一个小技巧,可能部分的人习惯了按下一步.所以不大知道.给大家说说哈. 到LOGIN步骤的时候,在Login sequen 新建.然后你懂的了.会新出来一个浏览器,直接登录后一直下一步即可

  6. 又是一个二模02,不过day2

    话说比较简单.除了第三题不会写平衡树啊你妹!!边做边写吧. 机智的链接~机智的链接~机智的链接~机智的链接~机智的链接~机智的链接~机智的链接~机智的链接~机智的链接~机智的链接~机智的链接~机智的链 ...

  7. thinkphp 前台html调用函数 格式化输出

    仅仅是输出变量并不能满足模板输出的需要,内置模板引擎支持对模板变量使用调节器和格式化功能,其实也就是提供函数支持,并支持多个函数同时使用.用于模板标签的函数可以是PHP内置函数或者是用户自定义函数,和 ...

  8. 查看Eclipse中的jar包的源代码:jd-gui.exe

    前面搞了很久的使用JAD,各种下载插件,最后配置好了,还是不能用,不知道怎么回事, 想起一起用过的jd-gui.exe这个工具,是各种强大啊!!! 只需要把jar包直接扔进去就可以了,非常清晰,全部解 ...

  9. 【转】MySQL Temporary Table相关问题的探究

    本文转载自:http://itindex.net/detail/10901-mysql-temporary-table 问题的引入 让我们先来观察几条非常简单的MySQL语句: mysql> c ...

  10. Android 中的code sign

    Android 中和ios中都有code sign.它们的目的一样,都是要保证程序的可靠性,最基本实现原理也一样.但是sign的过程比较不同. 下面记录一点Android sign的重要知识. 请参看 ...