排序算法(冒泡、插入、选择、快排、归并)原理动画及Python、Java实现

news/2024/9/14 9:30:41/ 标签: java, 排序算法, python

排序算法(冒泡、插入、选择、快排、归并)原理动画及Python、Java实现

  • 1 冒泡排序
    • 1.1 原理
    • 1.2 Python、Java实现
  • 2 插入排序
    • 2.1 原理
    • 2.2 Python、Java实现
  • 3 选择排序
    • 3.1 原理
    • 3.2 Python、Java实现
  • 4 快速排序
    • 4.1 原理
    • 4.2 Python、Java实现
  • 5 归并排序
    • 5.1 原理
    • 5.2 Python、Java实现

目前就总结这五种了,其它的后面看到了再弄。

1 冒泡排序

参考冒泡排序(详细图解分析+实现,小白一看就会)

1.1 原理

从序列的第一个元素开始,比较相邻两个元素,若顺序错误(如:从小到大排序时,前一个元素大于后一个元素),则交换位置。继续对下一对相邻元素执行相同的操作,直到序列的末尾。

核心:多趟排序,把最大的泡浮上来
每一轮排序的目的都是找到整个数组中最大的数并把它排在最后端,最后一个最大数不再比较移动。一轮一轮的比较,直到只剩下一个数时(完成了N趟的排序)这个排序就完成了,从而实现从小到大的排序。
在这里插入图片描述

1.2 Python、Java实现

python">def BubbleSort(nums):  # 从小到大n = len(nums)for i in range(n):  # 排序n轮for j in range(n - 1):  # 比较n-1组if nums[j] > nums[j + 1]:nums[j], nums[j + 1] = nums[j + 1], nums[j]return numsnums = [29, 10, 14, 37, 12, 6, 32]
print(BubbleSort(nums))  # [6, 10, 12, 14, 29, 32, 37]"""用一个标记优化"""
def BubbleSort(nums):  # 从小到大n = len(nums)for i in range(n):  # 排序n轮exchange = 0  # 标记是否进入排序循环for j in range(n - 1):  # 比较n-1组if nums[j] > nums[j + 1]:nums[j], nums[j + 1] = nums[j + 1], nums[j]exchange = 1# 如果前面的for循环都结束了,还没有一次交换,说明i后面已经完成了排序# 而前面的排序也已经在前面几轮中完成,所以可以直接跳出循环if exchange == 0:  breakreturn numsnums = [29, 10, 14, 37, 12, 6, 32]
print(BubbleSort(nums))  # [6, 10, 12, 14, 29, 32, 37]
java">import java.util.Arrays;public class Main {public static void main(String[] args) {int[] nums = {29, 10, 14, 37, 12, 6, 32};BubbleSort(nums);
//        System.out.println(nums);  // 这样会直接输出地址System.out.println(Arrays.toString(nums));  // 一开始想的是循环输出,这样后面的"]"前面还会有", "出现// [6, 10, 12, 14, 29, 32, 37]}/*如果函数被声明为static,它就可以被类直接调用,而不需要实例化类对象。如果函数没有被声明为static,它就必须通过实例化类对象来调用。*/public static void BubbleSort(int[] nums){int n = nums.length;for (int i = 0; i < n; i++) {for (int j = 0; j < n - 1; j++) {if (nums[j] > nums[j+1]) {int temp = nums[j];nums[j] = nums[j+1];nums[j+1] = temp;}}}}}/*函数部分优化*/public static void BubbleSort(int[] nums){int n = nums.length;for (int i = 0; i < n; i++) {int exchange = 0;for (int j = 0; j < n - 1; j++) {if (nums[j] > nums[j+1]) {int temp = nums[j];nums[j] = nums[j+1];nums[j+1] = temp;exchange = 1;}}if (exchange == 0){break;}}}

时间复杂度:O(n^2)

是稳定的吗?
稳定指的是相同的数的相对位置是否改变,即5, 0, 9, 11, 9里面的两个9最后位置是否变化。**冒泡排序是稳定的。**这一点在if nums[j] > nums[j + 1]中可以看出。

2 插入排序

十大排序算法(冒泡排序、插入排序、选择排序、希尔排序、堆排序、快排、归并排序、桶排序、计数排序、基数排序)

2.1 原理

就像是打扑克牌的摸牌过程,每从牌池里抽取一张牌,都会与手头已有的牌做比较,把它放在合适的位置。
在这里插入图片描述
描述:假设前n-1个元素已有序,现将第n个元素插入到前面已经排好的序列中,使得前n个元素有序,直到整个序列有序。一开始只能认为第一个元素是有序的,依次将其后面的元素插入到这个有序序列中来,直到整个序列有序为止。
在这里插入图片描述

