归并排序(algs4)
来源:互联网 发布:js获取flash对象 编辑:程序博客网 时间:2024/05/10 16:02
将两个有序的数组归并成一个更大的有序数组。要将一个数组排序,可以先(递归地)将它分成两半分别排序,然后将结果归并起来。
归并排序是算法中分治思想的典型应用
归并排序所需的时间和NlgN成正比。辅助数组所需的额外空间和N的大小成正比。
归并排序是一种渐进最优的基于比较排序的算法。
1. 原地归并
将涉及的所有元素复制到一个辅助数组,再把归并的结果放回原数组。
private static void merge(Comparable[] a,int lo,int mid,int hi){ /*将a[lo..mid]和a[mid+1..hi]归并*/int i=lo;int j=mid+1;for(int k=0;k<=hi;k++) /*将a[lo..hi]复制到aux[lo..hi]*/aux[k]=a[k];for(int k=lo;k<=hi;k++) /*归并回到a[lo..hi]*/{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++];}}
2.自顶向下的归并排序
归纳证明:如果它能将两个子数组排列,他就能够通过归并两个子数组来将整个数组排序。
private static Comparable[] aux; /*归并所需的辅助数组*/public static void sort(Comparable[] a){aux=new Comparable[a.length]; /*一次性分配空间*/sort(a,0,a.length-1);}private static void sort(Comparable[] a,int lo,int hi){ /*将数组a[lo..hi]排序*/if(hi<=lo) return;int mid = lo+(hi-lo)/2;sort(a,lo,mid); /*将左半边排序*/sort(a,mid+1,hi); /*将右半边排序*/merge(a,lo,mid,hi); /*归并结果*/}
3.自底向上的归并排序
先归并微型数组,然后再成对归并得到子数组
private static Comparable[] aux;public static void sort(Comparable[] a){ /*进行lg次两两归并*/int N=a.length;aux=new Comparable[N]; for(int sz=1;sz<N;sz=2*sz) /*sz子数组大小,初始值为1每次加倍*/ for(int lo=0;lo<N-sz;lo=lo+2*sz) /*lo子数组索引*/ merge(a,lo,lo+sz-1,Math.min(lo+2*sz-1,N-1));}
4.附录
package _2_Sorting;import java.util.Scanner;public class Merge{/** 算法2.4 自顶向下的归并排序(Top-down mergesort) * 要对子数组a[lo..hi]进行排序, * 先将它分为a[lo..mid]和[mid+1..hi]两部分,分别通过递归调用将他们单独排序, * 最后将有序的子数组归并为最终的排序结果。*/private static Comparable[] aux; /*归并所需的辅助数组*/public static void sort(Comparable[] a){aux=new Comparable[a.length]; /*一次性分配空间*/sort(a,0,a.length-1);}private static void sort(Comparable[] a,int lo,int hi){ /*将数组a[lo..hi]排序*/if(hi<=lo) return;int mid = lo+(hi-lo)/2;sort(a,lo,mid); /*将左半边排序*/sort(a,mid+1,hi); /*将右半边排序*/merge(a,lo,mid,hi); /*归并结果*/}private static void merge(Comparable[] a,int lo,int mid,int hi){ /*将a[lo..mid]和a[mid+1..hi]归并*/int i=lo;int j=mid+1;for(int k=0;k<=hi;k++) /*将a[lo..hi]复制到aux[lo..hi]*/aux[k]=a[k];for(int k=lo;k<=hi;k++) /*归并回到a[lo..hi]*/{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 v,Comparable w){return v.compareTo(w)<0;}private static void exch(Comparable[] a,int i,int j){Comparable t=a[i];a[i]=a[j];a[j]=t;}private static void show(Comparable[] a){for(int i=0;i<a.length;i++)System.out.println(a[i]+" ");System.out.println();}private static boolean isSorted(Comparable[] a){for(int i=1;i<a.length;i++)if(less(a[i],a[i-1]))return false;return true;}public static void main(String[] args){Scanner sc=new Scanner(System.in);int N;N=sc.nextInt();String[] a=new String[N];sc.nextLine(); /*读走换行*/System.out.println("请输入"+N+"个字符串:");for(int i=0;i<N;i++)a[i]=sc.nextLine();sort(a);show(a);}}
package _2_Sorting;import java.util.Scanner;/**自底向上的归并排序(Bottom-up mergesort) * 先进行两两归并、再进行四四归并、然后是八八的归并,一直下去。 * 适合用链表组织的数据*/public class MergeBU{private static Comparable[] aux;public static void sort(Comparable[] a){ /*进行lg次两两归并*/int N=a.length;aux=new Comparable[N]; for(int sz=1;sz<N;sz=2*sz) /*sz子数组大小,初始值为1每次加倍*/ for(int lo=0;lo<N-sz;lo=lo+2*sz) /*lo子数组索引*/ merge(a,lo,lo+sz-1,Math.min(lo+2*sz-1,N-1));}private static void merge(Comparable[] a,int lo,int mid,int hi){int i=lo;int j=mid+1;for(int k=lo;k<=hi;k++)aux[k]=a[k];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[i],aux[j]))a[k]=aux[i++];else a[k]=aux[j++];}private static boolean less(Comparable v,Comparable w){return v.compareTo(w)<0;}private static void exch(Comparable[] a,int i,int j){Comparable t=a[i];a[i]=a[j];a[j]=t;}public static void show(Comparable[] a){for(int i=0;i<a.length;i++)System.out.println(a[i]);System.out.println();}private static boolean isSorted(Comparable[] a){for(int i=1;i<a.length;i++)if(less(a[i],a[i-1]))return false;return true;}public static void main(String[] args){Scanner sc=new Scanner(System.in);int N;N=sc.nextInt();String[] a=new String[N];sc.nextLine(); /*读走换行*/System.out.println("请输入"+N+"个字符串:");for(int i=0;i<N;i++)a[i]=sc.nextLine();sort(a);show(a);}}
阅读全文
1 0
- 归并排序(algs4)
- 快速排序(algs4)
- Algs4-2.2.17链表归并排序
- 初级排序算法(algs4)
- Algs4-2.2.2 归并算法为EASYQUESTION排序的轨迹
- 回环变位(algs4)
- 算法分析(algs4)
- 优先队列(algs4)
- Algs4-2.2.11 改进的Merge排序
- 算法1.4背包(algs4)
- 合并排序(归并)
- 归并排序(ASC)
- 归并排序(C)
- 归并排序(MergeSort)
- 归并排序(上)
- 归并排序(下)
- 归并排序(java)
- POJ2299(归并排序)
- 2017年8月21日训练日记
- 利用python在linux下分布式任务管理
- 8.21
- xlistView下拉刷新,上拉加载更多
- 无序容器
- 归并排序(algs4)
- 2017.8.21-------树状数组
- DOM
- 堆
- Retrofit+fastjson
- Unity触发检测和碰撞检测
- 字符串匹配——KMP算法
- jekyll _config timezone
- solr 6.3 入门(三)