排序演算法之快速排序

2021-06-19 02:31:07 字數 1635 閱讀 6782

快速排序是一種不穩定的排序演算法,它的基本思想是,以某個元素為基準,將所有大於等於它的值放在右邊,小於它的值放在左邊,這樣陣列就被分為兩部分,遞迴對這兩部分進行快速排序,而單個元素我們認為是已經排好序的。這是一種歸併思想,當然在最後一步,合併,我們什麼也沒有做也不用做。每一次排序都有乙個元素被放在正確的位置,所以該演算法總是會結束。因此,演算法的精髓在於如何選擇基準並分為兩個子陣列。選擇基準有很多種方式,有直接選擇首元素和末尾元素的,可是如果陣列本身已經有序,這樣的選擇不是那麼明智的,因為這樣行形成的子陣列乙個元素個數為0,另乙個為n-1,當然如果無序數列的隨機性比較好,這樣選擇也是無可厚非的。比較好的提議有選擇中間位置的元素作為基準,或者選擇使用隨機數隨機的位置的元素作為基準。下面的partion版本則是以無序區最右邊的數字作為基準,很囧,選擇了乙個不怎麼明智的基準。

int partion(int a, int n, int left, int right)

}myexchange(a, right, index); //基準元素位於正確的位置,即index

return index;

}

然後可以開始呼叫此函式,進行遞迴的快速排序。

void ex_sortquick(int a, int n, int left, int right)

if (left >= right)

int mid = partion(a, n, left, right);

ex_sortquick(a, n, left, mid - 1);

ex_sortquick(a, n, mid + 1, right);

return;

}

快速排序函式本身很簡單,所以可以嘗試改進partion函式的實現,上面的版本我們從陣列的一頭開始遍歷,以index為大於基準元素的界限。進一步想,partion最終結果是陣列分為了兩個子陣列,總之呢,第乙個元素肯定是小於基準,最後乙個元素肯定是大於等於基準,我們準備兩個指標,乙個指向序列頭,乙個指向序列尾部,同時遍歷,若指向頭的指標小於基準,它已經在正確的子陣列了,當它遇到大於基準的值時,停了下來,然後開始遍歷尾部的指標,相反地,當它的值大於基準時,它在正確的子陣列,否則就停下來。這樣,當兩個指標停下來的時候,前面的指標指向大於基準的值,後面的指標指向小於基準的值,於是交換兩個指標指向的元素,他們就位於正確的子陣列中了,然後遞增(遞減)前後指標,開始下一次比較。一直到兩個指標相遇,整個陣列就被分成了兩個部分。比如序列a = ;以9為基準,當i遍歷到23(i = 4),j遍歷到7的時候(j = 6),交換7和23,然後i遞增指向23,此時i = 6,指標相遇,迴圈退出,此時i左邊的數字都比9小,交換i位置的數和9,於是整個陣列就變為,返回i的值,9排到了正確的位置。

版本二:兩個指標遍歷的partion函式

int partion(int a, int n, int left, int right)

while (i < j && a[j] > pivot)

if (i != j)

}if (a[i] > pivot)

return i;

}

其實當排序範圍較小的時候,應選擇插入或者選擇排序,因此當子陣列小於一定數目的時候,可以適當選擇恰當的排序方式,該問題以後討論。

排序演算法之快速排序

快速排序使用分治法 divide and conquer 策略來把乙個序列 list 分為兩個子串行 sub lists 步驟為 從數列中挑出乙個元素,稱為 基準 pivot 重新排序數列,所有元素比基準值小的擺放在基準前面,所有元素比基準值大的擺在基準的後面 相同的數可以到任一邊 在這個分割槽退出...

排序演算法之快速排序

快速排序入口 public void quicksort int lists 遞迴呼叫該函式。原理 每次從陣列從選乙個標兵 本實現為簡單起見直接選取給定範圍內的第乙個元素為標兵 讓後在給定範圍內進行雙向遍歷,目的是以標兵為分界線,將所有小於標兵值的數字排一邊,將所有大於標兵的數字 放到另一邊。標兵移...

排序演算法之快速排序

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