2.2 Python、Java实现

python">def InsertSort(nums):  # 从小到大n = len(nums)for i in range(1, n):  # 外部插入排序,默认第一个数有序,从第二个数开始排序if nums[i] < nums[i-1]:  # 现在这个数小于前面的数时,才进入排序过程(就好像拿到了大王直接往后面一放,不需要进入手中的牌进行排序)temp = nums[i]  # 记录这个要插入的数p = i-1  # 从前面一个开始比较while nums[p] > temp and p >= 0:  # 指针指的数如果大于要插入的数,就往后挪一位nums[p+1] = nums[p]p -= 1nums[p+1] = temp  # 结束循环时,p指向小于temp的数return numsnums = [29, 10, 14, 37, 12, 6, 32]
print(InsertSort(nums))  # [6, 10, 12, 14, 29, 32, 37]
java">import java.util.Arrays;public class Main {public static void main(String[] args) {int[] nums = {29, 10, 14, 37, 12, 6, 32};InsertSort(nums);
//        System.out.println(nums);  // 这样会直接输出地址System.out.println(Arrays.toString(nums));  // 一开始想的是循环输出,这样后面的"]"前面还会有", "出现// [6, 10, 12, 14, 29, 32, 37]}public static void InsertSort(int[] nums){int n = nums.length;for (int i = 1; i < n; i++) {if (nums[i] < nums[i-1]){int temp = nums[i];int j;for (j = i-1; j >= 0 && nums[j] > temp; j--) {/*应该使用逻辑与符号 "&&" 而不是位与符号 "&"因为逻辑与符号会在第一个条件不成立时直接跳出循环,而位与符号会继续执行第二个条件,可能导致数组越界异常*/nums[j+1] = nums[j];}nums[j+1] = temp;}}}}

时间复杂度:O(n^2),最好是O(n)

插入排序是稳定的。 这一点在while nums[p] > temp可以看出。

3 选择排序

选择排序(详细图解分析+实现,小白一看就会)

3.1 原理

核心:多趟选择
内层循环中:
第一次在所有n个数里面找最小值,与第一个数交换;
第二次在后面n-1个数里面找最小值,与n-1个数里面的第一个数交换……
在这里插入图片描述

3.2 Python、Java实现

python">def SelectSort(nums):  # 从小到大n = len(nums)for i in range(n):  # 排序n轮min_num = nums[i]min_index = ifor j in range(i+1, n):if nums[j] < min_num:min_num = nums[j]min_index = jnums[i], nums[min_index] = nums[min_index], nums[i]return numsnums = [29, 10, 14, 37, 12, 6, 32]
print(SelectSort(nums))  # [6, 10, 12, 14, 29, 32, 37]
java">import java.util.Arrays;public class Main {public static void main(String[] args) {int[] nums = {29, 10, 14, 37, 12, 6, 32};SelectSort(nums);System.out.println(Arrays.toString(nums));  // [6, 10, 12, 14, 29, 32, 37]}public static void SelectSort(int[] nums){int n = nums.length;for (int i = 0; i < n; i++) {int min_num = nums[i];int min_index = i;for (int j = i+1; j < n; j++) {if (nums[j] < min_num){min_num = nums[j];min_index = j;}}int temp = nums[i];nums[i] = nums[min_index];nums[min_index] = temp;}}}

可以优化,设置成同时找最大值和最小值

时间复杂度:O(n^2)

选择排序是不稳定的。 因为发生了交换,如 3,3,2,2要和第一个3交换,则两个3就换了位置。

4 快速排序

排序算法】快速排序(全坤式超详解)———有这一篇就够啦

4.1 原理

分治思想:随机选一个pivot(一般是最左边或者最右边),然后比 pivot 小的放左边、大的放右边。
在这里插入图片描述

4.2 Python、Java实现

用递归很快:

python">def QuickSort(nums):  # 从小到大if len(nums) <= 1:return numselse:pivot = nums[0]left = [num for num in nums[1:] if num < pivot]right = [num for num in nums[1:] if num >= pivot]return QuickSort(left) + [pivot] + QuickSort(right)nums = [29, 10, 14, 37, 12, 6, 32]
print(QuickSort(nums))  # [6, 10, 12, 14, 29, 32, 37]

Java版本就不写了。
左右指针法之类的其实也用了递归,这里不写了。能搜到好多。

时间复杂度:O(nlogn),最坏情况是O(n^2)
不稳定。

5 归并排序

5.1 原理

同样是分治思想:
在这里插入图片描述

  1. 不断的分割数据,让数据的每一段都有序(一个数据相当于有序)
  2. 当所有子序列有序的时候,在把子序列归并,形成更大的子序列,最终整个数组有序。

