一、冒泡排序

原理:

  1. 比较相邻的元素。如果第一个比第二个大就交换他们两个
  2. 每一对相邻元素做同样的工作,直到结尾最后一对
  3. 每个元素都重复以上步骤,除了最后一个

第一步:

将乱序中的最大值找出,逐一移到序列最后的位置

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]

二、选择排序

思路:

  1. 首先在序列中找到最大(小)元素,存放到序列的最后
  2. 在从剩余的序列元素中继续找最大(小)的元素,放到序列中上一个最大值的前一个位置
  3. 重复第二步,直到所有元素排序完毕

第一步:

将乱序中的元素两两比较,找出最大值,然后直接将最大值放置到序列最后的位置(将最大值直接和最后一个元素交换位置)

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

五、快速排序

思路:

  1. 将列表中第一个元素设定为基准数字,赋值给mid变量,然后将整个列表中比基准小的数值放在基准的左侧,比基准大的数字放在基准右侧,然后将基准数字左右两侧的序列在根据此方法进行排放
  2. 定义两个指针,low 指向最左侧,high 指向最右侧
  3. 然后对最右侧指针进行向左移动,移动法则是,如果指针指向的数值比基准小,则将指针指向的数字移动到基准数字原始位置,否则继续移动指针。
  4. 如果最右侧指针指向的数值移动到基准位置时,开始移动最左侧指针,将其向右移动,如果该指针指向的数值大于基准侧将该数值移动到最右侧指针指向的位置,然后停止移动。
  5. 如果左右侧指针重复则,将基准放入左右指针重复的位置,则基准左侧为比其小的数值,右侧为比其大的数值

第一步:

核心操作,将基数 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实现常用五种排序算法的更多相关文章

  1. C#常用8种排序算法实现以及原理简介

    public static class SortExtention { #region 冒泡排序 /* * 已知一组无序数据a[1].a[2].--a[n],需将其按升序排列.首先比较a[1]与a[2 ...

  2. python:实现几种排序算法

    冒泡排序 比较相邻两个字符,如果左边大于右边,则交换位置,遍历一遍字符后,则最大的肯定在最右边:继续循环处理剩下的字符(最右边的不用再比较了,已经最大了) 代码实现: def BubbleSort(s ...

  3. 几种排序算法的学习,利用Python和C实现

    之前学过的都忘了,也没好好做过总结,现在总结一下. 时间复杂度和空间复杂度的概念: 1.空间复杂度:是程序运行所以需要的额外消耗存储空间,一般的递归算法就要有o(n)的空间复杂度了,简单说就是递归集算 ...

  4. java算法03 - 常用的8种排序算法

    Java常用的八种排序算法: 插入排序 - 直接插入排序 每次将待排序的记录按照关键字的大小,插入到前面已经排好序的记录的适当位置.直到全部记录插入完成. 代码实现 /** * 直接插入排序 O(n^ ...

  5. 学习Java绝对要懂的,Java编程中最常用的几种排序算法!

    今天给大家分享一下Java中几种常见的排序算法的Java代码 推荐一下我的Java学习羊君前616,中959,最后444.把数字串联起来!     ,群里有免费的学习视频和项目给大家练手.大神有空时也 ...

  6. 常用七种排序的python实现

    1 算法复杂度 算法复杂度分为时间复杂度和空间复杂度.其中, 时间复杂度是指执行算法所需要的计算工作量:而空间复杂度是指执行这个算法所需要的内存空间. 算法的复杂性体现在运行该算法时的计算机所需资源的 ...

  7. Java 的八种排序算法

    Java 的八种排序算法 这个世界,需要遗忘的太多. 背景:工作三年,算法一问三不知. 一.八种排序算法 直接插入排序.希尔排序.简单选择排序.堆排序.冒泡排序.快速排序.归并排序和基数排序. 二.算 ...

  8. 用 C 语言描述几种排序算法

    排序算法是最基本且重要的一类算法,本文基于 VS2017,使用 C 语言来实现一些基本的排序算法. 一.选择排序 选择排序,先找到数组中最小的元素,然后将这个元素与数组的第一个元素位置互换(如果第一个 ...

  9. Python实现十大经典排序算法(史上最简单)。

    十大排序算法(Python实现)一. 算法介绍及相关概念解读 算法分类十种常见排序算法可以分为两大类: 非线性时间比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn), ...

随机推荐

  1. MySQL—Dos命令操作数据库

    MySQL 是一个关系型数据库,存在表的概念 结构,数据库可以存放多张表,每个表可以存放多个字段,每个字段可以存放多个记录 Dos命令操作数据库 PhpStudy使用终端打开数据库 第一次打开默认的密 ...

  2. SuperEdge 云边隧道新特性:从云端SSH运维边缘节点

    背景 在边缘集群的场景下边缘节点分布在不同的区域,且边缘节点和云端之间是单向网络,边缘节点可以访问云端节点,云端节点无法直接访问边缘节点,给边缘节点的运维带来很大不便,如果可以从云端SSH登录到边缘节 ...

  3. 3、dns服务搭建

    3.1.dns服务简介: 1.DNS(Domain Name System)域名系统. 目前提供网络服务的应用使用唯一的32位的IP地址来标识,但是由于数字比较复杂.难以记忆,因此产生了域名系统(DN ...

  4. external-attacher源码分析(2)-核心处理逻辑分析

    kubernetes ceph-csi分析目录导航 基于tag v2.1.1 https://github.com/kubernetes-csi/external-attacher/releases/ ...

  5. RabbitMQ消息可靠性传输

    消息的可靠性投递是使用消息中间件不可避免的问题,不管是使用kafka.rocketMQ或者rabbitMQ,那么在RabbitMQ中如何保证消息的可靠性投递呢? 先再看一下RabbitMQ消息传递的流 ...

  6. CentOS-yum安装Nginx

    查看系统版本 $ cat /etc/redhat-release Nginx 不在默认的 yum 源中,使用官网的 yum 源 $ rpm -ivh http://nginx.org/packages ...

  7. Docker:Docker部署mysql数据库

    docker部署mysql : 8.0 1.在宿主机创建mysql挂载目录 #创建目录 mkdir /home/mysql/conf mkdir /home/mysql/logs mkdir /hom ...

  8. 2020年MySQL数据库面试题总结(50道题含答案解析)

    1.MySQL 中有哪几种锁? (1)表级锁:开销小,加锁快:不会出现死锁:锁定粒度大,发生锁冲突的概率最 高,并发度最低. (2)行级锁:开销大,加锁慢:会出现死锁:锁定粒度最小,发生锁冲突的概率最 ...

  9. MySQL 删除devices表中id最大的一行

    原想法:delete from devices where id in (select max(id) from devices); 报错:ERROR 1093 (HY000): You can't ...

  10. Kong Admin API — 核心对象

    目录 Service API详解 1. 添加服务 2. 列出service列表 3. 查找service 按条件查找service 查找与指定route关联的service 查找与指定Plugin关联 ...