传统的快速排序法实现如下:
def quickSort(L,left,right):
if left>=right:
return
base=L[left]
r=right
l=left
while left<right:
while left<right and L[right]>=base:
right-=1
L[left]=L[right]
while left<right and L[left]<=base:
left+=1
L[right]=L[left]
L[left]=base
quickSort(L,l,left-1)
quickSort(L,left+1,r)
改进的三数中值法思想及实现:
5 3 4 9 1 0 8(原始排列)
现在选取两端及中间共三个数,即:5 9 8。并将其按照从小到大排序:5 8 9,在依次放回两端和中间可得:
5 3 4 8 1 0 9
将8作为枢纽值,并存放在倒数第二个位置(8与0进行交换):
5 3 4 0 1 8 9
『假设该排列第一个数的下标为0,且向右依次增长1,直至该排列结束。设置i,j哨兵,实现双向扫描。i从左向右扫描,找比枢纽值大的数,j从枢纽值左边第一个位置开始向右扫描,找比枢纽值小的数,若i,j都找到了则实现交换。往复循环上述操作,直至i,j相遇,则第一轮排序结束』
i从下标为0,即值为5的位置开始向右扫描找比8大的数,直到与j(下标为5,值为8的位置)相遇也没找到,则第一轮排序结束。此时8左边的数都比8小,8右边的数都比8大。
然后递归实现对子序列的相同处理:
5 3 4 0 1(原始子序列)
1 3 0 4 5 (取三数,排序,将枢纽值放倒数第二的位置)
…………………………(省略以后的步骤)
『嗯……这例子取的不好,没有用到双向扫描再交换』
具体代码实现如下:
def swap(L,left,right):
L[left],L[right]=L[right],L[left]
def initBase(L,left,right):
mid=(left+right)//2
#将三数排序
if L[left]>L[mid]:
swap(L,left,mid)
if L[left]>L[right]:
swap(L,left,right)
if L[mid]>L[right]:
swap(L,mid,right)
#将枢纽值放在末尾
swap(L,mid,right-1)
def quickSortM3(L,left,right):
if left>=right:
return
initBase(L,left,right)
l=left
r=right-1
base=L[right-1]
while l<r:
while l<r and L[l]<=base:
l+=1
while l<r and L[r]>=base:
r-=1
if l<r:
swap(L,l,r)
if l==r and L[l]>base:
swap(L,l,right-1)
quickSortM3(L,left,l-1)
quickSortM3(L,l+1,right)
我这里将 过程也输出了出来