今日复习了一下快速排序的算法。
hoare法
快速排序由Hoare在1960年提出。它的基本思想是:通过排序将需要排序的数据分割成独立的两部分,左边的所有数据都比右边的小,然后再按此方法对这两部分数据分别进行快速排序递归,使其变成有序序列。
在实践过程中,等号的位置问题、递归返回以及指针的移动问题都值得思考。
我们以序列[1, 10, 99, 23, 43, 11, 2]
为例。
- 就第一趟循环而言,选择最左侧的元素
1
为key
,与序列中元素进行比较。 - 因为以最左侧为
key
,所以右侧指针right
首先移动。在这个例子中,此举是为了防止1
右边的元素都比它大的情况。这样right
就会移动到0
的位置,即不需要交换位置。 - 每一次左右指针的移动都要判断
left < right
,以免交叉产生错误。
每一趟排序如下:
[1, 10, 99, 23, 43, 11, 2] 左指针: 0 右指针: 0
[1, 10, 2, 23, 43, 11, 99] 左指针: 2 右指针: 6
[1, 10, 2, 23, 43, 11, 99] 左指针: 2 右指针: 2
[1, 2, 10, 23, 11, 43, 99] 左指针: 4 右指针: 5
[1, 2, 10, 23, 11, 43, 99] 左指针: 4 右指针: 4
[1, 2, 10, 11, 23, 43, 99] 左指针: 5 右指针: 5
[1, 2, 10, 11, 23, 43, 99]
整体代码如下:
def quickSort(input,left,right):
if left>= right:
return
min_index=left
max_index=right
key_value = input[left]
while left < right:
while input[right] >= key_value and left < right:
right -= 1
while input[left] <= key_value and left < right:
left += 1
input[left], input[right] = input[right], input[left]
input[min_index],input[left]=input[left], input[min_index]
quickSort(input,min_index,left-1)
quickSort(input,left+1,max_index)
挖坑法
挖坑法在hoare的基础上进行了改进。主要是把左右指针的位置作为坑,将需要更改顺序的元素填入坑中。左侧的坑left
填入原本在右边但是<key_value
的元素input[right]
。同理,右边的坑填原本在左边但是>key_value
的元素。
整体代码如下:
def quickSort2(input, left, right):
if left >= right:
return
min_index = left
max_index = right
key_value = input[left]
while left < right:
while input[right] >= key_value and left < right:
right -= 1
input[left] = input[right]
while input[left] <= key_value and left < right:
left += 1
input[right] = input[left]
input[left] = key_value
quickSort2(input, min_index, left - 1)
quickSort2(input, left + 1, max_index)
每一趟排序如下:
[1, 10, 99, 23, 43, 11, 2] 左指针: 0 右指针: 0
[1, 10, 99, 23, 43, 11, 2] 指针: 0
[1, 2, 99, 23, 43, 11, 99] 左指针: 2 右指针: 6
[1, 2, 99, 23, 43, 11, 99] 左指针: 2 右指针: 2
[1, 2, 10, 23, 43, 11, 99] 指针: 2
[1, 2, 10, 11, 43, 43, 99] 左指针: 4 右指针: 5
[1, 2, 10, 11, 43, 43, 99] 左指针: 4 右指针: 4
[1, 2, 10, 11, 23, 43, 99] 指针: 4
[1, 2, 10, 11, 23, 43, 99] 左指针: 5 右指针: 5
[1, 2, 10, 11, 23, 43, 99] 指针: 5
[1, 2, 10, 11, 23, 43, 99]
可以对比一下hoare的具体排序步骤。
前后指针法
在搜索挖坑和hoare方法的时候看到了一篇写的很好的快排博客,引用
http://t.csdn.cn/tzWUS
详细介绍了前后指针法:
代码如下:
def quickSort3(input, left, right):
if left>=right:
return
pre = left
cur = left+1
key_value = input[left]
while cur <= right: # 改变了结束循环的条件
if input[cur] <= key_value:
pre += 1
input[pre], input[cur] = input[cur], input[pre]
cur+=1
input[pre],input[left] = key_value,input[pre]
quickSort3(input, left, pre - 1)
quickSort3(input, pre + 1, right)