Python实现八大排序算法
(原创作者:陈玓玏)
import math
import random
'''
时间复杂度记忆- 冒泡、选择、直接插入排序需要两个for循环,每次只关注一个元素,平均时间复杂度为O(n2)O(n2)(一遍找元素O(n)O(n),一遍找位置O(n)O(n))
快速、归并、希尔、堆基于二分思想,log以2为底,平均时间复杂度为O(nlogn)O(nlogn)(一遍找元素O(n)O(n),一遍找位置O(logn)O(logn)),在最坏的情况下,快排和希尔复杂度还会变得和冒泡一样计数排序和基排序不属于这些范畴,它们的时间复杂度和空间复杂度如下:计数排序 O(n+k) O(n+k) O(n+k) 是基数排序 O(N∗M) O(N∗M) O(M) 是
稳定性记忆-“快希选堆”(快牺牲稳定性) 排序算法的稳定性:排序前后相同元素的相对位置不变,则称排序算法是稳定的;否则排序算法是不稳定的。
'''# 1. 冒泡排序
def maopao(list): #两个for循环,时间复杂度始终为n^2for i in range(len(list)):for j in range(len(list)-i-1):if(list[j]>list[j+1]):list[j],list[j+1] = list[j+1],list[j]print(list)return list# 2. 选择排序
def xuanze(list): #两个for循环,不一样的是不会每次都交换,一轮内部循环后交换一次tmp = ['','']for i in range(len(list)):tmp = [list[i],i]for j in range(i+1,len(list),1):if(list[j]<tmp[0]):tmp = [list[j],j]if tmp[1]!=i:list[i],list[tmp[1]] = list[tmp[1]],list[i]print(i,list)return list# 3. 插入排序
def charu(list): #两个for循环,外层是一个个往后挪,里层是前面已经排好序的for i in range(1,len(list),1):for j in range(0,i,1):print(i,j,list)if list[i]<list[j]:list[i],list[j] = list[j],list[i]print(list)return list# 3. 插入排序改良版,前面的插入排序是直接交换,可能出现2插入[1,2,3,4]中变为[1,2,2,4,3]这种情况,其实是不对的,所以要改成从后往前比较
def charu2(list):for i in range(1,len(list),1):tmp = list[i]for j in range(0,i,1):#tmp = list[i] #不知道为什么,当把tmp定义在这里的时候,tmp的值会在两轮list[i-j] = tmp之后改变,导致结果错误#print(tmp,list[i-j])if tmp<list[i-j]:list[i-j+1] = list[i-j]list[i-j] = tmpprint(list)return list
插入排序一个更容易理解的版本:
def charu(list):for i in range(1,len(list)):for j in range(i,0,-1):print(i,j)if list[j]<list[j-1]:list[j-1],list[j] = list[j],list[j-1]print(list)print(list)# 4. 快排
def kuaipai(list): #随机选择一个中位数,做二分,大的放左边,小的放右边,再递归,一个for循环,但是要递归,所以复杂度根据初始序列的好坏程度来决定print(list)if len(list) > 1:mid = list[0]bigger = []smaller = []for i in range(1,len(list),1):if list[i] <mid:smaller.append(list[i])else:bigger.append(list[i])# if smaller!= []:# smaller = kuaipai(smaller)# if bigger!= []:# bigger = kuaipai(bigger)list = kuaipai(smaller)+ [mid] + kuaipai(bigger)#list = smaller + [mid] + biggerprint(list)return listelse:return list# 5. 归并
def guibing(list): #以中间位置为划分,左边右边按位置分开,然后依次类推做划分,最后组内排序、合并,也有递归过程if len(list) > 1:print('shuru',list)before = list[0:int(len(list)/2)]after = list[int(len(list)/2):]print('before,after',before,after)before = guibing(before)after = guibing(after)print('before1,after1', before, after)#下面是对两个排序数组进行合并,tmplist记录的是before和after两个数组的指针tmplist = [0,0]while tmplist[0]!=len(before) and tmplist[1]!=len(after):if before[tmplist[0]] < after[tmplist[1]]:tmplist.append(before[tmplist[0]])】tmplist[0] = tmplist[0]+1else:tmplist.append(after[tmplist[1]])tmplist[1] = tmplist[1] + 1#下面代码的意思是:如果两个有序数组合并的过程中,有一个先遍历完了,那另一个就直接加入到数组后面if tmplist[0] == len(before):tmplist = tmplist + after[tmplist[1]:]if tmplist[1] == len(after):tmplist = tmplist + before[tmplist[0]:]print('shuchu',tmplist[2:])return tmplist[2:]else:return list# 6. 计数排序
def jishu(list):count_list = []relist = []tmp = [0,0]while sum(count_list) < len(list):for i in list:if i==tmp[0]:tmp[1] = tmp[1] +1print(i,tmp[1])tmp[0] = tmp[0] + 1count_list.append(tmp[1])tmp[1] = 0print(count_list)for i in range(len(count_list)):while count_list[i]!=0:relist.append(i)count_list[i] = count_list[i]-1print(relist)return relist# 6. 改良的计数排序,因为上面的需要遍历n次,时间复杂度太高,而改良版只需要遍历一次
#两个for循环,但是只遍历一次列表,第一个是建立列表的,第二个是输出列表的
def jishu2(list):count_list = []relist = []list0 = [0]for i in list:if i+1 > len(count_list):count_list = count_list + list0*(i+1-len(count_list)) #增加数组的长度,并且新增项的初始值都是0print(count_list)count_list[i] = count_list[i] + 1for i in range(len(count_list)):while count_list[i]!=0:relist.append(i)count_list[i] = count_list[i]-1print(relist)return relist# 7. 桶排序
def tongpai(list):count_list = []relist = []for i in list:flo = math.floor(i)if flo + 1 > len(count_list):for h in range(flo + 1 - len(count_list)):count_list.append([])#count_list = count_list + list0 * (flo + 1 - len(count_list)) #对于数组用这种方法会出错print(count_list)count_list[flo].append(i)if len(count_list[flo])>1:for j in range(len(count_list[flo])):if count_list[flo][len(count_list[flo])-j-1] > i:count_list[flo][len(count_list[flo]) - j] = count_list[flo][len(count_list[flo]) - j-1]count_list[flo][len(count_list[flo]) - j-1] = ifor i in range(len(count_list)):if len(count_list[i]) != 0:relist = relist + count_list[i]print('relist',relist)return relist# 8. 堆排序
def dadingdui(list): #先建大顶堆n = math.log(len(list)+1,2)for i in range(len(list)):if i*2+1<=len(list)-1: #这句判断当前节点是否是叶子节点,条件成立时表示不是叶子节点if i*2+1==len(list)-1: #这句表示只有一个左叶子节点if list[i]<list[i*2+1]:list[i],list[i * 2 + 1] = list[i*2+1],list[i]else: #当节点有左右两个叶子节点时maxl = list[i]loc = ifor j in [1,2]:if list[i*2+j]>maxl:maxl = list[i*2+j]loc = i*2+jlist[i],list[loc] = list[loc],list[i]print(list)return list#二叉树有多少层,就要检查多少遍大顶堆的正确性
def duipai(list):for i in range(math.floor(math.log(len(list),2))+3):list = dadingdui(list)print(list)relist = [0]*len(list)for i in range(len(list)):list[0],list[len(list)-1] = list[len(list)-1],list[0]relist[len(list)-1] = list[len(list)-1]list.pop()if len(list)>0:for j in range(math.floor(math.log(len(list), 2)) + 3):list = dadingdui(list)print(len(relist),relist)list = [100,900,60,30,1000,1]
list = [1,3,5,7,9,10,3]
list = []
for i in range(40):list.append(random.randint(1,100))
print(list)
# list = [7,6,5,4,3,2,1]
# list = [0,4,5,6,2,2,6,8,9,1,2,4,5,6,7,8,9,10,9,2,2,2,3,4,5,11] #针对计数排序的
# list = [0,4.1,5.2,6.3,2.9,2.5,6.1,8.7,9.1,1,2.5,4.6,5.9,6.1,7.2,8,9,10,9.7,2.5,2.2,2,3.3,4.6,5.1,11] #针对桶排序的
#maopao(list)
#xuanze(list)
#charu(list)
#charu2(list)
#kuaipai(list)
#guibing(list)
#jishu(list)
#jishu2(list)
#tongpai(list)
duipai(list)
Python实现八大排序算法相关推荐
- Python实现八大排序算法(转载)+ 桶排序(原创)
插入排序 核心思想 代码实现 希尔排序 核心思想 代码实现 冒泡排序 核心思想 代码实现 快速排序 核心思想 代码实现 直接选择排序 核心思想 代码实现 堆排序 核心思想 代码实现 归并排序 核心思想 ...
- python基础===八大排序算法的 Python 实现
本文用Python实现了插入排序.希尔排序.冒泡排序.快速排序.直接选择排序.堆排序.归并排序.基数排序. 1.插入排序 描述 插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一 ...
- python的八大排序算法
本文用Python实现了插入排序.希尔排序.冒泡排序.快速排序.直接选择排序.堆排序.归并排序.基数排序. 1.插入排序 描述 插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一 ...
- 如何用Python实现八大排序算法
1.插入排序 描述 插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的.个数加一的有序数据,算法适用于少量数据的排序,时间复杂度为 O(n^2).是稳定的排序方法.插入算法 ...
- python 排序算法 简书_Python---简析八大排序算法
前言 1 .排序的概念 排序是计算机内经常进行的一种操作,其目的是将一组"无序"的记录序列调整为"有序"的记录序列. 排序分为内部排序和外部排序. 若整个排序过 ...
- 八大排序算法的 Python 实现
八大排序算法的 Python 实现 本文用Python实现了插入排序.希尔排序.冒泡排序.快速排序.直接选择排序.堆排序.归并排序.基数排序. 1.插入排序 描述 插入排序的基本操作就是将一个数据插入 ...
- 用python排序算法_Python - 八大排序算法
1.序言 本文使用Python实现了一些常用的排序方法.文章结构如下: 1.直接插入排序 2.希尔排序 3.冒泡排序 4.快速排序 5.简单选择排序 6.堆排序 7.归并排序 8.基数排序 上述所有的 ...
- Python数据结构常见的八大排序算法(详细整理)
前言 八大排序,三大查找是<数据结构>当中非常基础的知识点,在这里为了复习顺带总结了一下常见的八种排序算法. 常见的八大排序算法,他们之间关系如下: 排序算法.png 他们的性能比较: 下 ...
- C语言八大排序算法,附动图和详细代码解释!
文章来源:电子工程专辑.C语言与程序设计.竹雨听闲 一.前言 如果说各种编程语言是程序员的招式,那么数据结构和算法就相当于程序员的内功. 想写出精炼.优秀的代码,不通过不断的锤炼,是很难做到的. 二. ...
- 硬核!C语言八大排序算法,附动图和详细代码解释!
来源 :C语言与程序设计.竹雨听闲等 一 前言 如果说各种编程语言是程序员的招式,那么数据结构和算法就相当于程序员的内功. 想写出精炼.优秀的代码,不通过不断的锤炼,是很难做到的. 二 八大排序算法 ...
最新文章
- 私聊模式的设计与实现
- 极简代码:害死人不偿命的(3n+1)猜想 (15分)
- Oracle中主键自增长
- .NET Core etcd 配置源
- 键盘上的反引号怎么打
- phpstrom配置Xdebug
- 不装了,摊牌了,月薪10571元的我是新生代农民工中的一员
- HDOJ 1713 相遇周期 (最大公约数与最小公倍数)
- windows 邮件系统收发163邮件
- 计算机管理员命令符怎么关机,详细教您电脑关机命令是什么
- 美化MyEclipse
- MOOS-ivp 实验三 MOOS简介(1)
- [WinError 206] 文件名或扩展名太长(组策略值修改 解除windows文件名 字符长度限制)
- javascript复习资料第一部分
- 解决iOS6 Apple ID无法登录!十年了,爷青回!还是那个iPhone 4s,竟然能登陆成功!
- 全面 一文理解微服务高可用的常用手段
- React Routing
- 51单片机频率计c语言程序,51单片机简易频率计源代码
- 消愁,一杯敬故乡,一杯敬远方
- 联发科加入开放式神经网络交换平台,以推动AI创新
热门文章
- ps怎么把图片透明化
- 吃鸡游戏计算机配置,三款畅玩“吃鸡”游戏电脑配置推荐
- x86 BIOS 中断 INT 10h
- 数学四大思想八大方法_四种思想方法,让你轻松掌握高中数学
- python数据分析论文报告电影_一个实战案例带你走完python数据分析全流程:豆瓣电影评论的关键词云图制作...
- 计算机的运算符号,运算符号包括哪些
- Java同步问题_Java多线程同步问题
- table表单的修改和保存
- 蓝牙调试器-划时代无线调试器
- 左耳朵谈个人成长:做正确的事,等着被开除