核心:合并两个有序数组

在这里插入图片描述

5.2 Python、Java实现

python">def MergeSort(nums):  # 从小到大if len(nums) > 1:mid = len(nums) // 2  # 这里不能用 / 来除,会出现小数L = nums[:mid]R = nums[mid:]  # 递归到这里的时候,已经全部拆分成了长度为1的数组,也就是最底层# 递归MergeSort(L)MergeSort(R)# 到这一步的时候,其实就是开始从最底层处理,开始合并l = r = k = 0while l < len(L) and r < len(R):if L[l] <R[r]:nums[k] = L[l]l += 1else:nums[k] = R[r]r += 1k += 1# 左右数组长度可能不一样,所以还要检查是否还有剩余元素while l < len(L):  # 经过了上面,l按理来说应该正好等于len(L)了,如果还小于,说明有剩余的数nums[k] = L[l]l += 1k += 1while r < len(R):  # 经过了上面,l按理来说应该正好等于len(L)了,如果还小于,说明有剩余的数nums[k] = R[r]r += 1k += 1return numsnums = [29, 10, 14, 37, 12, 6, 32]
print(MergeSort(nums))  # [6, 10, 12, 14, 29, 32, 37]

Java版本就不写了。
左右指针法之类的其实也用了递归,这里不写了。能搜到好多。

时间复杂度:O(nlogn)
稳定。


http://www.ppmy.cn/news/1516760.html

相关文章

【十四届蓝桥杯省赛C++试卷】

一、选择题 第一题 C 中&#xff0c; bool 类型的变量占用字节数为&#xff08; &#xff09;。 A 、 1 B 、 2 C 、 3 D 、 4 答案&#xff1a;A 解析&#xff1a;&#xff08;C 中 bool 类型与 char 类型一样&#xff0c;都需要1 byte。一些其他类型的占用字节数&…

streeapptest 工具编译看 + 测试rk3568

首先来了解一下 stressappteset 网上的资料 压力测试不就是 内存的接口测试吗&#xff1f; 网上找了些资料&#xff0c;基本没有这个工具对于 磁盘网络的测试。 我的理解&#xff0c;压力测试应该指的就是 CPU内存的测试吧。 然后是 关于这个 软件的编译。 首先是下载 git c…

JavaScript(28)——正则表达式

定义正则表达式语法&#xff1a; const 变量名 /表达式/ 判断是否有符合规则的字符串&#xff1a; test()方法 用来查看正则表达式与指定的字符串是否匹配 语法&#xff1a; regObj.test(被检测的字符串) //返回布尔值 regObj.exec(字符串) //返回的是数组 <script>…

docker的部署及基本用法

目录​​​​​​​ 1 docker 介绍 1.1 什么是docker&#xff1f; 1.2 docker在企业中的应用场景 1.3 docker与虚拟化的对比 1.4 docker的优势 1.5 容器工作方式 2 部署docker 2.1 配置软件仓库 2.2 docker 安装 2.3 配置docker 镜像加速器 2.4 启动服务 2.5 激活内核网络选项…

每日刷力扣SQL题(五)

1164.指定日期的产品价格 一、方法&#xff1a;使用left join 和 ifnull 思路 本题的关键点在找到 2019-08-16 前所有有改动的产品及其最新价格和没有没有修改过价格的产品。 我们可以先找到所有的产品&#xff0c;再找到所有 2019-08-16 前有修改的产品和他们最新的价…

Vue3 pinia

1.简介 集中式状态&#xff08;数据&#xff09;管理 和vueX一样 2.安装pinia npm i pinia //引入 createApp用于创建应用 import {createApp} from vue; //引入 App 根组件 import App from ./App.vue;//引入pinia import {createPinia} from pinia;//创建一个应用 const…

PyTorch构建模型网络结构的6种方式

PyTorch提供了多种方式来构建模型的网络结构&#xff0c;我尝试总结一下&#xff0c;有如下6种常见方式&#xff08;可能还有我没注意到的&#xff0c;欢迎补充&#xff09;。我们平时写代码并不一定需要掌握全部方式&#xff0c;但是多了解一些&#xff0c;对于阅读理解别人的…

服务器主动推送的方法

目录 1.长轮询&#xff08;Long Polling&#xff09;2.WebSockets3.Server-Sent Events&#xff08;SSE&#xff09;4.HTTP2 Server Push 服务器如何主动推送数据 在传统的网络通信中&#xff0c;客户端&#xff08;如浏览器&#xff09;通常需要通过向服务器发起请求来获取数据…

快速判断一个项目是Spring MVC框架还是Spring Boot框架

