zoukankan      html  css  js  c++  java
  • 自顶向下(递归)的归并排序和自底向上(循环)的归并排序——java实现

    归并排序有两种实现方式,自顶向下和自底向上。前者的思想是分治法,现将数组逐级二分再二分,分到最小的两个元素后,逐级往上归并,故其核心在于归并。后者的思想相反,采用循环的方式将小问题不断的壮大,最后变成整个大问题。

    归并需要有一个同等大小的辅助数组aux,现将需要归并的元素copy至辅助数组aux中,然后通过逐一比较aux中的元素,将其放至原数组中的合适位置。

    归并排序的时间复杂度为nlogn,需要额外的空间n,排序元素稳定,即使在最坏的情况下归并排序的时间复杂度也是nlogn。

     1 package 排序;
     2 
     3 import java.util.Arrays;
     4 
     5 import edu.princeton.cs.algs4.In;
     6 import edu.princeton.cs.algs4.StdOut;
     7 /**
     8  * @author evasean www.cnblogs.com/evasean/
     9  */
    10 @SuppressWarnings("rawtypes")
    11 public class Merge归并排序 {
    12     private static Comparable[] aux;
    13     private static int num=1;
    14     public static void merge(Comparable[] a, int lo, int mid, int hi){
    15         StdOut.println("merge lo="+lo+",mid="+mid+",hi="+hi);
    16         int i = lo;  //左半边元素索引记录
    17         int j = mid+1; //右半边元素索引记录
    18         for(int k = lo; k <= hi; k++) 
    19             aux[k] = a[k];
    20         for(int k = lo; k <= hi; k++){
    21             if(i > mid) a[k] =  aux[j++];//左半边用尽,取右半边元素
    22             else if(j > hi) a[k] = aux[i++];//右半边用尽,取左半边元素
    23             else if(less(aux[j],aux[i])) a[k] = aux[j++];//右半边当前元素小于左半边当前元素,取右半边元素
    24             else a[k] = aux[i++];//右半边当前元素大于或等于左半边当前元素,取左半边元素
    25         }
    26         StdOut.println("第"+num+"次归并结果:"+Arrays.toString(a));
    27         num++;
    28     }
    29     /**
    30      * 自顶向下的归并排序
    31      * @param a
    32      */
    33     public static void sort(Comparable[] a){
    34         aux = new Comparable[a.length];
    35         sort(a,0,a.length-1);
    36     }
    37     public static void sort(Comparable[] a, int lo, int hi){
    38         if(hi <= lo) return;
    39         int mid = lo + (hi-lo)/2;
    40         sort(a,lo,mid);
    41         sort(a,mid+1,hi);
    42         merge(a,lo,mid,hi);
    43     }
    44     /**
    45      * 自底向上的归并排序
    46      * @param a
    47      */
    48     public static void sortBU(Comparable[] a){
    49         
    50         int N = a.length;
    51         aux = new Comparable[N];
    52         for(int sz = 1; sz < N; sz=2*sz){
    53             for(int lo = 0; lo < N - sz; lo += 2*sz){
    54                 merge(a,lo,lo+sz-1,Math.min(lo+2*sz-1, N-1));
    55             }
    56         }
    57     }
    58 
    59     @SuppressWarnings("unchecked")
    60     private static boolean less(Comparable v, Comparable w) {
    61         return v.compareTo(w) < 0;
    62     }
    63 
    64     private static void show(Comparable[] a) {
    65         for (int i = 0; i < a.length; i++)
    66             StdOut.print(a[i] + " ");
    67         StdOut.println();
    68     }
    69 
    70     public static boolean isSorted(Comparable[] a) {
    71         for (int i = 1; i < a.length; i++) {
    72             if (less(a[i], a[i - 1]))
    73                 return false;
    74         }
    75         return true;
    76     }
    77 
    78     public static void main(String[] args) {
    79         String[] a = new In().readAllStrings();
    80         StdOut.println(Arrays.toString(a));
    81         sort(a);
    82         assert isSorted(a);
    83         show(a);
    84     }
    85 }
  • 相关阅读:
    Activiti 整合的小插曲
    IDEA 提示找不到 javax 等 tomcat 的相关包
    一些好用的 Oracle 批处理和语句
    Oracle 日志报错导致的 “没有登录” 问题
    WebPack 从安装到闲置
    CHENEY-YANG'S BLOG(cheney-yang)
    Java基础知识常识总结
    激活Navicat
    IDEA文件头版权模板
    关于Spring框架中StringUtils常用/易误用方法解析
  • 原文地址:https://www.cnblogs.com/evasean/p/7233072.html
Copyright © 2011-2022 走看看