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]

posted on 2021-03-15 21:52  进击的davis  阅读(49)  评论(0编辑  收藏  举报

导航