算法

递归两个特点:
调用自身
有穷调用
计算规模越来越小,直至最后结束

用装饰器修饰一个递归函数时会出现问题,这个问题产生的原因是递归的函数也不停的使用装饰器。
解决方法是,只让装饰器调用一次即可,那么可以出创建一个新的普通函数,执行一下递归函数,并放回递归函数的返回值,给这个普通函数加上装饰器即可。

尾递归和正常循环时间复杂度相同,尾递归:每次递归尾部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实现简单排序算法的更多相关文章

  1. Python实现各种排序算法的代码示例总结

    Python实现各种排序算法的代码示例总结 作者:Donald Knuth 字体:[增加 减小] 类型:转载 时间:2015-12-11我要评论 这篇文章主要介绍了Python实现各种排序算法的代码示 ...

  2. 简单排序算法 C++类实现

    简单排序算法: 冒泡排序 插入排序 选择排序 .h代码: // // SortClass.h // sort and selection // // Created by wasdns on 16/1 ...

  3. 简单排序算法设计(Java)

    总共有八种排序算法,还是慢慢看吧 1.简单排序算法 简单排序算法就是设置标兵,逐个比较数,然后查找插入位置,插入 public static void p(int[] a){ for(int i=0; ...

  4. Python实现常用排序算法

    Python实现常用排序算法 冒泡排序 思路: 它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完 ...

  5. python 的常见排序算法实现

    python 的常见排序算法实现 参考以下链接:https://www.cnblogs.com/shiluoliming/p/6740585.html 算法(Algorithm)是指解题方案的准确而完 ...

  6. 教你用Python实现简单监督学习算法

    教你用Python实现简单监督学习算法 监督学习作为运用最广泛的机器学习方法,一直以来都是从数据挖掘信息的重要手段.即便是在无监督学习兴起的近日,监督学习也依旧是入门机器学习的钥匙. 这篇监督学习教程 ...

  7. 用 python 实现各种排序算法(转)

    常见几种排序的算法: 归并排序 归并排序也称合并排序,是分治法的典型应用.分治思想是将每个问题分解成个个小问题,将每个小问题解决,然后合并. 具体的归并排序就是,将一组无序数按n/2递归分解成只有一个 ...

  8. Python实现八大排序算法(转载)+ 桶排序(原创)

    插入排序 核心思想 代码实现 希尔排序 核心思想 代码实现 冒泡排序 核心思想 代码实现 快速排序 核心思想 代码实现 直接选择排序 核心思想 代码实现 堆排序 核心思想 代码实现 归并排序 核心思想 ...

  9. python实现桶排序算法

    桶排序算法也是一种可以以线性期望时间运行的算法,该算法的原理是将数组分到有限数量的桶里,每个桶再分别排序. 它的算法流程如下所示: 设置一个定量的数组当作空桶子. 寻访序列,并且把项目一个一个放到对应 ...

随机推荐

  1. 让44.1版本的sketch打开更高版本的sketch文件

    我们都知道,sketch的有效license与版本挂钩.最近设计师又更新了sketch版本,导致她生成的源文件我都无法打开. 毕竟我不是使用sketch进行UI设计,仅用它来查看设计稿参数,再花99美 ...

  2. 洛谷 [P2483] [模板] k短路

    人生中的第一道黑题... 其实就是k短路模板 #include <iostream> #include <cstdio> #include <cstring> #i ...

  3. 洛谷 [P2296] 寻找道路

    反向BFS预处理,求出所有符合题意的点,再正向BFS,(注意对于边权恒为一的点,BFS,比SPFA高效) 输入时n与m分清 #include <iostream> #include < ...

  4. SDN第5次上机作业

    SDN第5次上机作业 实验目的 1.搭建如下拓扑并连接控制器 2.下发相关流表和组表实现负载均衡 3.抓包分析验证负载均衡 实验步骤 1.建立以下拓扑,并连接上ODL控制器. 提交要求:ODL拓扑界面 ...

  5. ASP.NET Core Razor 页面使用指南

    ASP.NET Core Razor 页面作为 ASP.NET Core 2.0的一部分发布,它是基于页面的全新的Web开发框架.如果您想学习如何使用 ASP.NET Core Razor 页面,可以 ...

  6. sparksql工程小记

    最近做一个oracle项目迁移工作,跟着spark架构师学着做,进行一些方法的总结. 1.首先,创建SparkSession对象(老版本为sparkContext) val session = Spa ...

  7. C# 使用 SmtpClient 发送邮件注意项

    最近有邮件发送需求,使用 C#  SmtpClient 对象发送邮件 , 报异常, 如下错误代码: 调整代码顺序后,发送邮件成功! 注意:一定要先设置 EnableSsl和UseDefaultCred ...

  8. Git 上传 GitHub

    1.下载 2.安装 3.功能识别 3-1.查看git版本  git  --version 3-2.移除原来的版本 yum  remove git 4.配置 4-1.用户配置信息 git config ...

  9. [翻译] 编写高性能 .NET 代码--第二章 GC -- 将长生命周期对象和大对象池化

    将长生命周期对象和大对象池化 请记住最开始说的原则:对象要么立即回收要么一直存在.它们要么在0代被回收,要么在2代里一直存在.有些对象本质是静态的,生命周期从它们被创建开始,到程序停止才会结束.其它对 ...

  10. hihoCoder 1523 数组重排2 贪心

    题意:给定一个1-N的排列A1, A2, - AN,每次操作小Hi可以选择一个数,把它放到数组的最左边. 请计算小Hi最少进行几次操作就能使得新数组是递增排列的. 思路:最后的序列是递增的,那么必定满 ...