兩種快速排序解析
快速排序的主要思想就是分而治之,遞迴將序列用主元分為兩個子序列然後排序.
根據維基百科的描述,快速排序有兩種:
第一種是由Lomuto提出的, 為in-place交換;將序列最後一個元素選為主元。兩個掃描標籤從左邊開始,當array[ j ]大於主元時,j繼續掃描;當array[ j ]小於主元時,交換array[ i+1 ]和array[ j ].
首先,主元為最後一個元素 4,array[j] = 2,小於主元,所以交換array[i+1]和array[ j ]的值。因為i和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[hi]
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
參考連結:https://blog.csdn.net/v_JULY_v/article/details/6116297