学习分治思想的快速排序


 

前言

学无止境。


一、快速排序

1、比如数组 A = [66,45,72,18,9,82,45]      ---------中心思想:保证主元左边的元素都比主元小,右边的元素都比主元大 

①取主元:首个元素66,temp = A[0]      

②取两下标:start和end,start指向第一个元素,end指向最后一个元素    -----因为start指向的值已经赋值给temp,那么start的指向位置已经空出

③先从end开始,与主元进行比较:45 < 66,需要将45放到主元66的左边:A[start] = A[end]  start往后移动一位,指向A[1]   -----因为end指向的值已经赋值给start指向的位置,那么end的指向位置已经空出  [45,45,72,18,9,82,  ]

④比较start指向的A[1]与主元66的大小:45 < 66 ,该元素无需移动,将start往后移动一位,指向A[2]    ------end的指向位置依旧空出  [45,45,72,18,9,82,  ]

⑤比较start指向的A[2]与主元66的大小:66 < 72 ,需要将72放到主元66的右边:A[end]=A[start],将end往前移动一位,指向A[5]    -----因为start指向的值已经赋值给end指向的位置,那么start的指向位置已经空出[45,45,   ,18,9,82,72]

⑥比较end指向的A[5]与主元66的大小:66 < 82 ,该元素无需移动,将end往前移动一位,指向A[4]    ------start的指向位置依旧空出     [45,45,   ,18,9,82,72]

⑦比较end指向的A[4]与主元66的大小:9 < 66,需要将9放到主元66的左边:A[start] = A[end]  start往后移动一位,指向A[3]   -----因为end指向的值已经赋值给start指向的位置,那么end的指向位置已经空出  [45,45,9,18,   ,82,72]

⑧比较start指向的A[3]与主元66的大小:18 < 66 ,该元素无需移动,将start往后移动一位,指向A[4]    ------end的指向位置依旧空出  [45,45,9,18,   ,82,72]

⑨start和end都指向同一个位置,第一次排序结束,将主元放在该位置  A[start] = 66     [45,45,9,18,66,82,72]

⑩两个子数组诞生: [45,45,9,18]    [82,72]      分别重复上述步骤,完成排序

代码如下:

"""
    使用分治思想对数组进行快速排序
    分治思想:(1)分解:将原问题分解为若干个规模更小且和原问题结构相似的子问题
             (2)控制:从小问题层面解决问题:1.小问题如何解决 2.做下层递归的条件
             (3)合并:如何将子问题的解归并等到原问题的解
    快速排序:(1)分解:取一主元A[p],将数组A[p,..r]划分为两个数组A[p,..q-1](全部小于等于A[p])、A[q+1,..r](全部大于等于A[p])
             (2)控制:通过递归调用,对两个子数组进行排序
             (3)合并:递归之后的子数组的已经有序
"""
class QuickSort:
    def quickSort(self, sort_list, start, end):

        if start < end :
            #划分为两个数组,q就是第一轮快排结束后的主元元素下标
            q = self.deparate(sort_list, start, end)
            #对两个分解的数组进行排序
            self.quickSort(sort_list, start, q - 1)
            self.quickSort(sort_list, q + 1, end)
        return  sort_list

    def deparate(self, sort_list, start, end):
        #设置主元为首个元素:sort_list[start]
        temp = sort_list[start]
        
        #当start与end相等时,放置主元,成功将数组分为两个子数组
        while start < end :
            #先比较最右边元素与主元的大小,如果右边元素大,右边指针往左移;当右边元素小时跳出循环
            while start < end and sort_list[end] >= temp:
                # end往左移动一位
                end -= 1
            #右边元素小,将右边元素赋值给左边start指向的元素
            sort_list[start] = sort_list[end]

            #比较最左边元素与主元的大小,如果左边元素小,左边指针右移;当左边元素大时跳出循环
            while start < end and sort_list[start] <= temp:
                # start往右移动一位
                start += 1
            # 如果左边元素大,将左边元素赋值给右边end指向的元素
            sort_list[end] = sort_list[start]

        sort_list[start] = temp

        return start

if __name__ == '__main__':
    num = [25, 56, 5, 6, 6,78]
    sort = QuickSort()
    print(sort.quickSort(num,0,4))

总结

花费了一天总算是把这个排序搞懂了。一开始总是云里雾里的,觉得自己已经看懂了别人的写法,只有自己动手编写调试的时候才发现,并没有那么简单。清楚思路和写出代码真的是两回事,继续加油

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值