1. 查看项目的启动类 Spring Boot: 通常有一个主类&#xff0c;包含 SpringBootApplication 注解&#xff0c;并且有一个 main 方法来启动应用程序。 SpringBootApplication public class Application {public static void main(String[] args) {SpringApplication.run(Appli…

作业训练三编程题13. 导弹防御系统

【问题描述】 某国为了防御敌国的导弹袭击&#xff0c;开发出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷&#xff1a;虽然它的第一发炮弹能够到达任意的高度&#xff0c;但是以后每一发炮弹都不能高于前一发的高度。某天&#xff0c;雷达捕捉到敌国的导弹来袭&#xf…

python脚本请求数量达到上限,http请求重试问题例子解析

在使用Python的requests库进行HTTP请求时&#xff0c;可能会遇到请求数量达到上限&#xff0c;导致Max retries exceeded with URL的错误。这通常发生在网络连接不稳定、服务器限制请求次数、或请求参数设置错误的情况下。以下是一些解决该问题的策略&#xff1a; 增加重试次数…

并发服务器开发基础

一、服务器模型 1. 单循环服务器&#xff1a; 单循环服务器在同一时刻只能处理一个客户端的请求。由于其结构简单&#xff0c;适合低负载的场景&#xff0c;但在并发请求增加时可能导致性能问题。 2. 并发服务器模型&#xff1a; 并发服务器可以同时响应多个客户端…

本地环境注入jupyter:无法在jupyter选择已经创建的conda环境?快来看下解决办法(jupyter notebook选择已创建环境)

1、WinR打开本机cmd命令行 2、运行 conda activate 本地已创建的环境名称 3、运行 conda install ipykernel 4、运行 python -m ipykernel install --user --name 本地环境名称 --display-name "在jupyter上显示的环境名称" 就可以在jupyter notebook中看到环…

谷粒商城实战笔记-250-商城业务-消息队列-RabbitMQ安装-Docker

一&#xff0c;docker安装RabbitMq RabbitMQ 是一个开源的消息代理软件&#xff0c;广泛用于实现异步通信和应用程序解耦。 使用 Docker 容器化技术可以简化 RabbitMQ 的安装和部署过程。 以下是使用 Docker 安装 RabbitMQ 的详细步骤。 步骤 1: 安装 Docker 如果您的系统…

如何解决:Failed to start jenkins.service: Unit not found.

当在 CentOS 上尝试启动 Jenkins 服务时&#xff0c;出现 Failed to start jenkins.service: Unit not found 的错误&#xff0c;这通常表示 Jenkins 服务未安装或未正确配置。请按照以下步骤进行排查和解决&#xff1a; 解决步骤 检查 Jenkins 是否已安装&#xff1a; 确认 J…

如何使用ssm实现旅游网站的设计与实现

TOC ssm150旅游网站的设计与实现jsp 绪论 1.1 研究背景 当前社会各行业领域竞争压力非常大&#xff0c;随着当前时代的信息化&#xff0c;科学化发展&#xff0c;让社会各行业领域都争相使用新的信息技术&#xff0c;对行业内的各种相关数据进行科学化&#xff0c;规范化管…

ComfyUI 常用的节点

总的来说&#xff0c;如果可以的话 最佳实践是直接访问每个节点仓库&#xff0c;仔细阅读作者提供的文档和说明。然后&#xff0c;手动执行 git clone 来获取仓库的代码。 接着&#xff0c;你可以通过手动执行 pip install -r requirements.txt 来安装每个项目的依赖。这种方法…

【Linux】第十八章 Reactor模式

文章目录 Reactor模式epoll ET服务器&#xff08;Reactor模式&#xff09;设计思路Epoller.hppSock.hppProtocol.hppService.hppTcpServer.hpp-重点Connection类TcpServer类服务器框架TcpServer构造AddConnection函数SetNonBlock 函数Accepter函数IsExists函数TcpRecver函数Tcp…

[oeasy]python031_[趣味拓展]unix起源_Ken_Tompson_Ritchie_multics

[趣味拓展]unix起源_Ken_Tompson_Ritchie_multics &#x1f94b; 回忆上次内容 上次 动态设置了 断点 断点 可以把代码 切成一段一段的可以 更快地调试 调试的目的 是 去除 bug 别害怕 bug 一步步 总能找到 bug这 就是 程序员基本功 调试 debug 在bug出现的时候 甚至…

docker-harbor私有仓库部署和管理

harbor&#xff1a;开源的企业级的docker仓库软件 仓库&#xff1a;私有仓库 公有仓库 &#xff08;公司内部一般都是私有仓库&#xff09; habor 是有图形化的&#xff0c;页面UI展示的一个工具&#xff0c;操作起来很直观。 harbor每个组件都是由容器构建的&#xff0c;所…