Python实现常见的排序算法
冒泡排序(Bubble Sort):列表相邻的两个数,如果前面比后面大,则交换这两个数。一趟排序结束后,无序区减少一个数,有序区增加一个数。
import random
def bubble_sort(li):for i in range(len(li)-1): #多少趟,每次找出的是最值,所以只需n-1趟for j in range(len(li)-i-1): #循环每趟,排出一个if li[j] > li[j+1]:li[j],li[j+1] = li[j+1],li[j]
li = [random.randint(0,1000) for i in range(1000)]
print(li)
bubble_sort(li)
print(li)
选择排序:一趟取最小的数,放到第一个位置,在一趟排序记录列表无序区最小的数,放到第二个位置;算法关键:有序区和无序区,无序区最小数的位置。
def select_sort(li):for i in range(len(li)-1): #多少趟,每趟取出一个最小值min_loc = i #取出的值得下标暂时当做每趟最小下标for j in range(i+1,len(li)): #在剩余无序区做循环,拿出最值if li[j] <li[min_loc]:min_loc = jli[i],li[min_loc]= li[min_loc],li[i]return li
li = [1,4,5,6,7,7,2,0,7]
print(select_sort(li))
插入排序:初始时手里(有序区)只有一张牌,每次从(无序区)摸一张牌,插入到手里正确位置。
def sort(li):for i in range(1,len(li)): #从无序区开始拿牌,从1开始是将0当为有序区tmp = li[i] #一次拿到的牌j = i-1 #有序区最后一张牌下标while j >= 0 and li[j] > tmp: #有序区有牌且最后一个元素比拿出来的元素大li[j+1] = li[j] #将有序区牌后移给tmp腾地方j -= 1 #遍历有序区li[j+1] = tmp #遍历结束,将tmp放在合适的位置上,j+1是遍历完的符合条件的合适位置print(li)
li = [9,1,3,4,6,2]
sort(li)
希尔排序:是一种分组插入排序算法。时间复杂度跟选择的gap有关。1、先取一个整数d1=n/2,将元素分为d1个组,每组相邻量元素之间距离为d1,在各组内进行直接插入排序。2、取第二个人整数d2=d1/2,重复上述分组排序过程,直到d1=1,即所有元素在同一组内进行直接插入排序。希尔排序每趟并不使某些元素有序,而是使整体数据越来越接近有序,最后一躺排序是所有数据有序。
def inser_sort_gap(li,gap):for i in range(gap,len(li)): #从gap开始,可以循环每组无序区,因为gap之前的是每组有序区的第一个元素tmp = li[i] #每组无序区拿出的元素j = i - gap #每组有序区的元素while j >= 0 and li[j] > tmp: #每组有序区有元素且拿出的元素与有序区元素冲突li[j+gap] = li[j] #将大小冲突元素后移j -= gap #合适位置前移li[j+gap] = tmp #将tmp放在前移的j+gap位置上
def shell_sort(li):d = len(li)//2 #分为d组,相邻元素间隔dwhile d >= 1: #当分为最小组,停止循环,此时相邻元素间隔1inser_sort_gap(li,d)d //= 2
li = list(range(19))
import random
random.shuffle(li)
print(li)
shell_sort(li)
print(li)
快速排序:(思路:1.取一个元素p,使p归位。2.列表分为两个部分,左边都比p小,右边都比p大。3.递归。)效率:nlog(n) 最坏情况,递归
def guiwei(li,left,right): #将列表分为2部分,左边比tmp小,右边比tmp大tmp = li[left] #tmp取值while left < right: #更新完left,right后,继续循环while li[right] >= tmp and left < right: #当右边元素比tmp大right -= 1 #满足条件,right左移,防止一直左移下去,要求left《rightli[left] = li[right] #将比tmp大的元素移到左边while li[left] <= tmp and left < right:left += 1li[right] = li[left] #li[left] = tmp #left一直在右移,最终到达合适位置return left #返回界限下标
def quick_sort(li,left,right):if left < right: #mid = guiwei(li, left, right) #找出界限quick_sort(li, left, mid - 1) #对界限左边进行循环quick_sort(li, mid + 1, right) #对界限右边进行循环
import random
li = list(range(19))
random.shuffle(li)
print(li)
quick_sort(li,0,len(li)-1)
print(li)
归并排序:对列表进行递归拆分到单独元素,在进行递归合并为一整个有序列表。
def merge(li,low,mid,high): #对2个列表进行合并,使得合并后的列表有顺序ltmp = [] #新的列表i = low #i,j分别为两个列表的开始下标j = mid + 1while i <= mid and j <= high: #对2个列表依次拿出比较,符合条件的会加入到ltmp,指针会更新if li[i] < li[j]:ltmp.append(li[i])i += 1else:ltmp.append(li[j])j += 1while i <= mid: #当之前指针更新结束,说明其中一个列表已经全部加入ltmp,另一个列表中的其余元素则全部加入ltmpltmp.append(li[i])i += 1while j <= high:ltmp.append(li[j])j += 1li[low:high+1] = ltmp #ltmp每次递归,low-high+1是把一次递归的元素加上,+1是列表的索引性
def merge_sort(li,low,high): #将列表递归拆分if low < high: #一个列表左边小于右边就循环,也就是说只要列表有至少2个元素就进行拆分mid = (low + high) // 2 #拆分界线merge_sort(li, low, mid) #整除都是向下取整,所以mid,mid+1可以做到以mid为界限进行拆分merge_sort(li, mid + 1, high)merge(li, low, mid, high) #拆分递归到最后,是单个元素进行归并;然后再归并递归
li = list(range(9))
import random
random.shuffle(li)
print(li)
merge_sort(li,0,len(li)-1)
print(li)
计数排序:对列表进行排序,已知列表的数范围在0-100之间。设时间复杂度为O(n)的算法。
def count_sort(li):count = [0 for _ in range(max(li)+1)] #count为每个元素的个数表for k in li:count[k] += 1li.clear()for kk,kkk in enumerate(count): #循环每个元素及其个数,enumerate的作用是遍历索引及其元素for p in range(kkk): #range个数,打印元素,喵喵!!!li.append(kk)
import random
li = [random.randint(0,10) for _ in range(10)]
print(li)
count_sort(li)
print(li)
桶排序:首先将元素分在不同的桶里,在对每个桶里面的元素进行排序。桶排序的表现取决于数据的分布。也就是需要对不同数据排序时采用不同的分桶策略。平均情况时间复杂度:O(n+k)
def bar_sort(li,n,max_num): #n为桶的个数,max_num为li中的最大数,根据他两确定桶之间的差值buckets = [[] for _ in range(n)] #建立n个空桶for k in li:i = min(k//(max_num//n),n-1) #循环列表元素,将其放在适当桶里面buckets[i].append(k)for j in range(len(buckets[i])-1,0,-1): #循环每个桶里面的元素,0--len-1表示每个桶里面的所有元素if buckets[i][j] < buckets[i][j-1]:buckets[i][j-1],buckets[i][j] = buckets[i][j],buckets[i][j-1]else:breaksort_li = []for bucket in buckets:sort_li.extend(bucket)return sort_li
import random
li = [random.randint(0,100) for _ in range(100)]
print(li)
li = bar_sort(li,10,100)
print(li)
基数排序: 时间复杂度O(kn) 空间复杂度O(k+n) k表示数字位数
def ratix_sort(li): #将数字整除取余,依次按顺序添加到适当位置max_num = max(li) #列表中的最大数字it = 0 #首先从个位数开始while 10 ** it <= max_num: #当10的it次方小于最大数buckets = [[] for _ in range(10)] #余数为0--9,一共10个桶for var in li:geweishu = (var//10**it) % 10 #取每个数的余数buckets[geweishu].append(var) #将其放在余数的桶里,使得每个桶里的元素个位数一样li.clear()print(buckets)for buc in buckets:li.extend(buc)it += 1 #一趟结束后,it+1,继续上述操作,可以对之前桶里面的元素进行排序return li
import random
li = list(range(1000))
random.shuffle(li)
print(li)
c = ratix_sort(li)
print(c)
堆:一种特殊的完全二叉树结构。大根堆:一颗完全二叉树,满足任一节点都比其孩子节点大。(领导机构)小根堆:一颗完全二叉树,满足任一节点都比其孩子节点小。 堆的向下调整性:假设根节点的左右子树都是堆,但根节点不满足堆的性质,可以通过一次向下的调整来将其变成一个堆。 堆排序过程:1.建立堆.2.得到堆顶元素,为最大元素。3.去掉堆顶,将堆最后一个元素放到堆顶,此时可通过一次调整重新使堆有序。4.堆顶元素为第二大元素。5.重复步骤3,直到堆变空。
def shift(li,low,high): #堆的向下调整,一次将合适元素放在堆顶,low指堆顶tmp = li[low] #将堆顶暂时存在tmpi = low #根节点和叶节点j = 2*i + 1while j <= high: #当叶节点没到最后一个元素,一直循环if j + 1 <= high and li[j] < li[j+1]:j = j + 1 #保证拿最大叶节点和根节点比较大小if li[j] > tmp: #如果叶节点大于根节点,大的上移,将根节点下移到叶节点位置,循环比较li[i] = li[j]i = jj = 2*i + 1else:li[i] = tmp #当不符合循环条件,说明堆已经有序,将tmp放在此时的根节点位置上breakelse:li[i] = tmp #当跳出循环时,后面没有元素,将其放在此时的叶节点位置上
def heap_sort(li):n = len(li)for i in range(n-2//2,-1,-1): #循环跟节点,根节点从下向上,对每个根节点进行向下调整,达到建堆目的shift(li,i,n-1) #向下调整,起点为当前根节点for i in range(n-1,-1,-1): #循环拿出堆的最后一个元素,将其并入有序列表li[0],li[i] = li[i],li[0]shift(li,0,i-1) #每次拿出一个元素,对剩余的其他元素进行建堆,其余元素有序,只需调整一次import random
li = list(range(19))
random.shuffle(li)
print(li)
heap_sort(li)
print(li)
Python实现常见的排序算法相关推荐
- Python版常见的排序算法
学习笔记 排序算法 目录 排序分为两类,比较类排序和非比较类排序,比较类排序通过比较来决定元素间的相对次序,其时间复杂度不能突破O(nlogn):非比较类排序可以突破基于比较排序的时间下界,缺点就是一 ...
- python常用算法有哪些_python常见的排序算法有哪些?
大家都知道,关于python的算法有很多,其中最为复杂的就是python的排序算法,因为它并不是单一的,而是复杂的,关于排序算法就有好几种不同的方式,大家可以根据以下内容,结合自己的项目需求,选择一个 ...
- access两字段同时升序排序_7 天时间,我整理并实现了这 9 种常见的排序算法
排序算法 回顾 我们前面已经介绍了 3 种最常见的排序算法: java 实现冒泡排序讲解 QuickSort 快速排序到底快在哪里? SelectionSort 选择排序算法详解(java 实现) 然 ...
- PHP面试题:请写出常见的排序算法,并用PHP实现冒泡排序,将数组$a = array()按照从小到大的方式进行排序。
常见的排序算法: 冒泡排序法.快速排序法.简单选择排序法.堆排序法.直接插入排序法.希尔排序法.合并排序法. 冒泡排序法的基本思想是:对待排序记录关键字从后往前(逆序)进行多遍扫描,当发现相邻两个关键 ...
- 一篇夯实一个知识点系列--python实现十大排序算法
写在前面 排序是查找是算法中最重要的两个概念,我们大多数情况下都在进行查找和排序.科学家们穷尽努力,想使得排序和查找能够更加快速.本篇文章用Python实现十大排序算法. 很多人学习python,不知 ...
- 排序算法python实现_合并排序算法– Java,C和Python实现
排序算法python实现 Merge sort is one of the most efficient sorting algorithms. It works on the principle o ...
- JS 常见的排序算法
工作中算法不常用,但是排序经常用.因此在这里整理了几种JS中常见的排序算法. 冒泡排序 1.算法思想:判断两个相邻元素,大于则交换位置 2.算法步骤 从数组中第一个数开始,依次与下一个数比较并次交换比 ...
- 七种常见的排序算法总结
目录 引言 1.什么是排序? 2.排序算法的目的是什么? 3.常见的排序算法有哪些? 一,插入排序 1.基本思想 2.代码实现 3.性能分析 4.测试 二,希尔排序(缩小增量排序) 1.基本思想 2. ...
- 基于比较的常见的排序算法
目录 写在前面 排序 稳定性 排序的分类 常见的基于比较的排序 直接插入排序 代码 性能分析 总结 代码优化 折半插入 希尔排序 希尔排序 如何分组 代码 性能分析 选择排序 代码 性能分析 双向选择 ...
最新文章
- python3.7源码分析-字典
- 初学者怎么学单片机,嵌入式单片机培训机构有用吗?
- 半监督目标检测相关方法总结
- Self-Attention GAN 中的 self-attention 机制
- 3.Lucene3.x API分析,Director 索引操作目录,Document,分词器
- 大数据 互联网架构阶段 Redis
- mysql 多级分类_数据库多级分类相关行排列在一起的查询
- 密码学在区块链隐私保护中的应用学习
- java web filter链_filter过滤链:Filter链是如何构建的?
- axis在matlab中是什么意思_珠宝首饰上的钢印是什么意思呢?你都知道吗
- bp神经网络预测模型流程图,bp神经网络实例分析
- iOS country code及国际区号
- 大数据、数据分析、数据挖掘的差别
- Centos安装显卡驱动
- threejs第十三用 简单堆积木
- 可以边玩游戏边学编程的手游盘点
- 计算机深度睡眠状态啥意思,什么是计算机的“深度睡眠”模式?
- 为什么要学习软件质量保证与测试这门课?
- 多益2980邮箱集合专业游戏服务免费安全的电子邮箱
- 技术团队人员管理:组建团队的目的和基本规则
热门文章
- php,ajax -->Uncaught SyntaxError: Unexpected end of JSON input at JSON.parse (<anonymous>)
- 利用GPS定位[android]
- 控制windows 8,win8.1 win10 虚拟键盘
- 02 食尚年华石锅土鲫鱼需求简单描述
- 数组元素右移 c++实现
- 价格歧视:降价促销的底层逻辑
- 如何让图片放大不模糊?
- c语言*p1 什么意思,p1什么意思_p1,意思_词汇大全意思全集
- AT指令(中文详解版)二 [转载]
- C语言:7-10 计算工资.2021-07-29