python实现简单排序算法
算法
递归两个特点:
调用自身
有穷调用
计算规模越来越小,直至最后结束
用装饰器修饰一个递归函数时会出现问题,这个问题产生的原因是递归的函数也不停的使用装饰器。
解决方法是,只让装饰器调用一次即可,那么可以出创建一个新的普通函数,执行一下递归函数,并放回递归函数的返回值,给这个普通函数加上装饰器即可。
尾递归和正常循环时间复杂度相同,尾递归:每次递归尾部return递归函数
算法关键:
有序区和无序区,随着算法的推进,有序区越来越大,无序区越来越小,直至消失,完成排序
代码:
import random
import time
import sys
import copy
#装饰器
- def time_cost(func):
def wrapper(*args,**kwargs):
sTime = time.time()
func(*args,**kwargs)
print("Time cost:%s"%(time.time()-sTime))
print(args[0])
return wrapper
#冒泡排序:
#每一次循环从端点处比较n次选出最大或最小的数,一趟结束n--,每次里层循环n-i-1次。
- @time_cost
- def bubble_sort(list):
- print("\nbubble_sort:")
- for i in range(len(list)-1):
- tag = 0
- for j in range(len(list)-i-1):
- if list[j] > list[j+1]:
- list[j],list[j+1] = list[j+1],list[j]
- tag = 1
- if not tag:
- return
#选择排序
#每次选出最小的数,放在n,每趟结束n++,每次里层循环(i+1,len(list))
- @time_cost
- def select_sort(list):
- print("\nselect_sort:")
- for i in range(len(list)-1):
- min = i
- for j in range(i+1,len(list)):
- if list[min] > list[j]:
- min = j
- if min != i:
- list[i],list[min] = list[min],list[i]
#插入排序
#分有序区和无序区,列表前面是有序区,后面是无序区,每次从无序区的首位取一个元素,与有序区元素依次比较,放到合适的位置,直到无序区元素取完
- @time_cost
- def insert_sort(list):
- print("\ninsert_sort:")
- for i in range(len(list)):
- tag = 0
- for j in range(i,0,-1):
- if list[j] < list[j-1]:
- list[j],list[j-1] = list[j-1],list[j]
- tag = 1
- if not tag:
- break
#快速排序
#递归实现,取一个数(列表第一个),使得列表左边的元素比此数都小,列表右边的元素比此数都大,依据此数位置切割出左右两边列表分别进行递归,直至列表只有一个元素
- def part_sort(list,left,right):
- temp = list[left]
- while left < right:
- while left < right and temp <= list[right]:
- right -= 1
- list[left] = list[right]
- while left < right and temp >= list[left]:
- left += 1
- list[right] = list[left]
- list[left] = temp
- return left
- def _quckly_sort(list,left,right):
- if left < right:
- mid = part_sort(list,left,right)
- _quckly_sort(list,left,mid-1)
- _quckly_sort(list,mid+1,right)
- @time_cost
- def quckly_sort(list):
- print("\nquckly_sort:")
- return _quckly_sort(list,0,len(list)-1)
#快排的时间复杂度为O(nlogn)
#冒泡、选择、插入排序的时间复杂度为O(n^2)
#一般来说处理大数据排序问题,快排比前面三种排序快好几个数量级
#但是如果碰到极端情况,例如:列表是反序排列的
#快排的时间复杂度退化成O(n^2)
#由于自身有递归加大开销,会使相同排序比其他三种排序耗时更久
#系统自带排序 sort()
#大多数编程语言系统排序使用的都是快速排序
#python系统自带的排序使用的是C语言编写的快排,比python写的快排快一个数量级
sort(list)
#一般来说系统都有限制最大递归层数
#修改系统最大递归层数
import sys
sys.setrecursionlimit(10000)
#比较4种排序,当排序个数为10000时
#bubble_sort:
#Time cost:17.794017791748047
#select_sort:
#Time cost:5.8113322257995605
#insert_sort:
#Time cost:15.441883087158203
#_quckly_sort:
#Time cost:0.044002532958984375
#快排效率非常高
#堆排序
#当各节点是顺序存储时,且必须是完全二叉树
#父节点与左孩子关系: i ~ 2i+1
#父节点与右孩子关系: i ~ 2i+2
#首先将列表元素建堆,形成大根堆
#然后循环调整大根堆,取堆顶元素,生成有序序列
#时间复杂度O(nlogn)
- def sift(list,low,high):
- i = low
- j = 2 * i + 1
- temp = list[i]
- while j <= high:
- if j < high and list[j] < list[j+1]:
- j += 1
- if temp < list[j]:
- list[i] = list[j]
- i = j
- j = 2 * i + 1
- else:
- break
- list[i] = temp
- list[low],list[high] = list[low],list[high]
- @time_cost
- def heap_sort(list):
- print("\nheap_sort:")
- n = len(list)
- for i in range(n // 2 - 1, -1, -1):
- sift(list, i, n - 1)
- for i in range(n-1, -1, -1):
- list[0],list[i] = list[i],list[0]
- sift(list, 0, i - 1)
#归并排序
#一次归并,将两个排序好的列表合并成一个有序列表
#首先将一个无序列表递归分解成只有1个元素的n个列表
#将所有分解的列表两两执行一次归并算法,最终合成一个有序列表
#时间复杂度O(nlogn)
#空间复杂度O(n)每个一次归并都创建一个列表
- def ont_megre_sort(list,low,mid,high):
- i = low
- j = mid + 1
- ltmp = []
- while i <= mid and j <= high:
- if list[i] < list[j]:
- ltmp.append(list[i])
- i += 1
- else:
- ltmp.append(list[j])
- j += 1
- while i <= mid:
- ltmp.append(list[i])
- i += 1
- while j <= high:
- ltmp.append(list[j])
- j += 1
- list[low:high+1] = ltmp
- def _megre_sort(list,low,high):
- if low < high:
- mid = (low+high)//2
- _megre_sort(list,low,mid)
- _megre_sort(list,mid+1,high)
- ont_megre_sort(list,low,mid,high)
- @time_cost
- def megre_sort(list):
- print("\nmegre_sort:")
- return _megre_sort(list,0,len(list)-1)
#一般来说 快速排序 < 归并排序 < 堆排序
#快排极端情况下速度慢,不稳定
#归并排序需要空间开销
#堆排序相对稳定
#时间复杂度O(n)
#希尔排序
#一种分组插入排序算法
#根据定义d为间隔分组,对每个小分组做一次直接插入排序
#d逐渐缩小,列表相对有序,直至d=1,成为直接插入排序,最后一次循环使列表彻底有序
#时间复杂度O((1+T)n)=O(1.3n)
- @time_cost
- def shell_sort(list):
- print("\nshell_sort:")
- gap = len(list) // 2
- while gap > 0:
- for i in range(gap,len(list)):
- temp = list[i]
- j = i - gap
- while j >= 0 and temp < list[j]:
- list[j + gap] = list[j]
- j -= gap
- list[j + gap] = temp
- gap //= 2
#----------------------------------------------总结------------------------------------------------#
# 排序方法 时间复杂度 稳定性 代码复杂度 #
# #
# 最坏情况 平均情况 最好情况 #
# 冒泡排序 O(n^2) O(n^2) O(n) 稳定 简单 #
# #
# 直接选择排序 O(n^2) O(n^2) O(n^2) 不稳定 简单 #
# #
# 直接插入排序 O(n^2) O(n^2) O(n^2) 稳定 简单 #
# #
# 快速排序 O(n^2) O(nlogn) O(nlogn) 不稳定 较复杂 #
# #
# 堆排序 O(nlogn) O(nlogn) O(nlogn) 稳定 复杂 #
# #
# 归并排序 O(nlogn) O(nlogn) O(nlogn) 稳定 较复杂 #
# #
# 希尔排序 O(1.3n) 不稳定 较复杂 #
# #
# #
#-----------------------------------------------------------------------------------------------------------------------------#
全部代码
- __author__ = 'cq'
- import time
- import random
- import sys
- import copy
- def time_cost(func):
- def wrapper(*args,**kwargs):
- sTime = time.time()
- func(*args,**kwargs)
- print("Time cost:%s"%(time.time()-sTime))
- print(args[0])
- return wrapper
- #-------------------冒泡排序-----------------------#
- @time_cost
- def bubble_sort(list):
- print("\nbubble_sort:")
- for i in range(len(list)-1):
- tag = 0
- for j in range(len(list)-i-1):
- if list[j] > list[j+1]:
- list[j],list[j+1] = list[j+1],list[j]
- tag = 1
- if not tag:
- return
- #-------------------插入排序-----------------------#
- @time_cost
- def insert_sort(list):
- print("\ninsert_sort:")
- for i in range(len(list)):
- tag = 0
- for j in range(i,0,-1):
- if list[j] < list[j-1]:
- list[j],list[j-1] = list[j-1],list[j]
- tag = 1
- if not tag:
- break
- #-------------------选择排序-----------------------#
- @time_cost
- def select_sort(list):
- print("\nselect_sort:")
- for i in range(len(list)-1):
- min = i
- for j in range(i+1,len(list)):
- if list[min] > list[j]:
- min = j
- if min != i:
- list[i],list[min] = list[min],list[i]
- #-------------------快速排序-----------------------#
- def part_sort(list,left,right):
- temp = list[left]
- while left < right:
- while left < right and temp <= list[right]:
- right -= 1
- list[left] = list[right]
- while left < right and temp >= list[left]:
- left += 1
- list[right] = list[left]
- list[left] = temp
- return left
- def _quckly_sort(list,left,right):
- if left < right:
- mid = part_sort(list,left,right)
- _quckly_sort(list,left,mid-1)
- _quckly_sort(list,mid+1,right)
- @time_cost
- def quckly_sort(list):
- print("\nquckly_sort:")
- return _quckly_sort(list,0,len(list)-1)
- #-------------------堆排序-----------------------#
- def sift(list,low,high):
- i = low
- j = 2 * i + 1
- temp = list[i]
- while j <= high:
- if j < high and list[j] < list[j+1]:
- j += 1
- if temp < list[j]:
- list[i] = list[j]
- i = j
- j = 2 * i + 1
- else:
- break
- list[i] = temp
- list[low],list[high] = list[low],list[high]
- @time_cost
- def heap_sort(list):
- print("\nheap_sort:")
- n = len(list)
- for i in range(n // 2 - 1, -1, -1):
- sift(list, i, n - 1)
- for i in range(n-1, -1, -1):
- list[0],list[i] = list[i],list[0]
- sift(list, 0, i - 1)
- #-------------------归并排序-----------------------#
- def ont_megre_sort(list,low,mid,high):
- i = low
- j = mid + 1
- ltmp = []
- while i <= mid and j <= high:
- if list[i] < list[j]:
- ltmp.append(list[i])
- i += 1
- else:
- ltmp.append(list[j])
- j += 1
- while i <= mid:
- ltmp.append(list[i])
- i += 1
- while j <= high:
- ltmp.append(list[j])
- j += 1
- list[low:high+1] = ltmp
- def _megre_sort(list,low,high):
- if low < high:
- mid = (low+high)//2
- _megre_sort(list,low,mid)
- _megre_sort(list,mid+1,high)
- ont_megre_sort(list,low,mid,high)
- @time_cost
- def megre_sort(list):
- print("\nmegre_sort:")
- return _megre_sort(list,0,len(list)-1)
- #-------------------希尔排序-----------------------#
- @time_cost
- def shell_sort(list):
- print("\nshell_sort:")
- gap = len(list) // 2
- while gap > 0:
- for i in range(gap,len(list)):
- temp = list[i]
- j = i - gap
- while j >= 0 and temp < list[j]:
- list[j + gap] = list[j]
- j -= gap
- list[j + gap] = temp
- gap //= 2
- def main():
- #生成列表
- list0 = list(range(100))
- first_name = ["陈","张","李","王","赵"]
- second_name = ["冰","鑫","程","爱","暖"]
- third_name = ["强","国","明","风","芬"]
- listname = [
- {"id":""+str(i),
- "name":random.choice(first_name)+
- random.choice(second_name)+
- random.choice(third_name),
- "age":random.randint(16,60)
- } for i in range(10)
- ]
- random.shuffle(list0)
- random.shuffle(listname)
- #copy四份打乱后的列表
- list1 = copy.deepcopy(list0)
- list2 = copy.deepcopy(list0)
- list3 = copy.deepcopy(list0)
- list4 = copy.deepcopy(list0)
- list5 = copy.deepcopy(list0)
- list6 = copy.deepcopy(list0)
- list7 = copy.deepcopy(list0)
- #设置递归深度
- sys.setrecursionlimit(10000)
- print("sort_list:")
- print(list0)
- #排序算法
- bubble_sort(list1)
- select_sort(list2)
- insert_sort(list3)
- quckly_sort(list4)
- heap_sort(list5)
- megre_sort(list6)
- shell_sort(list7)
- print("\npractice to sort this list:")
- for i in listname:
- print(i)
- if "__main__" == __name__:
- main()
python实现简单排序算法的更多相关文章
- Python实现各种排序算法的代码示例总结
Python实现各种排序算法的代码示例总结 作者:Donald Knuth 字体:[增加 减小] 类型:转载 时间:2015-12-11我要评论 这篇文章主要介绍了Python实现各种排序算法的代码示 ...
- 简单排序算法 C++类实现
简单排序算法: 冒泡排序 插入排序 选择排序 .h代码: // // SortClass.h // sort and selection // // Created by wasdns on 16/1 ...
- 简单排序算法设计(Java)
总共有八种排序算法,还是慢慢看吧 1.简单排序算法 简单排序算法就是设置标兵,逐个比较数,然后查找插入位置,插入 public static void p(int[] a){ for(int i=0; ...
- Python实现常用排序算法
Python实现常用排序算法 冒泡排序 思路: 它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完 ...
- python 的常见排序算法实现
python 的常见排序算法实现 参考以下链接:https://www.cnblogs.com/shiluoliming/p/6740585.html 算法(Algorithm)是指解题方案的准确而完 ...
- 教你用Python实现简单监督学习算法
教你用Python实现简单监督学习算法 监督学习作为运用最广泛的机器学习方法,一直以来都是从数据挖掘信息的重要手段.即便是在无监督学习兴起的近日,监督学习也依旧是入门机器学习的钥匙. 这篇监督学习教程 ...
- 用 python 实现各种排序算法(转)
常见几种排序的算法: 归并排序 归并排序也称合并排序,是分治法的典型应用.分治思想是将每个问题分解成个个小问题,将每个小问题解决,然后合并. 具体的归并排序就是,将一组无序数按n/2递归分解成只有一个 ...
- Python实现八大排序算法(转载)+ 桶排序(原创)
插入排序 核心思想 代码实现 希尔排序 核心思想 代码实现 冒泡排序 核心思想 代码实现 快速排序 核心思想 代码实现 直接选择排序 核心思想 代码实现 堆排序 核心思想 代码实现 归并排序 核心思想 ...
- python实现桶排序算法
桶排序算法也是一种可以以线性期望时间运行的算法,该算法的原理是将数组分到有限数量的桶里,每个桶再分别排序. 它的算法流程如下所示: 设置一个定量的数组当作空桶子. 寻访序列,并且把项目一个一个放到对应 ...
随机推荐
- 再看Java基本类型
Java中的基本类型可以分为三类,字符类型char,布尔类型boolean以及数值类型byte.short.int.long.float.double. 数值类型又可以分为整数类型byte.short ...
- Java字节码基础[转]
原文链接:http://it.deepinmind.com/jvm/2014/05/24/mastering-java-bytecode.html Java是一门设计为运行于虚拟机之上的编程语言,因此 ...
- 自己动手实践 spring retry 重试框架
前序 马上过年了,预祝大家,新年快乐,少写bug 什么是spring retry? spring retry是从spring batch独立出来的一个能功能,主要实现了重试和熔断. 什么时候用? 远程 ...
- [Python Study Notes]psutil模块
系统性能信息模块psutil psutil是一个跨平台库,能够轻松实现获取系统运行的进程和系统利用率(CPU,内存,磁盘,网络等)信息,主要应用于系统监控,分析和限制系统资源及进程的管理,它实现了同等 ...
- Chrome浏览器的自动安装下载工具
链接 https://www.google.com/chrome/browser/desktop/index.html?brand=CHWL&utm_campaign=en&utm_s ...
- vagrant系列教程(二):vagrant的配置文件vagrantfile详解(转)
原文:http://blog.csdn.net/hel12he/article/details/51089774 上一篇文章完整的讲叙了如何安装一个vagrant的环境.这里主要说一说vagrant的 ...
- /dev/null 2>&1 详解
今天一个朋友突然在自己的维护的Linux中, /var/spool/cron/root 中看到了以下的内容: 30 19 * * * /usr/bin/**dcon.sh > /dev/nul ...
- iOS字体名字
上面我们提到我们需要设置字体集,在IOS系统中我们用到的字体包含一下几种 : Font Family: American Typewriter( AmericanTypewriter,American ...
- ng-csv 异步数据下载
相信很多码友遇到一个很坑的问题吧,就是使用ng-csv 的时候 lazy-load="true" 设置为true 还是 会下载0行数据 var getArray= functio ...
- JMeter之Http协议接口性能测试
一.不同角色眼中的接口 1.1,开发人员眼中的接口 1.2,测试人员眼中的接口 二.Http协议基本介绍 2.1,常见的接口协议 1.:2. :3. :4.:5.: 6. 2.2,Http协议栈 ...