常见的几种算法排序(C#)

总结下常见的几种排序及其实现,帮助自己加深记忆。

一、冒泡排序

1、原理: 通过依次比较相邻的元素,将较大(或较小)的元素交换到右侧,直到整个序列有序。

 public static int[] BuddleSort(int[] arry){ int n= arry.Length;for (int i = 0; i < n; i++){for (int j = 0; j < n - 1 - i; j++){if (arry[j] < arry[j + 1]){ int temp = arry[j];arry[j] = arry[j + 1];arry[j + 1]= temp;}}}return arry;}

2、算法步骤:
冒泡排序的基本步骤:
(1)遍历数组: 从第一个元素开始,依次比较相邻的两个元素。
(2)比较相邻元素: 比较当前元素和下一个元素的大小关系。
(3)交换位置: 如果当前元素大于下一个元素(升序排序),则交换它们的位置,否则不做任何操作。
(4)遍历次数: 完成一轮遍历后,最大(或最小)的元素就会沉到数组的最后一个位置。
(5)重复步骤: 重复执行以上步骤,直到数组中的所有元素都已经排序完成。

3、举例:
冒泡排序的每个步骤涉及多次比较和可能的交换操作。这里是对数组 [65, 24, 12, 32, 4, 15] 进行冒泡排序时的每个步骤的输出:
初始数组:[65, 24, 12, 32, 4, 15]
第1次内循环执行后:[24, 12, 32, 4, 15, 65]
第2次内循环执行后:[12, 24, 4, 15, 32, 65]
第3次内循环执行后:[12, 4, 15, 24, 32, 65]
第4次内循环执行后:[4, 12, 15, 24, 32, 65]
第5次内循环执行后:[4, 12, 15, 24, 32, 65]
因此,经过选择排序算法的执行后,数组变为 [4, 12, 15, 24, 32, 65]。
4、时间复杂度
冒泡排序的时间复杂度为 O(n^2)。

二、选择排序

1、原理: 每次从未排序的部分选择最小(或最大)的元素,放到已排序部分的末尾,直到整个序列有序。

public static int[] SelectSort(int[] arry){int n = arry.Length;int temp;for (int i = 0; i < n - 1; i++){int minIndex = i;for (int j = i+1; j < n - 1 ; j++){if(arry[j]<arry[minIndex])minIndex = j;                     }temp = arry[i];arry[i] = arry[minIndex];arry[minIndex] = temp;}return arry;}

2、算法步骤:
首先,找到数组中最小的元素,并将其与数组的第一个元素交换位置。
接下来,在剩余的未排序部分中找到最小的元素,并将其与数组的第二个元素交换位置。
以此类推,直到所有元素都被排序。

3、举例

比如我有个数组[65, 24, 12, 32, 4, 15],使用选择排序每次内循环执行后的输出内容如下:
初始状态:[65, 24, 12, 32, 4, 15]
第1次内循环执行后:[4, 24, 12, 32, 65, 15]
第2次内循环执行后:[4, 12, 24, 32, 65, 15]
第3次内循环执行后:[4, 12, 15, 32, 65, 24]
第4次内循环执行后:[4, 12, 15, 24, 65, 32]
第5次内循环执行后:[4, 12, 15, 24, 32, 65]
因此,经过选择排序算法的执行后,数组变为 [4, 12, 15, 24, 32, 65]。

4、时间复杂度
选择排序的时间复杂度为 O(n^2)。

三、插入排序

1、原理: 将数组分为已排序和未排序两部分,每次从未排序部分取出一个元素,插入到已排序部分的合适位置。
方法一:

 public static int[] InsertSort(int[] arry){int n=arry.Length;for (int i = 1; i < n; i++){int key = arry[i];int j = i - 1;while (j >= 0 && key > arry[j]) {arry[j+1]=arry[j];j--;}arry[j+ 1] = key;}return arry;}

插入排序方法二,我把方法一中内循环结束把key赋值的地方修改到内循环中了,感觉这种更好理解,类似于交换数据,但可能效率没有方法一好。

 public static int[] InsertSort2(int[] arry){int n = arry.Length;for (int i = 1; i < n; i++){int key = arry[i];int j = i - 1;while (j >= 0 && key > arry[j]){arry[j+1] = arry[j];arry[j]= key;j--;}}return arry;}

2、算法步骤:
(1)从第一个元素开始,将该元素视为已排序部分。
(2)取出下一个元素,在已排序部分从后往前扫描。
(3)如果已排序部分的元素大于新元素,将该元素向右移动一个位置。
(4)重复步骤3,直到找到已排序部分的元素小于或等于新元素的位置。
(5)将新元素插入到找到的位置。
(6)重复步骤2到步骤5,直到所有元素都被插入到已排序部分。

3、举例

比如我有个数组[65, 24, 12, 32, 4, 15],使用插入排序每次内循环执行后的输出内容如下:
初始序列:[65, 24, 12, 32, 4, 15]
第一次循环后:[24, 65, 12, 32, 4, 15]
第二次循环后:[12, 24, 65, 32, 4, 15]
第三次循环后:[12, 24, 32, 65, 4, 15]
第四次循环后:[4, 12, 24, 32, 65, 15]
第五次循环后:[4, 12, 15, 24, 32, 65]
最终排序完成的序列为:[4, 12, 15, 24, 32, 65]

四、快速排序

1、原理
选择一个基准元素,将数组分成两部分,左边的部分小于基准,右边的部分大于基准,然后对左右两部分递归进行排序,直到整个数组有序。

public static int[] QuickSort(int[] arry,int low, int high){if (low < high){ int pivot =Partition(arry,low,high);QuickSort(arry,low,pivot-1);QuickSort(arry, pivot+1, high);}return arry;}public static int Partition(int[] arry, int low, int high){int pivot = arry[low]; // 将第一个元素作为基准元素while (low < high){// 从右向左找到一个小于基准元素的值while (low < high && arry[high] >= pivot){high--;}// 将这个小于基准元素的值放到左侧arry[low] = arry[high];// 从左向右找到一个大于基准元素的值while (low < high && arry[low] <= pivot){low++;}// 将这个大于基准元素的值放到右侧arry[high] = arry[low];}// 将基准元素放到正确的位置上arry[low] = pivot;// 返回基准元素的索引return low;}

2、算法步骤:
(1)选择基准元素: 从数组中选择一个基准元素,通常是数组的第一个元素、最后一个元素或者中间的元素。
(2)分区操作: 将数组中的元素按照基准元素的大小分成两部分,小于基准元素的放在基准元素的左边,大于基准元素的放在右边。分区操作完成后,基准元素的位置就确定了。
Partition函数中的While循环解释如下:选择arry[0]作为基准元素。

  • 双指针移动: 使用两个指针分别指向数组的起始位置和结束位置。左指针从左向右移动,直到找到一个大于或等于基准元素的值;右指针从右向左移动,直到找到一个小于或等于基准元素的值。
  • 交换元素: 一旦找到了左侧大于基准元素和右侧小于基准元素的值对,就交换它们的位置。这样,就保证了左侧的元素都小于等于基准元素,右侧的元素都大于等于基准元素。
  • 重复操作: 继续移动双指针,直到它们相遇为止。此时,所有小于基准元素的值都在基准元素的左侧,所有大于基准元素的值都在基准元素的右侧。
  • 基准元素归位: 将基准元素放置在正确的位置上,一般是与相遇点进行交换。
    (3)递归排序: 递归地对基准元素左右两边的子数组进行快速排序,直到子数组的大小为 0 或 1,即已经有序。
    (4)合并结果: 当所有的子数组都有序时,整个数组也就有序了。
    说明:网上有很多视频可以很好的解释这个算法的排序规则,可以在B站搜索看下。

3、时间复杂度
快速排序的平均时间复杂度是O(nlogn),但是在实际排序中,时间复杂度和基准元素(枢轴)的选择有关。如果枢轴选取不好,那么快速排序有可能就会退化为冒泡排序,时间复杂度为O(n*n)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/673219.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

32USART串口

目录 一.通信接口 二.时序 三.USART简介 ​编辑四.数据帧 五.起始位侦测和采样位置对齐 &波特率计算 六.相关函数 七.编码格式设置 &#xff08;1&#xff09; UTF-8编码&#xff08;有的软件兼容性不好&#xff09;​编辑 &#xff08;2&#xff09;GB2312编码 八.…

【python数据分析基础】—dataframe中index的相关操作(添加、修改index的列名、修改index索引值等)

文章目录 前言一、添加、修改index的列名二、修改index索引值 前言 本文主要讲dataframe结构中index的相关操作&#xff0c;index相当于是数据表的行。 一、添加、修改index的列名 新建一个dataframe表&#xff0c;我们可以自定义index的值&#xff0c;如下&#xff1a; imp…

SSL协议是什么?关于SSL和TLS的常见问题解答

SSL&#xff08;安全套接字层&#xff09;及其后继者TLS&#xff08;传输层安全&#xff09;是用于在联网计算机之间建立经过身份验证和加密的链接的协议。尽管SSL协议在 1999年已经随着TLS 1.0的发布而被弃用&#xff0c;但我们仍将这些相关技术称为“SSL”或“SSL/TLS”。那么…

Verilog代码优化技巧

Verilog代码优化技巧&#xff1a; 1. 条件b为TRUE时&#xff0c;将c赋值给a; always(posedge fclk or negedge frstn)if(!frstn)a < 0;else if(b)a < c;elsea < a;&#x1f3bf;时序逻辑里&#xff0c;后面的else如果不写的话&#xff0c;综合时会自动插入门控时钟。…

Integer的使用

在Java中&#xff0c;Integer 是一个包装类&#xff0c;用于将基本数据类型 int 包装为一个对象。这个类提供了许多方法来操作和处理整数数据。下面是对 Integer 类的一些重要的概念和功能的详细介绍&#xff1a; 装箱和拆箱&#xff1a;Integer 类允许将 int 基本数据类型转换…

Instagram SEO如何优化?10个技巧

Instagram SEO 是优化 Instagram 内容以使其在平台搜索结果中被发现的做法。如果你希望你可以更快的让你的Ins获得流量&#xff0c;做好SEO就成功了一半。Instagram 搜索结果包括相关内容、帐户、音频、主题标签和地点&#xff0c;下面为你总结10个策略技巧&#xff01; 一、In…

解析spritf和sscanf与模拟常用字符串函数strchr,strtok(二)

今天又来继续我们的字符串函数的文章&#xff0c;这也是最后一篇了。希望这两篇文章能让各位理解透字符串函数。 目录 strchr strtok sprintf和sscanf strchr strchr 是一个用于在字符串中查找特定字符首次出现位置的函数。以下是解析和模拟实现 strchr 函数的示例&…

UI自动化之Poco常用断言方式

实际上用到的几种写断言的方式&#xff1a; 1.验证UI界面&#xff08;断言图片是否存在&#xff0c;UI页面不稳定情况下&#xff0c;图片识别效率不高&#xff09; assert_exists assert_not_exists 2.验证数值&#xff08;断言传入的两个值(数字或者string)是否相等&#xff…

【Linux】信号-下

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;折纸花满衣 &#x1f3e0;个人专栏&#xff1a;题目解析 &#x1f30e;推荐文章&#xff1a;【LeetCode】winter vacation training 目录 &#x1f449;&#x1f3fb;信号递达&#xff0c;信号未决&#x…

WebGPU Inter-stage 变量

1. webgpu Inter-stage 变量 Inter-stage变量在顶点着色器和片段着色器之间发挥作用。 这里我们声明了一个结构体 struct&#xff0c;这是在顶点着色器和片段着色器之间增加 Inter-stage 变量的一种简便方法。 struct OurVertexShaderOutput {builtin(position) position : …

vue3学习——自定义插件,注册组件(引入vue文件报红线)

在src/components文件夹目录下创建一个index.ts文件 import { App, Component } from Vue import SvgIcon from /components/SvgIcon/index.vue import Pagination from /components/Pagination/index.vue const globalComponents: { [name: string]: Component } { SvgIcon,…

第三模块 面向对象网络并发编程

第三模块 面向对象&网络&并发编程 面向对象基础1. 初识面向对象1.1 对象和self1.2 常见成员1.3 应用示例 2. 三大特性2.1 封装2.2 继承练习题2.3 多态 3. 扩展&#xff1a;再看数据类型总结作业 从今天开始&#xff0c;我们将进入系列课程第3个模块的的学习&#xff0c…

TCP和UDP相关问题(重点)(5)——5.TCP三次握手和四次挥手(非常重要)

5.1三次握手的过程 一次握手&#xff1a;客户端发送带有SYN(x)标志的数据包到服务端&#xff0c;然后客户端进入SYN_SEND状态&#xff0c;等待服务器端的确认。 二次握手&#xff1a;服务端发送带有SYN(y)ACK(x1)标志的数据包到客户端&#xff0c;然后服务端进入SYN_RECV状态。…

Java设计模式大全:23种常见的设计模式详解(三)

本系列文章简介&#xff1a; 设计模式是在软件开发过程中&#xff0c;经过实践和总结得到的一套解决特定问题的可复用的模板。它是一种在特定情境中经过验证的经验和技巧的集合&#xff0c;可以帮助开发人员设计出高效、可维护、可扩展和可复用的软件系统。设计模式提供了一种在…

收到微信发的年终奖。。。

大家好&#xff0c;我是小悟 还剩一天就过除夕了&#xff0c;很多单位都已经放假了&#xff0c;街上的人越来越少&#xff0c;门店关着的很多&#xff0c;说明大家都陆陆续续回自己的家乡过年了。 或许你还在搬砖&#xff0c;坚守节前最后一波工作&#xff0c;或许你正在回家的…

Java学习16-- 面向对象学习45. 面向对象三大特征抽象类和接口

面向对象学习4. 面向对象三大特征 1封装&#xff1a;高内聚(内部细节自己用&#xff0c;外部不能介入)&#xff0c;低耦合(保留很少接口给外部使用)&#xff0c;信息隐藏&#xff08;禁止外界直接访问内部数据(private)&#xff0c;如需要&#xff0c;可通过get/set接口访问&a…

docker初级问题一

一、什么是Docker&#xff0c;以及它的主要用途是什么&#xff1f; Docker是一个开源的应用容器引擎&#xff0c;它基于Go语言开发&#xff0c;并遵循Apache 2.0协议。Docker让开发者能够打包他们的应用以及依赖包到一个可移植的容器中&#xff0c;然后发布到任何流行的Linux机…

【评论送书】AIGC重塑教育:AI大模型驱动的教育变革与实践

作者&#xff1a;刘文勇 来源&#xff1a;IT阅读排行榜 本文摘编自《AIGC重塑教育&#xff1a;AI大模型驱动的教育变革与实践》&#xff0c;机械工业出版社出版 这次&#xff0c;狼真的来了。 AI正迅猛地改变着我们的生活。根据高盛发布的一份报告&#xff0c;AI有可能取代…

第九个知识点:内部对象

Date对象: <script>var date new Date();date.getFullYear();//年date.getMonth();//月date.getDate();//日date.getDay();//星期几date.getHours();//时date.getMinutes();//分date.getSeconds();//秒date.getTime();//获取时间戳&#xff0c;时间戳时全球统一&#x…

Qt 常用算法及正则表达式

目录 常用算法 正则表达式 常用算法 double c qAbs(a)&#xff0c;函数 qAbs() 返回 double 型数值 a 的绝对值 double max qMax(b,c)&#xff0c;函数 qMax() 返回两个数值中的最大值 int bnqRound(b)&#xff0c;返回一个与浮点数最接近的整数值(四舍五入) int cn q…