首页 > 编程语言 > 详细

快速排序法进阶

时间:2020-09-14 20:12:36      阅读:84      评论:0      收藏:0      [点我收藏+]

改进版本1

??舍去一边的快速排序,该边的快速排序用自身的排序代替。

def quick2(li,left,right):
    while left<right:
        mid=partition2(li,left,right)#索引的中间值
        quick2(li,left,mid-1)#单边递归法
        left=mid+1
    return li

def partition2(li,left,right):
    pivot=li[left]#定位左边的元素
    while left<right:#还没有搜索完
        # 从右边开始,将大于中间索引所在元素的元素放在左边
        while left<right and pivot<li[right]:
            right-=1
        li[left]=li[right]#在左边加
        # 从左边开始,将小于中间索引所在元素的元素放在右边
        while left<right and pivot>li[left]:
            left+=1
        li[right]=li[left]#在右边加
    li[left]=pivot#将右边的的最左端赋值为中间值
    return left#返回中间值的索引

改进版本2

??将有监督的快速排序优化为无监督的快速排序。

def quick3(li,left,right):
    while left<right:
        mid,right1 =partition3(li,left,right)#索引的中间值
        quick3(li,left,right1)
        left=mid
    return li

def partition3(li,left,right):
    pivot=li[left]#定位左边的元素
    while left<=right:
        while pivot<li[right]:
            right-=1
        while pivot>li[left]:
            left+=1
        if(left<=right):
            li[left],li[right]=li[right],li[left]#在右边加
            left += 1
            right -= 1
    return (left,right)#返回中间值的索引

改进版本3

??在分割点选取的初始值方面进行优化,在待分割下标区间随机选取分割点下标。

def quick4(li,left,right):
    while left<right:
        mid,right1 =partition4(li,left,right)#索引的中间值
        quick4(li,left,right1)
        left=mid
    return li

def partition4(li,left,right):
    pivot=li[int(left+np.random.rand()%(right-left+1))]#随机取原始分割点
    while left<=right:
        while pivot<li[right]:
            right-=1
        while pivot>li[left]:
            left+=1
        if(left<=right):
            li[left],li[right]=li[right],li[left]#在右边加
            left += 1
            right -= 1
    return (left,right)#返回中间值的索引

改进版本4

??继续在分割点选取的初始值方面进行优化,在待分割区间使用三点取中法选取初始分割点。

def quick5(li,left,right):
    while left<right:
        mid,right1 =partition5(li,left,right)#索引的中间值
        quick5(li,left,right1)
        left=mid
    return li

def partition5(li,left,right):
    pivot=mid_num(li,left,right)#三点取中法确定原始分割点
    while left<=right:
        while pivot<li[right]:
            right-=1
        while pivot>li[left]:
            left+=1
        if(left<=right):
            li[left],li[right]=li[right],li[left]
            left += 1
            right -= 1
    return (left,right)#返回中间值的索引
def mid_num(li,left,right):
    a=li[left]
    b=li[right]
    c=li[int((left+right)/2)]
    if(a>b):
        a,b = b,a
    if(a>c):
        a,c = c,a
    if (b > c):
        b,c = c,b
    return b

快速排序法进阶

原文:https://www.cnblogs.com/wisteria68/p/13667235.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!