python实现常用五种排序算法
一、冒泡排序
原理:
- 比较相邻的元素。如果第一个比第二个大就交换他们两个
- 每一对相邻元素做同样的工作,直到结尾最后一对
- 每个元素都重复以上步骤,除了最后一个

第一步:
将乱序中的最大值找出,逐一移到序列最后的位置
alist = [3, 5, 9, 2, 1, 7, 8, 6, 4]
def bubble_sort(alist):
# 找最大值的方式是通过对列表中的元素进行两两比较,值大的元素逐步向后移动
# 序列中有n个元素,两两比较的话,需要比较n-1次
for i in range(len(alist) - 1): # 循环n-1次,控制两两比较的次数
if alist[i] > alist[i + 1]:
# 如果前面的元素大于后面的元素,交换两个元素的位置,否则不做任何操作
alist[i], alist[i + 1] = alist[i + 1], alist[i]
return alist
print(bubble_sort(alist))
# 输出:最大值已经移动到最右边了
[3, 5, 2, 1, 6, 7, 8, 4, 9]
当上述代码已经可以将序列中的最大值放置到合适的位置,然后我们就可以将上述操作继续作用到 n-1 和元素对应的新序列,则就可以将 n-1 个元素对应的最大值放置到了 n-1 和元素的最后位置。
结论:发现如果将上述的操作逐步的作用 n-1 此就可以将整个序列变成有序的。
第二步:
将第一步的操作继续作用 n-1 次
alist = [3, 5, 9, 2, 1, 7, 8, 6, 4]
def bubble_sort(alist):
for j in range(len(alist)-1): # 外层循环次数递增,内层循环次数递减
for i in range(len(alist) - 1-j): # 循环次数需要递减-j,控制两两比较的次数
if alist[i] > alist[i + 1]:
# 如果前面的元素大于后面的元素,交换两个元素的位置,否则不做任何操作
alist[i], alist[i + 1] = alist[i + 1], alist[i]
return alist
print(bubble_sort(alist))
# 输出
[1, 2, 3, 4, 5, 6, 7, 8, 9]
二、选择排序
思路:
- 首先在序列中找到最大(小)元素,存放到序列的最后
- 在从剩余的序列元素中继续找最大(小)的元素,放到序列中上一个最大值的前一个位置
- 重复第二步,直到所有元素排序完毕
第一步:
将乱序中的元素两两比较,找出最大值,然后直接将最大值放置到序列最后的位置(将最大值直接和最后一个元素交换位置)
def select_sort(alist):
max_index = 0 # 最大值元素的下标,一开始假设下标为0的元素为最大值
for i in range(len(alist) - 1): # 循环控制两两比较的次数
# 如果在比较的过程中发现,下标为max_index不是最大值,那么就改变max_index
if alist[max_index] < alist[i + 1]:
max_index = i + 1
# 循环结束后max_index就一定是最大值的下标,并且把该数和最后一个值做交换
alist[len(alist) - 1], alist[max_index] = alist[max_index], alist[len(alist) - 1]
return alist
alist = [3, 5, 9, 2, 1, 7, 8, 6, 4]
print(select_sort(alist))
# 输出
[3, 5, 4, 2, 1, 7, 8, 6, 9]
第二步:
将第一步继续作用 n-1 次
def select_sort(alist):
for j in range(len(alist) - 1):# 外层循环递增n-1次
max_index = 0 # 最大值元素的下标,一开始假设下标为0的元素为最大值
for i in range(len(alist) - 1 - j): # 内层循环递减,循环控制两两比较的次数
# 如果在比较的过程中发现,下标为max_index不是最大值,那么就改变max_index
if alist[max_index] < alist[i + 1]:
max_index = i + 1
# 循环结束后max_index就一定是最大值的下标,并且把该数和最后一个值做交换
alist[len(alist) - 1 - j], alist[max_index] = alist[max_index], alist[len(alist) - 1 - j]
return alist
alist = [3, 5, 9, 2, 1, 7, 8, 6, 4]
print(select_sort(alist))
三、插入排序
思路:
- 需要将原始序列分为两个部分:有序部分、无序部分。
- 将无序部分中的元素逐一插入到有序部分中
注意:初始情况下,有序部分为乱序序列中的第一个元素,无序部分为乱序序列的 n-1 个元素
例如:
# 乱序序列:[8,3,5,7,6]
[8, 3,5,7,6] # 8就是初始的有序部分,3、5、7、6就是初始的无序部分
[3,8, 5,7,6]
[3,5,8, 7,6]
[3,5,7,8, 6]
[3,5,7,6,8, ]
第一步:
定义一个变量 i ,i 表示的是有序部分元素的个数和无序部分第一个元素小标
alist = [8, 3, 1, 6, 7]
i = 1 # i 就是有序部分元素的个数和无序部分第一个元素下标
# alist[i-1]:有序部分最后一个元素下标
# alist[i]:无序部分第一个元素下标
if alist[i - 1] > alist[i]:
alist[i], alist[i - 1] = alist[i - 1], alist[i]
# [3, 8, 1, 6, 7]
第二步:循环作用到每个元素中
alist = [8, 3, 1, 6, 7]
i = 2
# alist[i-1]:有序部分最后一个元素下标
# alist[i]:无序部分第一个元素下标
while i > 0:
if alist[i - 1] > alist[i]:
# 循环第一次时[3,1,8, 6,7]
alist[i], alist[i - 1] = alist[i - 1], alist[i]
i -= 1
# 循环继续
# [1,3,8, 6,7]
else:
break
第三步:
处理变量 i,需要让 i 进行自己递增
for i in range(1, len(alist)): # i = [1,2,3,4]
# alist[i-1]:有序部分最后一个元素下标
# alist[i]:无序部分第一个元素下标
while i > 0:
if alist[i - 1] > alist[i]:
alist[i], alist[i - 1] = alist[i - 1], alist[i]
i -= 1
else:
break
完整代码:
def insert_sort(alist):
for i in range(1, len(alist)):
while i > 0:
if alist[i - 1] > alist[i]:
alist[i - 1], alist[i] = alist[i], alist[i - 1]
i -= 1
else:
break
return alist
四、希尔排序
关键变量:增量gap
gap:初始值为 len(alist) // 2
- 表示分组的组数
- 每一组数据之间的间隔
插入排序就是增量为 1 的希尔排序

