本文主要介绍了Python的八种常用排序算法的定义、实现和耗时效率分析,并结合具体实例比较分析了冒泡排序、直接插入排序、选择排序、归并排序、山丘排序、桶排序、堆排序等排序算法的使用和执行效率。有需要的可以参考以下。
本文结合实例描述了Python的八种常用排序算法的定义、实现和耗时效率分析。分享给你,供你参考,如下:
昨晚开始总结几种常见的排序算法。由于之前写过几篇关于排序算法的博文,现在总结一下比较方便。这里的目的是对这些排序算法进行更全面彻底的总结。为了复习基本的东西,我们可以从冒泡排序、直接插入排序、选择排序、归并排序、小山排序、桶排序、堆排序来进行排序。快速排序从分析和实现开始。最后也给出了简单的时间统计,重点是原理和算法基础,其次是其他。掌握了这些,对于接下来的工作或者准备接下来的面试都没有太大的帮助。算法重在理解内在含义和理论基础,只有实现了才能避免陷阱,少犯错误。这并不是说练习的时候出现错误就不好,而是说,一些不该出现的错误还是尽量少出现的好。毕竟好的编程习惯离不开严格的约束。好了,这里就不多说了。复习基础知识,一起学习。下面是具体实现。评论要详细,我就不解释了:
#!usr/bin/env python
#编码:utf-8
'''''
__作者_ _:沂水冷城
功能:八种排序算法
'''
导入时间
随机导入
time_dict={}
定义time_deco(sort_func):
'''''
时间计算的装饰函数,可以用来计算函数的执行时间。
'''
定义包装器(num_list):
start_time=time.time()
res=sort_func(num_list)
end_time=time.time()
time_dict[str(sort_func)]=(结束时间-开始时间)*1000
打印“拍摄:”(结束时间-开始时间)*1000
打印'结果是:',res
返回包装
def random_nums_generator(最大值=1000,总数=20):
'''''
随机数发生器
一些常见功能:
随机随机数生成
Random.random()用于生成0到1之间的随机数:0=n1.0
Random.uniform(a,b),用于生成指定范围内的随机符号数。两个参数一个是上限,一个是下限。min(a,b)=n=max(a,b);
Randdom.randint(a,b),用于生成指定范围内的整数,其中a为下限,b为上限:a=n=b;
Random.randrange (start,stop,step),从一个集合中获取一个在指定范围内按指定基数递增的随机数;
Random.choice(sequence),从序列中获取随机元素;
Random.shuffle(x ),用于对列表中的元素进行加扰;
Random.sample(sequence,k),从指定序列中随机获取指定长度的片段;
'''
num_list=[]
对于范围内的I(总数):
num _ list . append(random . randint(0,max_value))
返回编号列表
#@time_deco
def Bubble_sort(数字列表):
'''''
冒泡排序,时间复杂度o (n 2),空间复杂度O(1),是一种稳定排序。
'''
对于范围内的I(len(num _ list)):
对于范围内的j(I,len(num_list)):
If _ list [i] num _ list [j]: #这里是升序排序
数量列表[i],数量列表[j]=数量列表[j],数量列表[i]
返回编号列表
#@time_deco
def Insert_sort(编号_列表):
'''''
时间复杂度为O (n 2),空间复杂度为O(1)的直接插入排序是一种稳定排序。
'''
对于范围内的I(len(num _ list)):
对于范围(0,I)中的j:
If _ list [i] num _ list [j]: #这里是升序排序,和冒泡排序的区别在于冒泡是向后遍历,这个是向前遍历。
数量列表[i],数量列表[j]=数量列表[j],数量列表[i]
返回编号列表
#@time_deco
定义Select_sort(num_list):
'''''
选择,时间复杂度O(n ^ 2),空间复杂度O(1),不是稳定排序。
'''
对于范围内的I(len(num _ list)):
最小值索引=i
对于范围内的j(I,len(num_list)):
如果数量列表[j]数量列表[最小值索引]:
最小值索引=j #乍一看,感觉冒泡,选择,插入都很像,选择跟冒泡的区别在于:冒泡是发现大
#小数目顺序不对就交换,而选择排序是一轮遍历结束后选出最小值才交换,效率更高
数量列表[我],数量列表[最小值索引]=数量列表[最小值索引],数量列表[我]
返回编号列表
#@time_deco
定义Merge_sort(num_list):
'''''
归并排序,时间复杂度O(nlogn),空间复杂度:O(1),是稳定排序
'''
如果len(数量列表)==1:
返回编号列表
长度=len(数字列表)/2
列表1=数量列表[:长度]
list 2=num _ list[长度:]
result_list=[]
而len(列表1)和len(列表2):
如果列表1[0]=列表2[0]:
result_list.append(list1[0])
删除列表1[0] #这里需要删除列表中已经被加入到加过列表中的元素,否则最后比较完后列表
否则:#中剩余元素无法添加
result_list.append(list2[0])
删除列表1[0]
如果len(列表1): #遍历比较完毕后列表中剩余元素的添加
result_list=list1
否则:
result_list=list2
返回结果列表
#@time_deco
def Shell_sort(num_list):
'''''
希尔排序,时间复杂度:O(n),空间复杂度:O(n^2),不是稳定排序算法
'''
new_list=[]
对于编号列表中的一个编号:
new_list.append(one_num)
count=len(new_list)
步长=计数/2;
而步骤0:
i=0
当我计数:
j=i步
while jcount:
t=new_list.pop(j)
k=j步
当k=0时:
如果t=new_list[k]:
new _ list。插入(k ^ 1,t)
破裂
k=k步
如果k0:
new_list.insert(0,t)
#打印'-本轮结果为: - '
#打印新列表
j=j步
#打印英语字母表中第十个字母
i=i 1
#打印英语字母表中第九个字母
步骤=步骤/2 #希尔排序是一个更新步长的算法
返回新列表
#@time_deco
def Tong_sort(num_list):
'''''
桶排序,时间复杂度O(1),空间复杂度与最大数字有关,可以认为是O(n),典型的空间换时间的做法
'''
original_list=[]
total_num=max(num_list) #获取桶的个数
对于范围内的我(总数为1): #要注意这里需要的数组元素个数总数比总数数多一个因为下标从0开始
原始_列表.追加(0)
对于数字列表中的数字:
original_list[num]=1
result_list=[]
对于范围内的j(len(原始列表)):
如果原创_list[j]!=0:
对于范围(0,原始列表[j])中的h:
结果列表附加(j)
返回结果列表
定义快速排序(数量列表):
'''''
快速排序,时间复杂度:O(nlogn),空间复杂度:O(nlogn),不是稳定排序
'''
if len(num_list)2:
返回编号列表
left_list=[] #存放比基准结点小的元素
右列表=[] #存放比基准元素大的元素
base_node=num_list.pop(0) #在这里采用流行()方法的原因就是需要移除这个基准结点,并且赋值给基本节点这个变量
#在这里不能使用德尔()方法,因为删除之后无法再赋值给其他变量使用,导致最终数据缺失
#快排每轮可以确定一个元素的位置,之后递归地对两边的元素进行排序
对于编号列表中的一个编号:
如果有一个基本节点:
left_list.append(一个数字)
否则:
右_列表.追加(一个数字)
返回快速排序(左列表)[基本节点]快速排序(右列表)
def Heap_adjust(num_list,I,size):
left_child=2*i 1
right_child=2*i 2
max_temp=i
#打印左_子,右_子,最大_温度
if left_childsize和num _ list[left _ child]num _ list[max _ temp]:
max_temp=left_child
if right _ child size and num _ list[right _ child]num _ list[max _ temp]:
max_temp=right_child
if max_temp!=我:
数量列表[我],数量列表[最大温度]=数量列表[最大温度],数量列表[我]
堆_调整(数量列表,最大温度,大小)#避免调整之后以最大为父节点的子树不是堆
def创建_堆(数量列表,大小):
a=尺寸/2-1
对于范围(甲,-1,-1)内的我:
# print ' * * * * * * * * * * *,I
Heap_adjust(num_list,I,size)
#@time_deco
定义堆排序(数量列表):
'''''
堆排序,时间复杂度:O(nlogn),空间复杂度:O(1),不是稳定排序
'''
size=len(num_list)
创建堆(数量列表,大小)
我=尺寸-1
而我0:
数量列表[0],数量列表[我]=数量列表[我],数量列表[0]
尺寸-=1
i -=1
Heap_adjust(num_list,0,size)
返回编号列表
if __name__=='__main__ ':
数字列表=随机数字生成器(最大值=100,总数=50)
打印"冒泡排序",冒泡排序(编号列表)
打印"插入排序",插入排序(编号列表)
打印"选择排序",选择排序(数字列表)
打印"合并排序",合并排序(编号列表)
打印“Shell_sort”,Shell_sort(num_list)
打印"童_排序",童_排序(编号_列表)
打印"堆排序",堆排序(数量列表)
打印"快速排序",快速排序(编号列表)
#打印'-'
# for k,v in time_dict.items():
#打印k,v
结果如下:
泡泡排序[34,49,63,67,71,72,75,120,128,181,185,191,202,217,241,257,259,260,289,293,295,304,311,326,362,396,401,419,423,456,525,570,60
Insert_sort [34,49,63,67,71,72,75,120,128,181,185,191,202,217,241,257,259
Select_sort [34,49,63,67,71,72,75,120,128,181,185,191,202,217,241,257,259,260,289,293,295,304,311,326,362,396,401,419,423,456,525,570,670
Merge_sort [34,49,63,67,71,72,75,120,128,181,185,191,202,217,241,257,259,260,289,293,295,304,311,326,362,396,401,419,423,456,525,570,60
Shell_sort [34,49,63,67,71,72,75,120,128,181,185,191,202,217,241,257,259,260,289,293,295,304,311,326,362,396,401,419,423,456,525,570,670
Tong_sort [34,49,63,67,71,72,75,120,128,181,185,191,202,217,241,257,259,260,289,293,295,304,311,326,362,396,401,419,423,456,525,570,60
Heap_sort [34,49,63,67,71,72,75,120,128,181,185,191,202,217,241,257,259,
快速排序[34,49,63,67,71,72,75,120,128,181,185,191,202,217,241,257,259,260,289,293,295,304,311,326,362,396,401,419,423,456,525,570,60
这里没有使用到装饰器,主要自己对这个装饰器不太了解,在快速排序的时候报错了,也没有去解决,这里简单贴一下一个测试样例使用装饰器的结果吧:
冒泡排序耗时为: 0.0290870666504
结果为: [5, 45, 46, 63, 81, 83, 89, 89, 89, 90]
没有人
插入_排序耗时为: 0.0209808349609
结果为: [5, 45, 46, 63, 81, 83, 89, 89, 89, 90]
没有人
选择排序耗时为: 0.0259876251221
结果为: [5, 45, 46, 63, 81, 83, 89, 89, 89, 90]
没有人
合并排序耗时为: 0.0138282775879
结果为: [5, 45, 46, 63, 81, 83, 89, 89, 89, 90]
没有人
外壳_排序耗时为: 0.113964080811
结果为: [5, 45, 46, 63, 81, 83, 89, 89, 89, 90]
没有人
童_排序耗时为: 0.0460147857666
结果为: [5, 45, 46, 63, 81, 83, 89, 89, 89, 90]
没有人
堆排序耗时为: 0.046968460083
结果为: [5, 45, 46, 63, 81, 83, 89, 89, 89, 90]
没有人
快速排序[5,45,46,63,81,83,89,89,89,90]
-
函数Shell _ sort at0x7f 8 ab9d 0 . 54676 . 386868686686
函数Select_sort在0x7f 8 ab9d 0上的运行56600.86867868661
函数Insert_sort在0x7f 8 ab9d 0上的运行56607.88868686661
函数Heap_sort在0x7f 8 ab9d 0时的作用56607.88867868671
函数Merge_sort在0x7f 8 ab9d 0上的应用56607.88868686671
函数Tong_sort在0x7f 8 ab9d 0上的排序56607.88868888661
函数Bubble_sort在0x7f 8 ab9d 0上的排序56607.88868868661
接下来,如果有时间,我想学习一些关于装修工的知识。感觉装修工简直就是图案化东西的神器,但是我得会用会写啊!
PS:这里再为大家推荐一款关于排序的演示工具供大家参考:
插入/选择/冒泡/合并/希尔/快速排序过程的在线动画工具;
http://tools.jb51.net/aideddesign/paixu_ys
对更多Python相关内容感兴趣的读者可以查看我们的专题:《Python数据结构与算法教程》、《Python列表(list)操作技巧总结》、《Python编码操作技巧总结》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》和《Python入门与进阶经典教程》。
希望本文对Python编程有所帮助。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。