八大排序演算法JAVA實現(時間複雜度O(n*logn)篇)

來源:互聯網
上載者:User

標籤:color   log   變形   等於   長度   bsp   填充   元素   strong   

本文講述時間複雜度為n*logn的排序演算法:歸併排序、快速排序、堆排序以及希爾排序的原理、Java實現以及變形應用。

一、歸併排序
  •  原理:把兩個有序數列合并為一個有序數列。需遞迴實現。
  •  Java實現:
 1     public int[] mergeSort(int[] a, int n) 2     { 3         return doMergeSort(a, n, 0, n - 1); 4     } 5         public int[] doMergeSort(int[] a, int n, int start, int end) 6     { 7         int[] res = new int[n]; 8         if (n <= 1) 9         {10             res[0] = a[start];11             return res;12         }13         // n>=2時,對其左右數組進行處理14         int half = n / 2;15         int leftEnd = start + half - 1;16         int rightStart = leftEnd + 1;17         //遞迴調用本函數,擷取有序的左數組以及右數組18         int[] left = doMergeSort(a, half, start, leftEnd);19         int[] right = doMergeSort(a, n - half, rightStart, end);20         // 將左右序列合并21         int k = 0, i = 0, j = 0;22         while (i < half && j < n - half)23         {//由前往後比較兩個序列,取較小值填充到res中,取值後該序列往後移動取下一個值比較24             if (left[i] <= right[j])25             {26                 res[k++] = left[i++];27             }28             else29             {30                 res[k++] = right[j++];31             }32         }33         // 剩餘的直接放入34         while (i < half)35         {36             res[k++] = left[i++];37         }38         while (j < n - half)39         {40             res[k++] = right[j++];41         }42         return res;43     }            
二、快速排序
  •  原理:每一次將一個數放在一個左邊的數全部比它小,且右邊的數全部比它大的位置,然後遞迴調用函數,將其左右序列排好。這邊有一個比較好理解的做法:在數組的左邊維護一個小於區間,在遍曆的時候,發現比當前數小的數位時候,將,擴增小於區間,並其放到小於區間內,結束後將當前數填充在小於區間後即可。
  • Java實現:
 1     public int[] quickSort(int[] a, int n) 2     { 3         doQuickSort(a, n, 0, n - 1); 4         return a; 5     } 6     public void doQuickSort(int[] a, int n, int start, int end) 7     { 8         if (n > 1) 9         {10             int current = a[end];11             int minLen = 0;// 小於區間的長度12             int i = start;13             for (; i < end; i++)14             {15                 if (a[i] < current)16                 {//發現比當前數小的數,擴充小於區間17                     int temp = a[start + minLen];18                     a[start + minLen] = a[i];19                     a[i] = temp;20                     minLen++;21                 }22             }23             a[end] = a[start + minLen];24             a[start + minLen] = current;25             //當前位置已經確定,排左右序列26             doQuickSort(a, minLen, start, start + minLen - 1);27             doQuickSort(a, n - minLen - 1, start + minLen + 1, end);28         }29     }        
  •  變形應用:三色排序練習題

有一個只由0,1,2三種元素構成的整數數組,請使用交換、原地排序而不是使用計數進行排序。給定一個只含0,1,2的整數數組A及它的大小,請返回排序後的數組。保證數組大小小於等於500。測試範例:
[0,1,1,0,2,2],6
返回:[0,0,1,1,2,2]

解析:運用快排的原理。用數字1來處理,在數組左右各維護一個小於區間和大於區間。

 

三、堆排序
  • 原理:維護一個大根堆(小根堆同理),即維護一棵二叉樹,該數子節點永遠比父節點小。每次在大根堆中取出根,根為此時待排序列最大值,放在待排序列最後,然後調整大根堆,重複上訴過程即可。
  • Java實現:博主不太會插圖,關於大小根堆的調整細節可自行百度。原理總結來說是從最後一個非葉子節點開始,往前調整。設當前調整的非葉子節點為n,選舉n,n的左,n的右三個節點的最大值作為父節點。且每次調整了靠前的非葉子節點的值後,可能會破壞下面的數的大根堆規則,需要再次調整。嗯我覺得我並沒有講清楚,百度看看圖就好。
    public int[] heapSort(int[] a, int n)    {        for (int len = n; len > 0; len--)        {// len為構建的堆的大小            for (int i = len / 2 - 1; i >= 0; i--)            {// 從後往前遍曆非葉子節點                while (2 * i + 1 < len)                {                    int j = 2 * i + 1;// 左節點序號                    if (j + 1 < len && a[j] < a[j + 1])                    {                        j++;                    }                    if (a[i] < a[j])                    {                        int temp = a[j];                        a[j] = a[i];                        a[i] = temp;                        i = j;                    }                    else                    {                        break;                    }                }            }            int temp = a[len - 1];            a[len - 1] = a[0];            a[0] = temp;        }        return a;    }
  • 變形應用:常規應用如在1000+個數中找出最大的10個數之類的。

已知一個幾乎有序的數組,幾乎有序是指,如果把數組排好順序的話,每個元素移動的距離可以不超過k,並且k相對於數組來說比較小。請選擇一個合適的排序演算法針對這個資料進行排序。 給定一個int數組A,同時給定A的大小n和題意中的k,請返回排序後的數組。

測試範例: [2,1,4,3,6,5,8,7,10,9],10,2

返回:[1,2,3,4,5,6,7,8,9,10]

解析:維護一個大小為k的小根堆,每次調整完這個小根堆後,最小值就會出現在第一位,此時移除第一位,添加後一位元進來,繼續調整這個小根堆即可。可以想象為一個從前往後移動的滑動視窗,滑動視窗中是一個小根堆。

四、希爾排序
  • 原理:變形後的插入排序,每個數只與它前面固定步長的倍數的位置進行比對。如:步長step,當前數與它前面step,step*2,step*3....位置進行比較,插入到合適的位置。
  • Java實現:
    public int[] shellSort(int[] a, int n)    {        // 步長選擇        for (int k = 1, step = 10; step > 1; k++)        {            step = n / (2 * k);            for (int i = step; i < n; i++)            {                if (a[i] < a[i - step])                {                    int temp = a[i];                    a[i] = a[i - step];                    a[i - step] = temp;                    int pre = i - step;                    while (pre - step > 0)                    {                        if (a[pre] < a[pre - step])                        {                            temp = a[pre];                            a[pre] = a[pre - step];                            a[pre - step] = temp;                            pre -= step;                        }                        else                        {                            break;                        }                    }                }            }        }        return a;    }

 

八大排序演算法JAVA實現(時間複雜度O(n*logn)篇)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.