<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    gr8vyguy@Blogjava

    Insertion-Sort和Merge-Sort

    Insertion-SortMerge-Sort是兩種非常有代表性的排序算法。Insertion-Sort逐個將未排序的元素插入到正確的位置,下面這張圖很形象的描述了Insertion-Sort.


    所以Insertion-Sort也是一種incremental的算法。Merge-Sort采用一種完全不同的方式,即是divide-and-conquer, 將元素分成兩組,先分別將這兩組排好序,然后再組合起來,就如下圖所示,


    Java實現

    Insertion-Sort

    /**
         * sort A in nondecreasing order
         * 
         * 
    @param A
         *            The array to sorted
         
    */

        
    public static void sort(int[] A) {
                sort(A, 
    0, A.length - 1);
            }


        
    public static void sort(int[] A, int p, int r) {
            
    for (int j = p + 1; j <= r; j++{
                     
    int key = A[j];
                     
    // Insert A[j] into the sorted sequence A[0 .. j-1]
                      int i = j - 1;
                 
    while (i >= p && A[i] > key) {
                            A[i 
    + 1= A[i];
                            i 
    = i - 1;
                      }

                     A[i 
    + 1= key;
                }

           }

    Merge-Sort

    /**
         * Sort A[p .. r] with Merge Sort
         
    */

      public static
     void mergeSort(int[] A, int p, int r) {
            
    if (p < r) 
    {
                     
    int q = (p + r) / 
    2;
                      mergeSort(A, p, q);
                      mergeSort(A, q 
    + 
    1, r);
                      merge(A, p, q, r);
                }

          }

    merge函數

    /**
         * merge sorted A[p .. q] and A[q+1 .. r] into A[p .. r]
         
    */

        
    private static void merge(int[] A, int p, int q, int r) 
    {
                 
    int[] L = new int[q - p + 1
    ];
                 
    int[] R = new int[r -
     q];
             
    for (int i = 0; i < L.length; i++
    {
                        L[i] 
    = A[p +
     i];
                 }

             
    for (int j = 0; j < R.length; j++{
                       R[j] 
    = A[q + 1 +
     j];
                 }

            
                 
    int i = 0;
                
    int j = 0
    ;
                
    int k =
     p;
            
    while (i < L.length && j < R.length) 
    {
                 
    if (L[i] < R[j]) 
    {
                          A[k
    ++= L[i++
    ];
                  }
     else {
                          A[k
    ++= R[j++
    ];
                     }

                }

             
    while (i < L.length) {
                     A[k
    ++= L[i++
    ];
                 }

            
    while (j < R.length) {
                    A[k
    ++= R[j++
    ];
                }

         }


    復雜度分析

    最差情況下Insertion-Sort的復雜度是O(n2), 而Merge-Sort是O(nlgn)。就是說Merge-Sort比Insertion-Sort好了一個n對lgn的程度,相差大嗎?當然是n越大,Merge-Sort相比于Insertion-Sort的優勢越明顯。有多明顯呢?做個實驗看看,將一百萬個整數排序。在我的電腦上,Merge-Sort用了731 ms,而Insertion-Sort跑了5分鐘還沒出來,就不等了,沒這個耐心。不過可以估算大概需要多長時間。Insertion-Sort排10000個整數所需的時間
    T(10000)=191 ms,假設T(n) = cn^2.


    約需32分鐘,如果你有興趣可以在你的電腦上試試看,所有的源代碼和測試程序可以在下面下載。

    Insertion-Sort和Merge-Sort的結合

    雖然Insertion-Sort是平方級的復雜度,而Merge-Sort是nlgn級的復雜度,但是當n比較小的時候,Insertion-Sort反而要快一些,因為復雜度分析是一種增長級速的分析,對大的輸入情況才有意義。既然n小的時候,Insertion-Sort比Merge-Sort要快,那么一個改善Merge-Sort的方法就呼之欲出了。當divide(回歸調用)到一定程度的時候,即元素個數小于某個值K的時候,用Insertion-Sort排序。這種算法可以稱作Insertion-Merge-Sort.

    Insertion-Merge-Sort的Java實現

        public static void sort(int[] A) {
                mergeSort(A, 
    0, A.length - 1);
           }


        
    private static void mergeSort(int[] A, int p, int r) {
            
    if (r - p + 1 <= K) {
                     InsertionSort.sort(A, p, r);
            }
     else {
                   
    int q = (p + r) / 2;
                    mergeSort(A, p, q);
                    mergeSort(A, q 
    + 1, r);
                    merge(A, p, q, r);
              }

           }


        
    private static void merge(int[] A, int p, int q, int r) {
                
    int n1 = q - p + 1;
               
    int n2 = r - q;
               
    int[] L = new int[n1 + 1];
               
    int[] R = new int[n2 + 1];
            
    for (int i = 0; i < n1; i++{
                   L[i] 
    = A[p + i];
               }

               L[n1] 
    = Integer.MAX_VALUE; // put the sentinel
            for (int j = 0; j < n2; j++{
                  R[j] 
    = A[q + 1 + j];
                }

               R[n2] 
    = Integer.MAX_VALUE;
              
    int i = 0;
              
    int j = 0;
           
    for (int k = p; k <= r; k++{
                
    if (L[i] < R[j]) {
                         A[k] 
    = L[i];
                         i 
    = i + 1;
                }
     else {
                        A[k] 
    = R[j];
                        j 
    = j + 1;
                    }

               }

        }

    Insertion-Merge-Sort比Merge-Sort快多少? 用Insertion-Merge-Sort對一百萬個整數排序需要大約541ms. 相比于Merge-Sort的731ms,快了將近26%.

    Insertion-Merge-Sort的復雜度分析

    假設當輸入個數為K時,采用Insertion-Sort, 那么有n/K個小組要用Insertion-Sort,所需時間為,
    n/K * K2=nK, 將n/K個小組組合起來,所需的時間是n*lg(n/K), 那么加起來就是Insertion-Merge-Sort的復雜度O(nK + nlg(n/K)).

    還有一個問題,某個值K應該取多大才算是最合適呢? 

    當K=1時,Insertion-Merge-Sort就成了Merge-Sort, 當K=n時,Insertion-Merge-Sort就成了Insertion-Sort。理論上,K的取值不應該使得Insertion-Merge-Sort的復雜度高于Merge-Sort的復雜度即O(nlgn), 如果按這個要求推理,那么K應該屬于O(lgn)。 在實踐中,K可以取所有Insertion-Sort還比Merge-Sort快的最大值。但是在不同的計算環境和不同的輸入下,這個值也會不一樣。我們只能根據實驗的情況取一個多數情況下比較好的K值。Java的Arrays.sort(.)函數取的是7,你可以看JDK的源代碼。好像Java的Arrays類以前用的是Quick-Sort算法, 不知道什么時候換成Insertion-Merge-Sort了。

    本文所有源代碼

    注腳
    以上所有的復雜度實際上即是上限,也是下限,習慣上應該用Theta表示,而O一般只表示一個上限,由于Theta不好打,只好這樣了,而且O的知名度要高很多,也被人濫用了很多。具體參照Knuth的論文Big Omicron and big Omega and big Theta


    轉載請保留http://m.tkk7.com/xilaile/archive/2007/04/29/114453.html


    posted on 2007-04-28 22:36 gr8vyguy 閱讀(3767) 評論(2)  編輯  收藏 所屬分類: 計算機科學基礎

    評論

    # re: Insertion-Sort和Merge-Sort 2007-05-06 07:45 InPractice

    JDK中既有快速排序,也有merge-insertation 排序。
    前者基本上用于 primitive 的排序。
    后者基本上用于對象數數組的排序。  回復  更多評論   

    # re: Insertion-Sort和Merge-Sort 2007-05-06 23:17 Pande

    @InPractice
    你說對,的確是如此,JDK的QuickSort也是用InsertionSort優化過的  回復  更多評論   

    <2007年5月>
    293012345
    6789101112
    13141516171819
    20212223242526
    272829303112
    3456789

    導航

    統計

    公告

  • 轉載請注明出處.
  • msn: gr8vyguy at live.com
  • 常用鏈接

    留言簿(9)

    隨筆分類(68)

    隨筆檔案(80)

    文章分類(1)

    My Open Source Projects

    搜索

    積分與排名

    最新評論

    主站蜘蛛池模板: 久久久久免费看黄A片APP| a级毛片在线免费| 免费可以在线看A∨网站| 无码专区—VA亚洲V天堂| 91国内免费在线视频| 亚洲精品无码99在线观看| 羞羞网站免费观看| 免费人成在线观看播放国产| 国产亚洲精品第一综合| 亚洲AV无码成人精品区大在线| 成人黄网站片免费视频| 亚洲国产精品无码专区在线观看| 成人无码视频97免费| 亚洲精品字幕在线观看| 免费无遮挡无码永久视频| 亚洲视频免费观看| 一二三四免费观看在线视频中文版| 亚洲人成在线中文字幕| 成人性生活免费视频| 美女黄频免费网站| 亚洲精品蜜桃久久久久久| 一个人免费日韩不卡视频| 久久精品国产亚洲AV忘忧草18| 午夜私人影院免费体验区| 国产成人精品亚洲| 亚洲国产精品无码专区| 国产1024精品视频专区免费| 亚洲av乱码一区二区三区按摩| 综合亚洲伊人午夜网 | 亚洲AV色欲色欲WWW| 亚洲男女内射在线播放| 69精品免费视频| 亚洲精品国产综合久久久久紧| 亚洲国产婷婷综合在线精品| 久久免费动漫品精老司机| 中文字幕在线日亚洲9| 亚洲欧洲日本在线| 中国xxxxx高清免费看视频| 色噜噜狠狠色综合免费视频| 精品日韩亚洲AV无码一区二区三区 | 国产性生交xxxxx免费|