算法学习笔记--归并排序
来源:互联网 发布:三六五网络董事长 编辑:程序博客网 时间:2024/05/29 17:26
归并排序:一种简单的利用递归排序的算法,将一个数组先(递归地)将它分成两半分别排序,然后将两半分别排序,然后将结果归并起来。
原地归并的抽象方法:
public static void merge(int[] a, int lo, int mid, int hi){ //将a[lo..mid] 和 a[mid+1..hi] 归并 int N = a.length; int[] b = new int[N]; int i = lo; int j = mid + 1; for (int k = lo; k <= hi; k++) { b[k] = a[k]; } //归并回a[lo..hi] for (int k = lo; k <= hi; k++) { if(i > mid){ a[k] = b[j++]; }else if(j > hi){ a[k] = b[i++]; } else if(b[i] < b[j]){ a[k] = b[i++]; }else{ a[k] = b[j++]; } } }
先将所有元素复制到吧b[]中,然后再归并回a[]中。
归并轨迹如下图:
自顶向下的归并排序:
这是基于原地归并的抽象实现的递归归并,应用了高效算法设计中的分治思想的典型的例子。
public static void sort(int[] a, int lo, int hi){ // lo,hi 数组下标 if(hi <= lo){ return; } int mid = lo + (hi-lo)/2; sort(a, lo, mid); //将左半边排序 sort(a, mid+1, hi); //将右半边排序 Merge.merge(a, lo, mid, hi); //原地归并的抽象方法 }
要对数组 a[lo..hi] 进行排序,先将它分为a[lo..mid] 和 a[mid+1..hi] 两部分,分别通过递归调用将它们单独排序,最后将有序的子数组归并为最终的排序结果。
归并结果轨迹:
自底向上的归并排序:
这种排序的思想是:先归并那些微型数组,然后再成对归并得到的子数组。
先进行两两归并,然后再四四归并,再八八归并。。。
public static void sort(int[] a){ int N = a.length; for (int sz = 1; sz < N; sz = 2*sz) { //子数组的大小 for (int lo = 0; lo < N - sz; lo += 2*sz) { // lo为子数组的索引 Merge.merge(a, lo, lo + sz - 1, Math.min(N - 1, lo + 2*sz -1)); } } }
归并轨迹图:
特点:
对于长度为N的任意数组,归并排序需要(1/2)N/lgN至NlgN次比较,最多需要访问数组6NlgN次。
可以用归并排序处理数百万甚至更大规模的数组。
0 0
- 算法学习笔记----归并排序
- 归并排序算法学习笔记
- 算法学习笔记--归并排序
- 基础算法学习笔记—归并排序
- 归并排序-《算法导论》学习笔记二
- 《算法导论》学习笔记:归并排序
- 算法笔记--归并排序
- 归并排序算法笔记
- 算法学习-归并排序
- 归并排序算法学习
- 算法学习-归并排序
- 算法学习--归并排序
- 算法学习:归并排序
- [学习笔记]Java排序算法之归并排序
- 《数据结构与算法》学习笔记9 希尔排序、归并排序
- 归并排序学习笔记
- 学习笔记-归并排序
- 算法笔记之归并排序
- [acm/icpc2016香港赛区][Kattis] Slim Cut 支持撤销的动态规划(?)
- Laravel子查询
- php 中use关键字的用法
- mysql dba系统学习(5)二进制日志binlog之一
- 华为手机日志打印不全解决方案
- 算法学习笔记--归并排序
- Unity Assets目录下的特殊文件夹名称(作用和是否会被打包到build中)
- Java的Listener与Filter详解
- Html5笔记之第二天
- Scala语法中的协变与逆变
- Java并发之线程池(一)
- mysql dba系统学习(6)二进制日志binlog之二
- Mysql中文乱码问题分析
- maven配置之setting配置