快速排序的主要思想就是分而治之,递归将序列用主元分为两个子序列然后排序.
根据维基百科的描述,快速排序有两种:
第一种是由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
参考链接:https://blog.csdn.net/v_JULY_v/article/details/6116297