week3——归并排序
来源:互联网 发布:手机淘宝4.2.2安卓版 编辑:程序博客网 时间:2024/06/18 07:08
声明
本文是博主在Coursera学习时所写的学习笔记,如有错误疏漏还望各位指正。
欢迎交流讨论
如果大家转载,请注明本文地址!
归并排序
基本思想
- 将列表分为两部分
- 通过递归将每部分排序
- 合并两部分
举个例子
输入一个数组
将其分为两部分,并对每个部分排序,如下图
合并两部分
新建一个aux[]的拷贝a[]
设两部分最小元素的下标为i,j,每次比较i,j所对应的元素大小,将较小的元素放入a[],让后将i或j加1,直至将两部分合并完成。
算法分析
- 时间复杂度
比较次数:O(NlogN)
数组访问次数:O(6NlogN) - 空间复杂度
需要额外的O(N) ,这是归并排序最明显的缺点
代码实现
public class MergeSort { //合并 private static void merge(Comparable[] a, Comparable[] aux, int lo, int mid, int hi) { for (int k = lo; k <= hi; k++) aux[k] = a[k]; int i = lo, j = mid + 1; for (int k = lo; k <= hi; k++) { if (i > mid) a[k] = aux[j++]; else if (j > hi) a[k] = aux[i++]; else if (less(aux[j], aux[i])) a[k] = aux[j++]; else a[k] = aux[i++]; } } private static boolean less(Comparable a, Comparable b) { return a.compareTo(b) < 0; } private static void sort(Comparable[] a, Comparable[] aux, int lo, int hi) { if (hi <= lo) return; int mid = lo + (hi - lo) / 2; sort(a, aux, lo, mid); sort(a, aux, mid + 1, hi); merge(a, aux, lo, mid, hi); } public static void sort(Comparable[] a) { Comparable[] aux = new Comparable[a.length]; sort(a, aux, 0, a.length - 1); }}
改进
对划分后较小的数组使用插入排序
因为递归的原因,归并排序对较小的数组有很大开销,因此对较小的数组我们改用插入排序
将上述的sort(Comparable[] a, Comparable[] aux, int lo, int hi)改为如下:
private static void sort(Comparable[] a, Comparable[] aux, int lo, int hi){ //当数组长度小于CUTOFF时使用插入排序,CUTOFF应设置为常数。 if (hi <= lo + CUTOFF - 1) { Insertion.sort(a, lo, hi); return; } int mid = lo + (hi - lo) / 2; sort (a, aux, lo, mid); sort (a, aux, mid+1, hi); merge(a, aux, lo, mid, hi);}
如果归并前排序已经完成则停止
对划分后的两部分分别排序后,如果左边最大的元素小于右边最大的元素,则不要进行归并
将sort(Comparable[] a, Comparable[] aux, int lo, int hi)改为如下:
private static void sort(Comparable[] a, Comparable[] aux, int lo, int hi){ if (hi <= lo) return; int mid = lo + (hi - lo) / 2; sort (a, aux, lo, mid); sort (a, aux, mid+1, hi); //新添加的代码 if (!less(a[mid+1], a[mid])) return; merge(a, aux, lo, mid, hi);}
自下而上归并排序
基本思想
将数组划分为长度为1的若干数组,合并成为长度为2的若干数组。
将长度为2的书组合并成长度为4的若干数组。以此类推,直至排序完成。
举个例子
示例图
代码实现
将sort(Comparable[] a)改为如下:
public static void sort(Comparable[] a){ int N = a.length; Comparable[] aux = new Comparable[N]; for (int sz = 1; sz < N; sz = sz+sz)//每次归并的数组长度,1,2,4,8.... for (int lo = 0; lo < N-sz; lo += sz+sz)//每次归并的子数组a[lo]~a[N-sz] merge(a, aux, lo, lo+sz-1, Math.min(lo+sz+sz-1, N-1));}
说明
这种自下而上的归并排序是一种简单的无递归归并排序,但是要大约比应用递归的自顶而下的归并排序慢10%
0 0
- week3——归并排序
- week3——快速排序
- 排序—归并排序
- 数据结构 — 归并排序
- 数据结构 — 归并排序
- 排序——归并排序
- 排序——归并排序
- 排序——归并排序
- 排序——归并排序
- 排序——归并排序
- 排序——归并排序
- 排序——归并排序
- 排序——归并排序
- 排序——归并排序
- 排序算法—归并排序
- 内部排序—归并排序
- 排序算法—归并排序
- 归并排序——二路归并排序
- Android----MVP模式的理解
- 算法导论例程——红黑树
- C++对象数组与对象指针
- HDU-1164
- 杭电1671——Phone List(字典树的应用)
- week3——归并排序
- Codeforces 624B Making a String 【水题】
- 项目技术总结三之分布与集群的区别
- mysql 中导入数据库时提示 MySQL server has gone away
- ubuntu10.04貌似安装不了最新版本的chrome
- 07、字体
- 必过的节日
- 避免僵尸进程
- 对于hadoop生态圈的理解