,,Python八大常见排序算法定义、实现及时间消耗效率分析

,,Python八大常见排序算法定义、实现及时间消耗效率分析

本文主要介绍了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的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: