zoukankan      html  css  js  c++  java
  • python3实现数据结构与算法30天-排序-快速排序(7)

    快速排序: 快
    时间复杂度:O(nlogn)
    相较冒泡排序:

    如果list长度1024,冒泡是O(n^2),粗略计算应是10214*1024,快排预计1024*(log1024)=1024*10,2个数量级优势。
    

    快速排序思路:
    1.取一个元素p,第一个元素,使元素p归位
    2.列表被p分成两部分,左边比p小,右边比p大
    3.递归完成排序

    partition函数:
    目标:通过这个函数,实现列表以中间数分左右两边,左边比中间数小,右边比中间大

    具体思路过程:
    1.选取左边0号元素作为初始值作为mid,以最左和最右两数为left,right两个指针,
    2.因为选取的是左边的0号元素作为mid,可以标记为l,首先从right自右向左移动指针,找到第一个比mid小的数,放入初始0号位置,也就是l位置,对应位置标记r
    3.接着从left自左向右移动指针,找到第一个比mid大的数,填入r位置,空缺标记l
    4.right指针向左,找到比mid小的填入l位置,标记r
    5.left指针向右,找到比mid大的值填入r,标记l
    6.重复4/5步骤,知道left/right指针相遇,确定中间位置mid
    7.左边递归[0, mid-1],右边递归[mid+1,len(lst)],重复1-6步骤

    递归问题及最坏情况:
    首先,Python有意地将递归限制在一个固定的深度。与Scheme不同,Scheme会一直为递归调用分配帧,直到内存耗尽,Python(至少最流行的实现CPython)在失败之前只分配^{}帧(默认为1000)。这是有原因的,但事实上,这在这里并不相关;只是事实上,它做到了这一点是需要知道的。

    第二,正如已经知道的,虽然快速排序是O(nlogn),但它的最坏情况是O(n^2),特别是(使用标准的pivot规则)已经排序的列表。当这种情况发生时,堆栈深度最终可能是O(n)。所以,如果有1000个元素,按最坏情况的顺序排列,并且已经进入堆栈一帧,就会溢出。

    通过sys模块,改变递归深度:

    import sys
    
    sys.setrecursionlimit(1500)
    

    代码实现:

    import random
    
    def partition(lst, left, right):
        temp = lst[left]
        while left < right:
            while left < right and lst[right] >= temp: # 自右向左找比temp小
                right -= 1 # 左移
            lst[left] = lst[right] # 右边值移到左边空位
            print("right: ", lst)
    
            while left < right and lst[left] <= temp:
                left += 1
            lst[right] = lst[left] # 左边值移到右边
            print("left:  ", lst)
    
        lst[left] = temp # 把temp归位
        print(lst)
    
        return left
    
    def quick_sort(lst, left, right):
        if left < right:
            mid = partition(lst, left, right)
            quick_sort(lst, left, mid-1)
            quick_sort(lst, mid+1, right)
        # print(lst)
    
    lst = [random.randint(1,50) for x in range(10)]
    print(lst)
    partition(lst, 0, 9)
    quick_sort(lst, 0, len(lst)-1)
    print(lst)
    

    运行结果:

    [11, 27, 27, 13, 25, 43, 9, 44, 20, 25]
    right:  [9, 27, 27, 13, 25, 43, 9, 44, 20, 25]
    left:   [9, 27, 27, 13, 25, 43, 27, 44, 20, 25]
    right:  [9, 27, 27, 13, 25, 43, 27, 44, 20, 25]
    left:   [9, 27, 27, 13, 25, 43, 27, 44, 20, 25]
    [9, 11, 27, 13, 25, 43, 27, 44, 20, 25]
    right:  [9, 11, 27, 13, 25, 43, 27, 44, 20, 25]
    left:   [9, 11, 27, 13, 25, 43, 27, 44, 20, 25]
    [9, 11, 27, 13, 25, 43, 27, 44, 20, 25]
    right:  [9, 11, 27, 13, 25, 43, 27, 44, 20, 25]
    left:   [9, 11, 27, 13, 25, 43, 27, 44, 20, 25]
    [9, 11, 27, 13, 25, 43, 27, 44, 20, 25]
    right:  [9, 11, 25, 13, 25, 43, 27, 44, 20, 25]
    left:   [9, 11, 25, 13, 25, 43, 27, 44, 20, 43]
    right:  [9, 11, 25, 13, 25, 20, 27, 44, 20, 43]
    left:   [9, 11, 25, 13, 25, 20, 27, 44, 44, 43]
    right:  [9, 11, 25, 13, 25, 20, 27, 44, 44, 43]
    left:   [9, 11, 25, 13, 25, 20, 27, 44, 44, 43]
    [9, 11, 25, 13, 25, 20, 27, 27, 44, 43]
    right:  [9, 11, 20, 13, 25, 20, 27, 27, 44, 43]
    left:   [9, 11, 20, 13, 25, 20, 27, 27, 44, 43]
    [9, 11, 20, 13, 25, 25, 27, 27, 44, 43]
    right:  [9, 11, 13, 13, 25, 25, 27, 27, 44, 43]
    left:   [9, 11, 13, 13, 25, 25, 27, 27, 44, 43]
    [9, 11, 13, 20, 25, 25, 27, 27, 44, 43]
    right:  [9, 11, 13, 20, 25, 25, 27, 27, 43, 43]
    left:   [9, 11, 13, 20, 25, 25, 27, 27, 43, 43]
    [9, 11, 13, 20, 25, 25, 27, 27, 43, 44]
    [9, 11, 13, 20, 25, 25, 27, 27, 43, 44]
    
  • 相关阅读:
    linux 时间设置
    linux
    linux 关闭防火墙
    GIS-008-ArcGIS JS API 全图
    GIS-007-Terrain跨域访问
    GIS-006-ArcGIS API 空间关系
    Python 中文乱码
    GIS-005-Dojo & jQuery 事件处理
    GIS-004-Cesium版权信息隐藏
    GIS-003-在线地图下载及应用
  • 原文地址:https://www.cnblogs.com/davis12/p/14540205.html
Copyright © 2011-2022 走看看