快速排序及其优化(三数中值法)

传统的快速排序法实现如下:

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,在依次放回两端和中间可得:

   3     4          1      0        9

将8作为枢纽值,并存放在倒数第二个位置(8与0进行交换):

   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)

我这里将 过程也输出了出来

快速排序算法的性能取决于枢纽元的选取上,采用了三数中值法来对枢纽元进行选取,可以有效规避最坏的情形。该排序适用于对数据量较大的数据进行排序,而对于数据量较小的数据则表现一般。

  • 8
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值