python实现排序算法后续
来源:互联网 发布:淘宝客博主的收入 编辑:程序博客网 时间:2024/05/01 21:25
上一篇因为时间的缘故,没有能写全这几个经典的排序算法,这里补上了三个,其中快排在上一篇中已经出现了,放在这里的原因是:出于对比的目的,归并排序、快速排序、堆排序三个排序算法的时间性能都很优秀,时间复杂度也都相同,所以放在这里,当然快排是我本人最喜欢用的一种排序算法,这里关于三个算法的原理都不再累赘了,这一段时间写的博客完全是出于复习的目的,所以也是尽可能的都读透彻,读明白了才可以。下面看代码:
#!usr/bin/env python #-*- coding: utf-8 -*- '''简介:三个时间复杂度一样的优秀排序算法:归并、快排、堆排序'''import timeimport random#随机序列生成器def randomnumber_generate(total_num=100, max_num=1000): num_list = [] n = 1 #得到1000以内的100个随机数 while n <= total_num: lin = random.randint(0, max_num) num_list.append(lin) n += 1 return num_list#堆调整def Heap_adjust(num_list, i, size):left_child = 2*i+1right_child = 2*i+2max_temp = i#print left_child, right_child, max_tempif left_child<size and num_list[left_child]>num_list[max_temp]:max_temp = left_childif right_child<size and num_list[right_child]>num_list[max_temp]:max_temp = right_childif max_temp != i:num_list[i], num_list[max_temp] = num_list[max_temp], num_list[i]Heap_adjust(num_list, max_temp, size) #避免调整之后以max为父节点的子树不是堆#创建堆def Create_heap(num_list, size):a = size/2-1for i in range(a, -1, -1):#print '**********', iHeap_adjust(num_list, i, size)#堆排序def Heap_sort(num_list, size):# b=size-1Create_heap(num_list, size)i = size-1while i > 0:num_list[0], num_list[i] = num_list[i], num_list[0]size -= 1i -= 1Heap_adjust(num_list, 0, size)return num_list#归并排序def MergeSort(num_list): #分割终止条件 if len(num_list)<2: return num_list result_list = [] #将原始序列分为左右两部分 ,递归对两个子列表进行排序,典型的分而治之的思想 #print num_list[len(num_list)/2] left_list = MergeSort(num_list[:len(num_list)/2]) right_list = MergeSort(num_list[len(num_list)/2:]) #分别开始比较两个子列表,将较小的元素添加进新的列表 while len(left_list)>0 and len(right_list)>0: if left_list[0]<right_list[0]: result_list.append(left_list.pop(0)) else: result_list.append(right_list.pop(0)) #倘若两个列表比较结束,即一个列表已经都被加入结果列表 #则将另一个列表其余元素均加入结果列表 if len(left_list)>0: result_list.extend(MergeSort(left_list)) else: result_list.extend(MergeSort(right_list)) return result_list #快排def quickSort(num_list): if len(num_list)<2: return num_list left_list = [] #存放比基准结点小的元素 right_list = [] #存放比基准元素大的元素 base_node = num_list.pop(0) #在这里采用pop()方法的原因就是需要移除这个基准结点,并且赋值给base_node这个变量 #在这里不能使用del()方法,因为删除之后无法再赋值给其他变量使用,导致最终数据缺失 #快排每轮可以确定一个元素的位置,之后递归地对两边的元素进行排序 for one_num in num_list: if one_num < base_node: left_list.append(one_num) else: right_list.append(one_num) return quickSort(left_list) + [base_node] + quickSort(right_list) if __name__ == '__main__': num_list = [1,5,8,9,4,3,5,6,89,14,25,23, -2, -67, 100, 23, -5] start_time_create = time.time() #num_list = randomnumber_generate(total_num=100, max_num=1000) end_time_create = time.time() print '随机序列生成耗时:', end_time_create - start_time_create start_time1 = time.time() result_list1 = Heap_sort(num_list, len(num_list)) end_time1 = time.time() print "堆排序结果为" #print num_list print result_list1 print '堆排序总耗时:', end_time1 - start_time1 start_time3 = time.time() result_list3 = MergeSort(num_list) end_time3 = time.time() print "归并排序结果为" #print num_list print result_list3 print '归并排序总耗时:', end_time3 - start_time3 start_time2 = time.time() result_list2 = quickSort(num_list) end_time2 = time.time() print "快速排序结果为" #print num_list print result_list2 print '快速排序总耗时:', end_time2 - start_time2使用小数据作为测试,本次运行得到的结果如下:
随机序列生成耗时: 0.0
堆排序结果为
[-67, -5, -2, 1, 3, 4, 5, 5, 6, 8, 9, 14, 23, 23, 25, 89, 100]
堆排序总耗时: 5.88893890381e-05
归并排序结果为
[-67, -5, -2, 1, 3, 4, 5, 5, 6, 8, 9, 14, 23, 23, 25, 89, 100]
归并排序总耗时: 0.000135183334351
快速排序结果为
[-67, -5, -2, 1, 3, 4, 5, 5, 6, 8, 9, 14, 23, 23, 25, 89, 100]
快速排序总耗时: 0.000169992446899
可以看到均正确的输出了,在之前的实验中发现一直出错没找到原因,错误在于:我把归并排序放在了快速排序的后面,导致归并排序的结果输出总是少一个数字:-67,后来才发现是因为在快速排序阶段因为使用了pop()方法,导致原始的数组被删除了基准元素,所以自然就会少一个数字了,换一下顺序就好了。
接下来使用随机序列生成器函数来自动的随机生成100个1000以内的数字来进行时间性能的测试,下面是结果:
随机序列生成耗时: 0.000493049621582
堆排序结果为
[5, 10, 13, 17, 50, 69, 72, 78, 79, 79, 88, 100, 108, 109, 110, 124, 125, 126, 135, 167, 167, 172, 196, 201, 210, 214, 221, 246, 269, 269, 271, 279, 283, 285, 289, 290, 298, 299, 308, 311, 314, 330, 369, 385, 406, 408, 418, 440, 445, 445, 459, 464, 473, 478, 493, 506, 508, 557, 562, 569, 577, 592, 596, 612, 617, 646, 654, 657, 676, 678, 685, 694, 716, 721, 738, 762, 794, 810, 814, 815, 818, 819, 825, 837, 838, 842, 852, 868, 872, 881, 882, 887, 890, 906, 908, 942, 948, 977, 981, 991]
堆排序总耗时: 0.000715017318726
归并排序结果为
[5, 10, 13, 17, 50, 69, 72, 78, 79, 79, 88, 100, 108, 109, 110, 124, 125, 126, 135, 167, 167, 172, 196, 201, 210, 214, 221, 246, 269, 269, 271, 279, 283, 285, 289, 290, 298, 299, 308, 311, 314, 330, 369, 385, 406, 408, 418, 440, 445, 445, 459, 464, 473, 478, 493, 506, 508, 557, 562, 569, 577, 592, 596, 612, 617, 646, 654, 657, 676, 678, 685, 694, 716, 721, 738, 762, 794, 810, 814, 815, 818, 819, 825, 837, 838, 842, 852, 868, 872, 881, 882, 887, 890, 906, 908, 942, 948, 977, 981, 991]
归并排序总耗时: 0.00460505485535
快速排序结果为
[5, 10, 13, 17, 50, 69, 72, 78, 79, 79, 88, 100, 108, 109, 110, 124, 125, 126, 135, 167, 167, 172, 196, 201, 210, 214, 221, 246, 269, 269, 271, 279, 283, 285, 289, 290, 298, 299, 308, 311, 314, 330, 369, 385, 406, 408, 418, 440, 445, 445, 459, 464, 473, 478, 493, 506, 508, 557, 562, 569, 577, 592, 596, 612, 617, 646, 654, 657, 676, 678, 685, 694, 716, 721, 738, 762, 794, 810, 814, 815, 818, 819, 825, 837, 838, 842, 852, 868, 872, 881, 882, 887, 890, 906, 908, 942, 948, 977, 981, 991]
快速排序总耗时: 0.00185680389404
三者对比之下,时间性能都很出色,相差的也是很小的,因为还有其他因素的干扰,感兴趣的还可以使用随机数列生成函数来进行翻倍处理,看看时间性能的变化是怎么样的。
- python实现排序算法后续
- 排序算法python实现
- 排序算法Python实现
- Python实现排序算法
- 排序算法python实现
- 直接排序算法python实现
- python 实现插入排序算法
- 基本排序算法:Python实现
- python实现各种排序算法
- python实现排序算法目录
- 排序算法总结-python实现
- python实现常见排序算法
- Python实现快速排序算法
- python实现快速排序算法
- Python:经典排序算法实现
- python实现经典排序算法
- python实现各种排序算法
- python实现各种排序算法
- Bandwidth UVA-140
- json字符串出现转义符,导致调用者使用ObjectMapper解析成Map报错
- Android 操作SQLite基本用法
- 谈谈linear regression 和 SVM
- 从C#到TypeScrip
- python实现排序算法后续
- Lambda 表达式 最快的记忆方法
- 使用Faster R-CNN训练自己的数据
- 网格聚类算法(一)
- nat 详解
- 第一份工作离职时候的前述,觉得当时的文采很不错奥
- No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK?
- Android:获得屏幕物理尺寸、密度及分辨率
- 计算机网络(七)--重要概念