第一步:
将插入排序代码写出
def hill_sort(alist):
for i in range(1, len(alist)):
while i > 0:
if alist[i - 1] > alist[i]:
alist[i - 1], alist[i] = alist[i], alist[i - 1]
i -= 1
else:
break
return alist
第二步:
在插入排序代码中加入增量的概念
def hill_sort(alist):
gap = len(alist) // 2 # 初识增量
# 将插入排序中的增量1替换成gap
# 由增量1变成了增量为gap了
for i in range(gap, len(alist)):
while i > 0:
if alist[i - gap] > alist[i]:
alist[i - gap], alist[i] = alist[i], alist[i - gap]
i -= gap
else:
break
return alist
第三步:
在第二步中进行增量的缩减(增量缩减到1结束)完整代码
def hill_sort(alist):
gap = len(alist) // 2 # 初识增量
while gap >= 1:
for i in range(gap, len(alist)):
while i > 0:
if alist[i - gap] > alist[i]:
alist[i - gap], alist[i] = alist[i], alist[i - gap]
i -= gap
else:
break
gap //= 2 # 缩减增量
return alist
五、快速排序
思路:
- 将列表中第一个元素设定为基准数字,赋值给mid变量,然后将整个列表中比基准小的数值放在基准的左侧,比基准大的数字放在基准右侧,然后将基准数字左右两侧的序列在根据此方法进行排放
- 定义两个指针,low 指向最左侧,high 指向最右侧
- 然后对最右侧指针进行向左移动,移动法则是,如果指针指向的数值比基准小,则将指针指向的数字移动到基准数字原始位置,否则继续移动指针。
- 如果最右侧指针指向的数值移动到基准位置时,开始移动最左侧指针,将其向右移动,如果该指针指向的数值大于基准侧将该数值移动到最右侧指针指向的位置,然后停止移动。
- 如果左右侧指针重复则,将基准放入左右指针重复的位置,则基准左侧为比其小的数值,右侧为比其大的数值
第一步:
核心操作,将基数 mid 放置到序列中间,使得基数左侧都是比它小的,右侧是比它大的
def quick_sort(alist):
low = 0 # 第一个元素下标
high = len(alist) - 1 # 最后一个元素下标
mid = alist[low] # 基数:初始值为序列中的第一个数值
while low != high:
# 先移动high
while low < high:
if mid < alist[high]: # 下标high对应的值大于mid,high就向右偏移1
high = high - 1
else:
# 否则,就把将high指向的数值放置到左侧下标为low对应的空位
alist[low] = alist[high]
break # 传递后high下标偏移结束
# 开始移动low
while low < high:
if mid > alist[low]: # 下标low对应的值小于mid,low就向左偏移1
low = low + 1
else:
# 否则,就把将low指向的数值放置到左侧下标为high对应的空位
alist[high] = alist[low]
break # 并结束
# 最后当low和high相等的时候,那么就把mid传给下标为low或high的位置
alist[low] = mid
return alist
alist = [6, 1, 2, 7, 9, 3, 4, 5, 10, 8]
print(quick_sort(alist))
# 输出——>6左边都是比6小的,右边都是比6大的
[5, 1, 2, 4, 3, 6, 9, 7, 10, 8]
第二步:
将第一步的核心操作递归作用到基数的左右两侧的子序列中
# 那么如何区分根据基数拆分出的左右子序列呢?可以通过传入指定的left和right来指定不同的子序列
def quick_sort(alist, left, right):
low = left # 第一个元素下标
high = right # 最后一个元素下标
if low > high: # 递归结束条件,low是不能大于high的
return
mid = alist[low] # 基数:初始值为序列中的第一个数值
while low != high:
# 先移动high
while low < high:
if mid < alist[high]: # 下标high对应的值大于mid,high就向右偏移1
high -= 1
else:
# 否则,就把将high指向的数值放置到左侧下标为low对应的空位
alist[low] = alist[high]
break # 传递后high下标偏移结束
# 开始移动low
while low < high:
if mid >= alist[low]: # 下标low对应的值小于mid,low就向左偏移1
low += 1
else:
# 否则,就把将low指向的数值放置到左侧下标为high对应的空位
alist[high] = alist[low]
break # 并结束
# 最后当low和high相等的时候,那么就把mid传给下标为low或high的位置
if low == high:
alist[low] = mid
# 上述为核心操作,需要将核心操作递归作用到左右子序列中
quick_sort(alist, left, low - 1) # 递归到左侧序列中
quick_sort(alist, high + 1, right) # 递归到右侧序列中
return alist
alist = [6, 1, 2, 7, 9, 3, 4, 5, 10, 8]
print(quick_sort(alist, 0, len(alist) - 1))
# 输出
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
python实现常用五种排序算法的更多相关文章
- C#常用8种排序算法实现以及原理简介
public static class SortExtention { #region 冒泡排序 /* * 已知一组无序数据a[1].a[2].--a[n],需将其按升序排列.首先比较a[1]与a[2 ...
- python:实现几种排序算法
冒泡排序 比较相邻两个字符,如果左边大于右边,则交换位置,遍历一遍字符后,则最大的肯定在最右边:继续循环处理剩下的字符(最右边的不用再比较了,已经最大了) 代码实现: def BubbleSort(s ...
- 几种排序算法的学习,利用Python和C实现
之前学过的都忘了,也没好好做过总结,现在总结一下. 时间复杂度和空间复杂度的概念: 1.空间复杂度:是程序运行所以需要的额外消耗存储空间,一般的递归算法就要有o(n)的空间复杂度了,简单说就是递归集算 ...
- java算法03 - 常用的8种排序算法
Java常用的八种排序算法: 插入排序 - 直接插入排序 每次将待排序的记录按照关键字的大小,插入到前面已经排好序的记录的适当位置.直到全部记录插入完成. 代码实现 /** * 直接插入排序 O(n^ ...
- 学习Java绝对要懂的,Java编程中最常用的几种排序算法!
今天给大家分享一下Java中几种常见的排序算法的Java代码 推荐一下我的Java学习羊君前616,中959,最后444.把数字串联起来! ,群里有免费的学习视频和项目给大家练手.大神有空时也 ...
- 常用七种排序的python实现
1 算法复杂度 算法复杂度分为时间复杂度和空间复杂度.其中, 时间复杂度是指执行算法所需要的计算工作量:而空间复杂度是指执行这个算法所需要的内存空间. 算法的复杂性体现在运行该算法时的计算机所需资源的 ...
- Java 的八种排序算法
Java 的八种排序算法 这个世界,需要遗忘的太多. 背景:工作三年,算法一问三不知. 一.八种排序算法 直接插入排序.希尔排序.简单选择排序.堆排序.冒泡排序.快速排序.归并排序和基数排序. 二.算 ...
- 用 C 语言描述几种排序算法
排序算法是最基本且重要的一类算法,本文基于 VS2017,使用 C 语言来实现一些基本的排序算法. 一.选择排序 选择排序,先找到数组中最小的元素,然后将这个元素与数组的第一个元素位置互换(如果第一个 ...
- Python实现十大经典排序算法(史上最简单)。
十大排序算法(Python实现)一. 算法介绍及相关概念解读 算法分类十种常见排序算法可以分为两大类: 非线性时间比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn), ...
随机推荐
- Pytorch项目基本结构
梳理一下Pytorch项目的基本结构(其实TF的也差不多是这样,这种思路可以迁移到别的深度学习框架中) 结构树 -------checkpoints #存放训练完成的模型文件 ----xxx.pk ...
- Luat Demo | 一文读懂,如何使用Cat.1开发板实现Camera功能
让万物互联更简单,合宙通信高效便捷的二次开发方式Luat,为广大客户提供了丰富实用的Luat Demo示例,便于项目开发灵活应用. 本期采用合宙全新推出的VSCode插件LuatIDE,为大家演示如何 ...
- Python分析44130条用户观影数据,挖掘用户与电影之间的隐藏信息!
01.前言 很多电影也上映,看电影前很多人都喜欢去 『豆瓣』 看影评,所以我爬取44130条 『豆瓣』 的用户观影数据,分析用户之间的关系,电影之间的联系,以及用户和电影之间的隐藏关系. 02.爬取观 ...
- Go语言深度比较值是否相等
Go语言深度比较值是否相等 需求描述: 我们在开发过程中经常会遇到一些需要比较值是否相等的场景,例如比较两个数组.结构体.Map.等,自己写这些代码比较繁琐,大部分时候这里都可以使用到反射reflec ...
- kubernetes ceph-csi分析
概述 最近在做分布式存储ceph接入kubernetes,用的是csi这一套,在开发的过程中,自己也用有道云笔记做过一些ceph-csi相关的源码分析.知识总结之类的记录,刚好自己又萌生了发博的想法, ...
- Unity Lamba错误集
请先看对象层级视图 /// <summary> /// 选择关卡的内容对象 /// </summary> public Transform Transform_levelCon ...
- 第3章:快速部署一个Kubernetes集群
kubeadm是官方社区推出的一个用于快速部署kubernetes集群的工具. 这个工具能通过两条指令完成一个kubernetes集群的部署: # 创建一个 Master 节点$ kubeadm in ...
- 5.15、tomcat下部署JPress
1.说明: jpress类似于wordpress,wordpress是php语言开发的国外开源软件,jpress是java语言 开发的国内开源软件: 2.下载软件包: [root@slave-node ...
- 7、Oracle通过客户端(sqlplus)登录认证用户的方式
select version from v$instance; #查看当前数据库的版本 192.168.31.5:1521/orcl 7.1.操作系统认证: 1.Oracle认为操作系统用户是可靠的, ...
- @EnableDiscoveryClient与Nacos自动注册
前一阵看到有篇博客说cloud从Edgware版本开始,可以不加@EnableDiscoveryClient注解,只要配置好注册中心的相关配置即可自动开启服务注册功能,比较好奇其中的原理,研究了一番特 ...