天天看點

快速排序算法_快速排序(QSort,快排)算法及C語言實作

上節介紹了如何使用起泡排序的思想對無序表中的記錄按照一定的規則進行排序,本節再介紹一種排序算法——快速排序算法(Quick Sort)。

C語言中自帶函數庫中就有快速排序——qsort函數 ,包含在 頭檔案中。

快速排序算法是在起泡排序的基礎上進行改進的一種算法,其實作的基本思想是:通過一次排序将整個無序表分成互相獨立的兩部分,其中一部分中的資料都比另一部分中包含的資料的值小,然後繼續沿用此方法分别對兩部分進行同樣的操作,直到每一個小部分不可再分,所得到的整個序列就成為了有序序列。例如,對無序表

{49,38,65,97,76,13,27,49}

進行快速排序,大緻過程為:

  1. 首先從表中選取一個記錄的關鍵字作為分割點(稱為“樞軸”或者支點,一般選擇第一個關鍵字),例如選取 49;
  2. 将表格中大于 49 個放置于 49 的右側,小于 49 的放置于 49 的左側,假設完成後的無序表為:

    {27,38,13,49,65,97,76,49}

  3. 以 49 為支點,将整個無序表分割成了兩個部分,分别為

    {27,38,13}

    {65,97,76,49}

    ,繼續采用此種方法分别對兩個子表進行排序;
  4. 前部分子表以 27 為支點,排序後的子表為

    {13,27,38}

    ,此部分已經有序;後部分子表以 65 為支點,排序後的子表為

    {49,65,97,76}

  5. 此時前半部分子表中的資料已完成排序;後部分子表繼續以 65為支點,将其分割為

    {49}

    {97,76}

    ,前者不需排序,後者排序後的結果為

    {76,97}

  6. 通過以上幾步的排序,最後由子表

    {13,27,38}

    {49}

    {49}

    {65}

    {76,97}

    構成有序表:

    {13,27,38,49,49,65,76,97}

整個過程中最重要的是實作第 2 步的分割操作,具體實作過程為:

  • 設定兩個指針 low 和 high,分别指向無序表的表頭和表尾,如下圖所示:
    快速排序算法_快速排序(QSort,快排)算法及C語言實作
  • 先由 high 指針從右往左依次周遊,直到找到一個比 49 小的關鍵字,是以 high 指針走到 27 的地方停止。找到之後将該關鍵字同 low 指向的關鍵字進行互換:
    快速排序算法_快速排序(QSort,快排)算法及C語言實作
  • 然後指針 low 從左往右依次周遊,直到找到一個比 49 大的關鍵字為止,是以 low 指針走到 65 的地方停止。同樣找到後同 high 指向的關鍵字進行互換:
    快速排序算法_快速排序(QSort,快排)算法及C語言實作
  • 指針 high 繼續左移,到 13 所在的位置停止(13<49),然後同 low 指向的關鍵字進行互換:
    快速排序算法_快速排序(QSort,快排)算法及C語言實作
  • 指針 low 繼續右移,到 97 所在的位置停止(97>49),然後同 high 指向的關鍵字互換位置:
    快速排序算法_快速排序(QSort,快排)算法及C語言實作
  • 指針 high 繼續左移,此時兩指針相遇,整個過程結束;

該操作過程的具體實作代碼為:

該方法其實還有可以改進的地方:在上邊實作分割的過程中,每次交換都将支點記錄的值進行移動,而實際上隻需在整個過程結束後(low==high),兩指針指向的位置就是支點記錄的準确位置,是以無需每次都移動支點的位置,最後移動至正确的位置即可。

是以上邊的算法還可以改寫為:

快速排序的完整實作代碼(C語言)

運作結果:

13 27 38 49 49 65 76 97

總結

快速排序算法的時間複雜度為

O(nlogn)

,是所有時間複雜度相同的排序方法中性能最好的排序算法。

快速排序算法_快速排序(QSort,快排)算法及C語言實作

繼續閱讀