import random
import time
data = list(range(1000))
random.shuffle(data)
def calc_time(func):
def swrapper(*args, **kwargs):
ti1 = time.time()
x = func(*args, **kwargs)
ti2 = time.time()
print(func.__name__,"time cost",":",ti2-ti1)
return x
return swrapper
@calc_time
def bubble_sort(li):
for i in range(len(li) - 1):
for j in range(len(li) - i - 1):
if li[j] > li[j+1]:
li[j], li[j+1] = li[j+1], li[j]
@calc_time
def bubble_op_sort(li):
for i in range(len(li) - 1):
exchange = False
for j in range(len(li) - i - 1):
if li[j] > li[j+1]:
li[j], li[j+1] = li[j+1], li[j]
exchange = True
if not exchange:
break
@calc_time
def select_sort(li):
for i in range(len(li)-1):
min_loc = i
for j in range(i+1, len(li)):
if li[j] < li[min_loc]:
min_loc = j
li[i], li[min_loc] = li[min_loc], li[i]
@calc_time
def insert_sort2(li):
#待商榷
for i in range(1,len(li)):
#exchange = False
for j in range(i):
if li[i-j] < li[i-1-j]:
li[i-j], li[i-1-j] = li[i-1-j], li[i-j]
else:
break
@calc_time
def insert_sort(li):
for i in range(1, len(li)):
tmp = li[i]
j = i - 1
while j >= 0 and li[j] > tmp:
li[j+1] = li[j]
j = j-1
li[j+1] = tmp
@calc_time
def quick_sort(data, left, right):
return _quick_sort(data, left, right)
#如何解决递归装饰器的方法
def _quick_sort(data, left, right):
if left < right:
mid = partition(data, left, right)
_quick_sort(data, left, mid-1)
_quick_sort(data, mid+1, right)
def partition(data, left, right):
tmp = data[left]
while left < right:
while left < right and data[right] >= tmp:
right -= 1
data[left] = data[right]
while left < right and data[left] <= tmp:
left += 1
data[right] = data[left]
data[left] = tmp
return left
@calc_time
def sys_sort(data):
return data.sort()
测试结果:
#bubble_sort time cost : 0.13609981536865234
#bubble_op_sort time cost : 0.12430572509765625
#select_sort time cost : 0.09456682205200195
#insert_sort time cost : 0.15010905265808105
#insert_sort2 time cost : 0.051015615463256836
#quick_sort time cost : 0.002998828887939453
#sys_sort time cost : 0.0
注意内建函数sort最快~~~所以能用内建用内建不要自己写啊。。。
时间复杂度
O(n*n)
- 插入排序、选择排序和冒泡排序
O(nlogn)
- 快速排序、堆排序和归并排序
影响排序效果的因素
- 待排序的数据规模
- 关键字的结构及其初始状态
- 稳定性的要求
- 语言工具的条件
- 存储结构
- 时间和辅助空间复杂度
应用场景:
- 若n较小(数据规模较小),插入排序或选择排序较好
- 若数据初始状态基本有序(正序),插入、冒泡或快速排序为宜
- 若n较大,则采用时间复杂度为O(nlogn)的排序方法:快速排序或堆排序
- 快速排序是目前基于比较的排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短;
- 堆排序所需的辅助空间少于快速排序,并且不会出现快速排序可能出现的最坏情况。这两种排序都是不稳定的。
快速排序最坏情况:时间复杂度是O(n*n)
快速排序的时间性能取决于快速排序的递归深度,可以用递归树来描述递归算法的执行情况
- 在关键字已经基本有序的情况下(正序或者逆序),每次划分都只得到一个比上一次划分少一个记录的子序列,此时需要执行n-1次递归调用,且第i次划分需要经过n-i次关键字的比较才能找到第i个记录,比较次数达到(n(n-1))/2,最终其时间复杂度为O(n*n)