Hark的数据结构与算法练习之归并排序
算法说明:
归并排序的思路就是分而治之,将数组中的数字递归折半进行排序。 递归到最底层就只剩下有两个数字进行比较,再从底层往下进行排序合并。最终得出结果。
同样,语言描述可能对于不知道这个算法的人来说,理解的比较吃力,所以还是举个例子来简单说明一下。
首先,测试数据是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的数据结构与算法练习之归并排序的更多相关文章
- Hark的数据结构与算法练习之多路归并排序
算法说明 多路归并排序也叫k路归并排序,实际上是归并排序的扩展版,同样也是归并排序的一种,通常的应用场景的针对大数据量的排序. 实现过程: 1.从字面可以看出,多路归并就是将待排的大数据量分成K路,然 ...
- JavaScript 数据结构与算法之美 - 归并排序、快速排序、希尔排序、堆排序
1. 前言 算法为王. 想学好前端,先练好内功,只有内功深厚者,前端之路才会走得更远. 笔者写的 JavaScript 数据结构与算法之美 系列用的语言是 JavaScript ,旨在入门数据结构与算 ...
- Hark的数据结构与算法练习之若领图排序ProxymapSort
算法说明 若领图排序是分布排序的一种. 个人理解,若领图排序算是桶排序+计数排序的变异版,桶排序计数排序理解了,那么若领图排序理解起来就会比较容易.区别其实就是存储中间值的方式做了调整…… 话说,这个 ...
- Hark的数据结构与算法练习之珠排序
---恢复内容开始--- 算法说明 珠排序是分布排序的一种. 说实在的,这个排序看起来特别的巧妙,同时也特别好理解,不过不太容易写成代码,哈哈. 这里其实分析的特别好了,我就不画蛇添足啦. 大家看一 ...
- Hark的数据结构与算法练习之鸽巢排序
算法说明 鸽巢排序是分布排序的一种,我理解其实鸽巢就是计数排序的简化版,不同之处就是鸽巢是不稳定的,计数排序是稳定的. 逻辑很简单,就是先找出待排数组的最大值maxNum,然后实例一个maxNum+1 ...
- Hark的数据结构与算法练习之锦标赛排序
算法说明 锦标赛排序是选择排序的一种. 实际上堆排序是锦标赛排序的优化版本,它们时间复杂度都是O(nlog2n),不同之处是堆排序的空间复杂度(O(1))远远低于锦标赛的空间复杂度(O(2n-1)) ...
- Hark的数据结构与算法练习之圈排序
算法说明 圈排序是选择排序的一种.其实感觉和快排有一点点像,但根本不同之处就是丫的移动的是当前数字,而不像快排一样移动的是其它数字.根据比较移动到不需要移动时,就代表一圈结束.最终要进行n-1圈的比较 ...
- Hark的数据结构与算法练习之梳排序
算法说明梳排序是交换排序的一种,它其实也是改自冒泡排序,不同之处是冒泡排序的比较步长恒定为1,而梳排序的比较步长是变化的. 步长需要循环以数组长度除以1.3,到最后大于等于1即可. 光说可能比较抽象, ...
- Hark的数据结构与算法练习之地精(侏儒)排序
算法说明 地精排序是交换排序的一种,它是冒泡排序的一种改良,我感觉和鸡尾酒排序挺像的. 不同之处是鸡尾酒排序是从小到大,然后再从大到小切换着排序的.而地精排序是上来先从小到大排序,碰到交换到再从大到小 ...
随机推荐
- Highways(prim & MST)
Highways Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 23421 Accepted: 10826 Descri ...
- Centos 7 安装LAMP环境
一.安装Centos 官网下载Centos 7刻录成光盘后安装 二.安装apache yum install httpd #根据提示,输入Y安装即可成功安装 systemctl start httpd ...
- rocksdb 编译安装 日志
Compilation RocksDB's library should be able to compile without any dependency installed, although w ...
- 使用msgfmt编译多语言文件
msgfmt --statistics --verbose -o django.mo django.po
- 【Python】Django 如何直接返回404 被 curl,wget 捕获到
代码示例: from django.http import Http404, HttpResponseNotFound #raise Http404(filename) return HttpResp ...
- 应用 JD-Eclipse 插件实现 RFT 中 .class 文件的反向编译
概述 反编译是一个将目标代码转换成源代码的过程.而目标代码是一种用语言表示的代码 , 这种语言能通过实机或虚拟机直接执行.文本所要介绍的 JD-Eclipse 是一款反编译的开源软件,它是应用于 Ec ...
- 37.寻找丑数[Ugly numbers]
[题目] 我们把只包含质因子2.3和5的数称作丑数(Ugly Number),例如:2,3,4,5,6,8,9,10,12,15,等,习惯上我们把1当做是第一个丑数.求按从小到大的顺序的第1500个丑 ...
- auto_ptr浅析(转载)
转载自http://www.cnblogs.com/qytan36/archive/2010/06/28/1766555.html auto_ptr是C++标准库中(<utility>)为 ...
- Java面向对象的多态
Java中多态的概念是面向对象中除封装和继承外非常重要的知识点,也是Java面向对象三大特性最后一个特性 多态其实就是指对象存在的多种形态,多态分为引用多态和方法多态 引用多态的含义就是:父类的引用可 ...
- 如何在Ubuntu下安装”.deb“、”.bin“、”.tar.gz“、”.tar.bz2“格式的软件包!
今天在Ubuntu11.10中安装Google chrome浏览器是遇到了问题,下载好的“.deb”格式的安装文件google-chrome-stable.deb双击后或者右键快捷菜单选择 Synap ...