自頂向下(遞歸)的歸並排序和自底向上(循環)的歸並排序——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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM