#快速排序复杂度计算
# 16
# 8 8
# 4 4 4 4
# 2 2 2 2 2 2 2 2
# 1 ....
# 每一次都减半 每一层都是n的复杂度,一共有log16 =.4层
# 所以是 O(nlogn
快速排序
from cal_time import *
from bubble_sort import *
import random
import copy
def partition(li,left,right):
tmp = li[left]
while left < right:
while left < right and li[right] >= tmp:#从右边开始找比tmp小的数
right -= 1 #左移1位
li[left] = li[right] #把右边的值写到左边空位上
#print(li)
#print('—'*100)
while left < right and li[left] <= tmp:
left += 1
li[right] = li[left]#把左边的值写到右边空位上
#print(li)
li[left] =tmp #把tmp归位
return left
#测试partition函数
# li = [5,7,4,6,3,1,2,9,8]
# print(li)
# partition(li,0,len(li)-1)
# print(li)
def _quick_sort(li,left,right):
if left <right:
mid = partition(li,left,right)#mid值出来了说明列表分为两个部分,之后再对这两个部分分类
_quick_sort(li,left,mid-1)
_quick_sort(li,mid+1,right)
# li = [5,7,4,6,3,1,2,9,8]
# _quick_sort(li,0,len(li)-1)
# print(li)
@cal_time
def quick_sort(li):
_quick_sort(li,0,len(li)-1)
# #比较快速排序跟冒泡排序算法效率
# li = list(range(10000))
# random.shuffle(li)
#
# li1 = copy.deepcopy(li)
# li2 = copy.deepcopy(li)
#
# quick_sort(li1)# 0.025s
# better_bubble_sort(li2) #12.227s
#
# print(li1)
# print(li2)
#最坏的情况:恰好是倒序——解决问题随机一个数,跟第一个数交换
li = list(range(10000,0,-1))
quick_sort(li)
#堆排序 O(nlogn)
![](https://i-blog.csdnimg.cn/blog_migrate/32aff47a1880af7e66107927e058c89f.png)
![](https://i-blog.csdnimg.cn/blog_migrate/e2a5a5d82c54ce18c5d73cdf7860700d.png)
![](https://i-blog.csdnimg.cn/blog_migrate/5e80fba766fb5671353af095def502c5.png)
![](https://i-blog.csdnimg.cn/blog_migrate/aa2cb1a597c3ae47ae58e55ab555e054.png)
![](https://i-blog.csdnimg.cn/blog_migrate/f7562a8562e1c6a7a36c95c8be9e96f6.png)
![](https://i-blog.csdnimg.cn/blog_migrate/7ce01a8714a56486fec5d355de6b87fa.png)
def sift(li,low,high):
"""
:param li:列表
:param low:堆的根节点位置
:param high:堆的最后一个元素位置
:return:
"""
i = low #i最开始指向根节点
j = 2*i+1 #j开始是做孩子
tmp = li[low] #把堆顶存起来
while j <= high:#只要j位置有数
if j +1 <= high and li[j+1] > li[j]: #如果右孩子有且比较大
j = j + 1 #j指向右孩子
if li[j] > tmp:
li[i] = li[j]
i = j #往下看一层
j = 2 * i + 1
else: #tmp更大,把tmp放到i的位置
break
li[i] = tmp #跳出循环两个条件,1.i到了最后一层,导致j没有数了 2.tmp的值比两个子节点的值大,tmp传入li[i]中
def heap_sort(li):
n = len(li)
for i in range((n-2)//2,-1,-1):
#i表示建堆的时候调整的部分的根的下标
sift(li,i,n-1)# high假设为每个堆的最后一位
# 建堆完成了
print(li)
for i in range(n-1,-1,-1):
#i指向当前堆的最后一个元素
li[0],li[i] = li[i],li[0]
sift(li,0,i-1) #i-1是新的high
li = [i for i in range(100)]
import random
random.shuffle(li)
heap_sort(li)
print(li)