排序 之 快速排序

2022-05-30 20:30:14 字數 2677 閱讀 7162

快速排序是氣泡排序的公升級,屬於交換排序

快速排序(quick sort)的基本思想是:通過一趟排序將待排記錄分割成獨立的兩部分,其中一部分記錄的關鍵字均比另一部分記錄的關鍵字ixoa,則可分別對這兩部分記錄繼續進行排序,以達到整個排序有序的目的。

快速排序********************************

*//*

交換順序表l中子表的記錄,使樞軸記錄到位,並返回其所在位置

*//*

此時在它之前(後)的記錄均不大(小)於它。

*/int partition(sqlist *l,int low,int

high)

return low; /*

返回樞軸所在位置 */}

/*對順序表l中的子串行l->r[low..high]作快速排序

*/void qsort(sqlist *l,int low,int

high)}/*

對順序表l作快速排序

*/void quicksort(sqlist *l)

partition函式要做的,就是先選取當中的乙個關鍵字,然後想盡辦法將它放到乙個位置,使得它左邊的值都比它小,右邊的值比它大,我們將這樣的關鍵字稱為樞軸(pivot)。

partition函式其實就是將選取的pivotkey不斷交換,將比它小的換到它的左邊,比它大的換到它的右邊,它也在交換中不斷更改自己的位置,知道完全滿足這個要求為止。

複雜度

快速排序的時間複雜度為o(nlogn).

空間複雜度為o(logn),(遞迴造成的棧空間的使用。)

由於關鍵字的比較和交換是跳躍進行的,因此,快速排序是一種不穩定的排序方法。

1.優化選取樞軸

三數取中(median-of-three)法,即取三個關鍵字先進行排序,將中間數做為樞軸,一般是取左端、右端和中間三個數,也可以隨機選取。

2.優化不必要的交換

在partition函式中,其中的有些交換是不需要的,可以採用替換的方式進行操作。

改進後的partition函式**

/*

快速排序優化演算法

*/int partition1(sqlist *l,int low,int

high)

l->r[low]=l->r[0

];

return low; /*

返回樞軸所在位置

*/}

3.優化小陣列時的排序方案

對於元素個數較小的排序要求,快速排序反而不如直接插入排序來的更好,(直接插入是簡單排序中效能最好的).其原因在於快速排序用到了遞迴操作,在大量資料排序時,這點效能影響可以忽略,當陣列只有幾個記錄需要排序時,就成了乙個大炮打蚊子的大問題。可以增加乙個判斷,當元素個數不大於某個常數時,(有資料認為7比較合適,也有認為50更合理),就用直接插入排序。

4.優化遞迴操作

尾遞迴:在電腦科學裡,尾呼叫是指乙個函式裡的最後乙個動作是乙個函式呼叫的情形:即這個呼叫的返回值直接被當前函式返回的情形。這種情形下稱該呼叫位置為尾位置。若這個函式在尾位置呼叫本身(或是乙個尾呼叫本身的其他函式等等),則稱這種情況為尾遞迴

尾遞迴優化:與普通遞迴相比,由於尾遞迴的呼叫處於方法的最後,因此方法之前所積累下的各種狀態對於遞迴呼叫結果已經沒有任何意義,因此完全可以把本次方法中留在堆疊中的資料完全清除,把空間讓給最後的遞迴呼叫。這樣的優化1便使得遞迴不會在呼叫堆疊上產生堆積,意味著即時是「無限」遞迴也不會讓堆疊溢位。這便是尾遞迴的優勢。

一般來說對於尾遞迴形式的呼叫,大部分編譯器會自動做出優化,當然也可以主動以迴圈的方式來優化尾遞迴。

void qsort1(sqlist *l,int low,int

high)

}else

insertsort(l);

}排序演算法總結

排序分類

排序方法

平均情況

最好情況

最壞情況

輔助空間

穩定性插入排序

直接插入排序

o(n2)

o(n)

o(n2)

o(1)

穩定希爾排序

o(nlogn)~o(n2)

o(n1.3)

o(n2)

o(1)

不穩定選擇排序

簡單選擇排序

o(n2)

o(n2)

o(n2)

o(1)

不穩定堆排序

o(nlogn)

o(nlogn)

o(nlogn)

o(1)

不穩定交換排序

氣泡排序

o(n2)

o(n)

o(n2)

o(1)

穩定快速排序

o(nlogn)

o(nlogn)

o(n2)

o(logn)~o(n)

不穩定歸併排序

歸併排序

o(nlogn)

o(nlogn)

o(nlogn)

o(n)

穩定

排序之快速排序

快速排序的在內排中起到比較重要的作用,平均時間複雜度達到o nlogn 公升序快速排序 1 int partition vector vi,int start,int end 11 vi start key 12return start 13 14void quickcore vector vi,i...

排序之快速排序

有沒有既不浪費空間又可以快一點的排序演算法呢?那就是 快速排序 啦!光聽這個名字是不是就覺得很高階呢。假設我們現在對 6 1 2 7 9 3 4 5 10 8 這個10個數進行排序。首先在這個序列中隨便找乙個數作為基準數 不要被這個名詞嚇到了,就是乙個用來參照的數,待會你就知道它用來做啥的了 為了方...

排序之快速排序

該方法的基本思想是 1 先從數列中取出乙個數作為基準數。2 分割槽過程,將比這個數大的數全放到它的右邊,小於或等於它的數全放到它的左邊。3 再對左右區間重複第二步,直到各區間只有乙個數 o nlogn 出處 includeusing namespace std void quicksort int ...