兩種快速排序解析 python

2021-09-30 17:11:43 字數 2724 閱讀 1481

快速排序的主要思想就是分而治之,遞迴將序列用主元分為兩個子串行然後排序. 

根據維基百科的描述,快速排序有兩種:

第一種是由lomuto提出的,  為in-place交換;將序列最後乙個元素選為主元。兩個掃瞄標籤從左邊開始,當array[ j ]大於主元時,j繼續掃瞄;當array[ j ]小於主元時,交換array[ i+1 ]和array[ j ].

首先,主元為最後乙個元素 4,array[j] = 2,小於主元,所以交換array[i+1]和array[ j ]的值。因為 i+1 和 j 都指向同乙個index所以沒有改變 。j繼續向前移動

array[ j ] = 8 > 4, 所以不用交換,i的位置也不會移動。j繼續向前移動。

array[ j ] = 7 > 4, 所以不用交換,i的位置依舊不會移動,j繼續向前移動。

array[ j ] = 1 < 4, 所以交換array[i+1]和array[ j ]的值,j繼續向前移動。

array[ j ] = 3 < 4, 所以交換array[i+1]和array[ j ]的值,j繼續向前移動。

array[ j ] = 5 > 4, 所以不用交換,i的位置也不會移動。j繼續向前移動

array[ j ] = 6 > 4, 所以不用交換,i的位置也不會移動。j繼續向前移動

此時j = r,交換array[i+1]和array[ r ]的值就完成了一輪排序。

上面為一輪排序,後面遞迴對兩個子串行進行排序 。因為在主元前面的值都比主元小,在主元後面的值都比主元大。

該演算法保證了i+1到 j-1 之間的序列值永遠比 array[r]的值大,所以當 array[ j ]小於array[r]時,可以將array[i+1]和array[j]進行交換,最後在交換array[i+1] 的值和array[r]的值,這樣就能保證i+1之前的值比array[i+1]的值小,i+1之後的值都比array[i+1]的值大。下面為python**:

## 將序列從小到大排序

def quick_sort(array, lo, r):

"""array: 待排序的序列

lo: array裡面最小的index

r: array裡面最大的index

"""if lo < hi:

q = partition(array, lo, r)

quick_sort(array, lo, q-1)

quick_sort(array, q+1, r)

def partition(array, lo, r):

x = array[r]

i = lo - 1

for j in range(lo, r):

if array[j] <= x:

i += 1

array[i], array[j] = array[j], array[i]

array[i+1], array[r] = array[r], array[i+1]

return i+1

如果想要從大到小的排序,將array[ j ] <= x 改為array[ j ] >= x 即可。 

第二種是由hoare提出的。將序列的第乙個元素作為主元。從左右兩個方向開始對array排序,j從右邊開始找小於主元的值,找到後將array[ j ]的值賦給array[ i ];  i從左邊開始找大於主元的值,找到後將array[ i ]的值賦給array[ j ].

首先, 主元為第乙個元素6, j從右向左找到array[ j ] =  5 < 6,將它的值賦給array[ i ];

i從左向右掃瞄,找到array[ i ] = 8 > 6, 將它的值賦給array[ j ];

j繼續 從右向左找到array[ j ] =  4 < 6,將它的值賦給array[ i ];

i繼續從左向右掃瞄,找到array[ i ] = 7 > 6, 將它的值賦給array[ j ];

此時 i = j,停止掃瞄,將主元賦給array [i]

上面就完成了一次排序,後面再遞迴對兩個子串行排序即可。下面為python**:

def quick_sort(array, lo, hi):

if lo < hi:

p = partition(array, lo, hi)

# 這裡為p而不是p-1,因為當左邊的序列只有乙個主元的時候會出現lo > hi的情況

quick_sort(array, lo, p)

quick_sort(array, p+1, hi)

def partition(array, lo, hi):

x = array[lo]

i = lo

j = hi

while i < j:

while i < j and array[j] >= x:

j -= 1

if i < j:

array[i] = array[j]

while i < j and array[i] < x:

i += 1

if i < j:

array[j] = array[i]

array[i] = x

return i

兩種快速排序

快排是一種基於交換的排序,氣泡排序 兩兩相鄰作比較,逆序則交換 也是基於交換的排序,快排運用了二分法的思想,每次找乙個哨兵,比哨兵小的放一邊,大的放一邊,這是完成了一趟快排。冒泡 for int i 0 ia j 1 快排一 void quicksort int left,int right if ...

快速排序的兩種實現

快速排序演算法是現在用的最廣的排序演算法,也是效率最高的。它有兩種實現方式,一種是定軸法,另外一種是挖坑法。這裡簡單介紹一下兩種實現方法的思想,並附上c 實現 一 定軸法 1.備份對軸 首記錄 2.取兩個指標left和right,初始值分別是序列的第二個元素和最後乙個元素,並且left right ...

快速排序的兩種思路

選取最左端 low 為基準值,以公升序為例 從右向左 high low 查詢到乙個小於基準值的元素,再從左向右查詢乙個大於基準值的元素,再將兩者相交換。while arr j temp low從右向左 high low 查詢到乙個小於基準值的元素,將兩者相交換,再從左向右查詢乙個大於基準值的元素,再...