基本的五大排序算法
目录:
一,直接插入算法
二,希尔排序算法
三,选择排序
四,堆排序
五,冒泡排序算法
简介:
排序算法目前是我们最常用的算法之一,据研究表明,目前排序占用计算机CPU的时间已高达百分之30到百分之50。可见,高效率的排序算法是我们必须掌握的基本算法之一,本篇博客就先跟大家介绍五种常用的排序算法:直接插入算法,希尔算法,选择算法,堆排序算法,冒泡算法。
一,直接插入算法
直接插入算法的原理与我们打扑克牌时,进行不摸牌排序的效应一样。平常我们在打扑克牌时会不断的摸牌,每当我们摸到一个牌时就会往里面插入,使得我们手中的排有序。直接插入算法与之同理,其基本思想是把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列种,直到所有的记录插入完为止,得到一个新的有序序列,即摸牌效应,如下图,是插入排序的示意图:
明白以上原理后,接下来要思考的是此算法的效率如何,不难发现,当为最好情况时(即有序排列),将一次性直接遍历整个数组,时间复杂度为O(N);当为最坏情况是(即要跟排列的顺序相反),需要一直往首元素插入,此时的时间复杂度为O(N^2)。具体代码如下:
#include <stdio.h>
//直接插入算法
void InsertSort(int* a, int n) {for (int i = 0; i < n - 1; i++) {// [0,end]有序,把end+1位置的插入到前序序列,控制[0,end+1]有序int end = i;int next = a[i + 1];// 升序排列while (end >= 0) {if (a[end] > next) {a[end + 1] = a[end];}else {break;}end--;}a[end + 1] = next;}
}
int main() {int a[] = { 5,9,7,3,0,1,4,2,6,8 };InsertSort(a, sizeof(a) / sizeof(int));for (int i = 0; i < sizeof(a) / sizeof(int); i++) {fprintf(stdout, "%d ", a[i]);}puts("");return 0;
}
运行图:
二,希尔排序算法
希尔排序是以插入排序为基础的排序。首先,该算法要设置一个分组,然后再用直接插入算法的思想进行预排序,预排序是将数据分组排序,每组数据之间有着一定的间距。如下图:
上图中,第一组数据:9,5,8,5。第二组数据:1,7,6。第三组数据:2,4,3。三组数据先分别用直接插入算法进行预排序,排序后第一组数据为5,5,8,9。第二组数据为1,6,7。第三组数据为2,3,4。经过这些预排序后,整体的数据为5 1 2 5 6 3 8 7 4 9(不同颜色代表不同组中的数据,可直观的看出)。
其中,将数据进行预排序的目的是大的数据更快的到后面去,小的数据更快的到前面去,其中,间距越大跳得越快,越不接近有序;间距越小跳得越慢,越接近有序,当间距为1时,直接为有序,因为,当间距为1时就是直接插入排序。
希尔算法运用得原理就是给定一个间距值进行预排序,当间距值大于1时进行的排序为预排序,当间距值等于1时的排序就是直接插入排序,即排序已完成。本算法的效率很高,但时间复杂度很难计算出,暂时先不研究这个,代码实现具体如下:
#include <stdio.h>
//希尔排序算法
void ShellSort(int* a, int n) {int grab = n;//开始时,设置间距grab = n;//当grab == 1时为直接插入算法,当grab > 1时为预排序while (grab != 1) {//grab /= 2;//不断的缩减grab的大小,直到grab == 1排序完成//由于grab一次性的缩减比较小,导致算法效率较低,以下的grab为改进算法,提高算法效率grab = grab / 3 + 1;//不断缩减间距grab的大小,直到grab == 1排序完成//以下是根据间距grab的大小来进行的插入排序for (int j = 0; j < grab; j++) {for (int i = j; i < n - grab; i += grab) {int end = i;int x = a[i + grab];while (end >= 0) {if (a[end] > x) {a[end + grab] = a[end];}else {break;}end -= grab;}a[end + grab] = x;}}}
}
int main() {int a[] = { 5,9,7,3,0,1,4,2,6,8 };ShellSort(a, sizeof(a) / sizeof(int));for (int i = 0; i < sizeof(a) / sizeof(int); i++) {fprintf(stdout, "%d ", a[i]);}puts("");return 0;
}
运行图:
三,选择排序
1,选择排序的基本思想:
每一次从待排序的数据元素中选出最小或最大的一个元素,存放在系列的起始位置,即进行一趟选择,直到全部待排序的数据元素排完,其中时间复杂度:O(N^2)。空间复杂度:O(1)。如下图:
以上就是选择排序的基本套路,但我们仔细思考下来,其实这种方法还有优化空间,当数据进行一趟选择时,我们可直接选出最大数和最小数,将其放在开头或末尾。然后再次进行遍历,直到头尾遍历相遇为止。代码如下:
#include <stdio.h>
//选择算法
void Swap(int* x1, int* x2) {int t = *x1;*x1 = *x2;*x2 = t;
}
void SelectSort(int* a, int n) {int begin = 0, end = n - 1;while (begin < end) {int max = begin, min = begin;//进行一趟遍历,确定最小值和最大值的下标,当前面遍历等于end时排序就已排好for (size_t i = begin + 1; i < end; i++) {if (a[max] < a[i]) {max = i;}if (a[min] > a[i]) {min = i;}}Swap(a + max, a + end);//当min在最后时,max与原先的end交换了位置,所以这时的end的下标已经变了if (min == end) {min = max;}Swap(a + min, a + begin);//前面排好,往后前进begin++;//后面排好,往前前进end--;}
}
int main() {int a[] = { 5,9,7,3,0,1,4,2,6,8 };SelectSort(a, sizeof(a) / sizeof(int));for (int i = 0; i < sizeof(a) / sizeof(int); i++) {fprintf(stdout, "%d ", a[i]);}puts("");return 0;
}
运行图:
四,堆排序
堆排序跟二叉堆排序一模一样,即先建立堆结构,然后进行堆的调整,使整体有序。要注意的是,升序排列首选大堆,降序排列首选小堆建立。(这一原理运用的是二叉树的知识,如若感觉有困难,就必须先把二叉树的堆结构再学习下。不建议直接上来搞这一块知识)。其中结构上是选择堆结构上的选择排序,结构图如下:
由于原理与之前的二插堆一样,在这里就不做过多结构上的说明,下面是代码的实现和讲解:
#include <stdio.h>
void Swap(int* x1, int* x2) {int t = *x1;*x1 = *x2;*x2 = t;
}
//归并算法
void Adjustdown(int* a, int n, int parent) {int child = 2 * parent + 1;while (child < n) {if (child + 1 < n && a[child] < a[child + 1]) {child++;}if (a[child] > a[parent]) {Swap(a + child, a + parent);parent = child;child = parent * 2 + 1;}else {break;}}
}
//以升序为例,升序用建大堆思想
void HeapSort(int* a, int n) {//从最后一层走起,因为要保证导入的parent往下都是有序的,即大堆建立for (int i = (n - 1 - 1) / 2; i >= 0; i--) {Adjustdown(a, n, i);}//大堆建立后根为最大数,然后进行排序int end = n - 1;while (end > 0) {Swap(a, a + end);//因为根为最大数,要升序就要把最大数放入最后Adjustdown(a, end, 0);end--;}
}
int main() {//归并算法int a[] = { 5,9,7,3,0,1,4,2,6,8 };HeapSort(a, sizeof(a) / sizeof(int));for (int i = 0; i < sizeof(a) / sizeof(int); i++) {fprintf(stdout, "%d ", a[i]);}puts("");return 0;
}
运行图:
五,冒泡排序算法
冒泡排序是一种交换排序,所谓交换,就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置,此种交换的特点是将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动,其中时间复杂度:O(N^2);空间复杂度:O(1)。
冒泡排序的原理图:
此种排序非常简单,具体代码如下:
#include <stdio.h>
void Swap(int* x1, int* x2) {int t = *x1;*x1 = *x2;*x2 = t;
}
//冒泡排序算法
void BubbleSort(int* a, int n)
{for (size_t j = 0; j < n; j++){//用x进行控制,可提升算法的效率int x = 0;for (size_t i = 1; i < n - j; i++){//进行排序,当没有进入此步时,说明是有序的if (a[i - 1] > a[i]){Swap(&a[i - 1], &a[i]);x = 1;}}//当x == 0时,说明序列是有序的,可直接跳出,提升算法的效率if (x == 0){break;}}
}
int main() {//冒泡算法int a[] = { 5,9,7,3,0,1,4,2,6,8 };BubbleSort(a, sizeof(a) / sizeof(int));for (int i = 0; i < sizeof(a) / sizeof(int); i++) {fprintf(stdout, "%d ", a[i]);}puts("");return 0;
}
运行图:
总:在五种排序算法中,效率最高的是希尔排序,效率最低的是冒泡排序,堆排序与希尔不相上下,但堆排序实现起来比较麻烦,因此个人建议首选希尔,直接插入算法比选择排序算法和冒泡略高一筹,但在进行大量数据排序时,效率都不高,因此,在五大基本排序中,希尔排序为最佳选择。
相关文章:
基本的五大排序算法
目录: 一,直接插入算法 二,希尔排序算法 三,选择排序 四,堆排序 五,冒泡排序算法 简介: 排序算法目前是我们最常用的算法之一,据研究表明,目前排序占用计算机CPU的时…...
封装api的理解
1.基地址(baseUrl) (1).测试环境 用于测试环境的运行 (2).正式环境 用于正式环境的运行 2.拦截器 1.请求拦截器 (1)成功的回调 做的事情:例如在请求头header里面加入toekn。 (2)失败的回调 直接返回失败的结果: return promise.reject(error) 2.响应拦截器 (1)成功的回…...
Unity实现设计模式——命令模式
Unity实现设计模式——命令模式 推荐一个Unity学习设计模式很好的GitHub地址:https://github.com/QianMo/Unity-Design-Pattern 有非常多的Star 一、介绍 命令模式使得请求的发送者与请求的执行者之间消除耦合,让对象之间的调用关系更加灵活。在命令模…...
四、YApi的安装和配置
YApi是去哪儿网的前端技术中心的一个开源可视化接口管理平台。 创建接口项目 创建接口 编写接口...
JAVA学习(2)-全网最详细~
🌈write in front🌈 🧸大家好,我是Aileen🧸.希望你看完之后,能对你有所帮助,不足请指正!共同学习交流. 🆔本文由Aileen_0v0🧸 原创 CSDN首发🐒 如…...
MySQL学习笔记27
MySQL主从复制的核心思路: 1、slave必须安装相同版本的mysql数据库软件。 2、master端必须开启二进制日志,slave端必须开启relay log 日志。 3、master主服务器和slave从服务器的server-id号不能一致。 4、slave端配置向master端来同步数据。 master…...
数据结构与算法之字典: Leetcode 76. 最小覆盖子串 (Typescript版)
最小覆盖子串 https://leetcode.cn/problems/minimum-window-substring/description/ 描述 给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 “” 。注意: 对于 t 中重…...
2023-10-03 VsCode诡异消失事件
VsCode诡异消失事件 前言一、排查问题二、原因分析三、其它可能不好的倾向总结 前言 今天打开电脑, 习惯性的打开VsCode, 收到错误消息, 该快捷方式所指向的项目Code.exe已经更改或移动, 因此该快捷方式无法正常工作. 是否删除该快捷方式. 一、排查问题 打开快捷方式指向的位…...
elementPlus表格组件el-table实现只能同时选择一行,全选按第一行处理
目录 需求背景: 具体实现: 模板代码: 函数处理代码: 代码讲解: 需求背景: 点击表格最左侧的复选框列,选中当前表格行,而且只允许选择一行,选中一行后,其…...
栈的应用场景(三)
最小栈 1.题目2.画图分析3.代码实现 1.题目 2.画图分析 3.代码实现 package Stack;import java.util.Stack; public class MinStack {private Stack <Integer> stack;private Stack <Integer> MinStack;public MinStack() {stack new Stack<>();MinStack …...
leetCode 45.跳跃游戏 II 贪心算法
45. 跳跃游戏 II - 力扣(LeetCode) 给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说,如果你在 nums[i] 处,你可以跳转到任意 nums[i j] 处: 0 &…...
【MATLAB-基于直方图优化的图像去雾技术】
【MATLAB-基于直方图优化的图像去雾技术】 1 直方图均衡2 程序实现3 局部直方图处理 1 直方图均衡 直方图是图像的一种统计表达形式。对于一幅灰度图像来说,其灰度统计直方图可以反映该图像中不同灰度级出现的统计情况。一般而言,图像的视觉效果和其直方…...
读书笔记|《数据压缩入门》—— 柯尔特·麦克安利斯 亚历克斯·海奇
前言:在接触文本隐写研究领域时了解到这本书。本书可算作《数据压缩》的入门书籍之一,这本书对熵编码、变长编码、统计编码、自适应统计编码、字典编码、上下文编码等常用编码方式的定义及来源进行介绍,对不同场景下不同格式的压缩数据有针对…...
Pandas进阶修炼120题-第五期(一些补充,101-120题)
目录 往期内容:第一期:Pandas基础(1-20题)第二期:Pandas数据处理(21-50题)第三期:Pandas金融数据处理(51-80题)第四期:当Pandas遇上NumPy…...
NPDP产品经理知识(产品创新管理)
复习文化,团队与领导力 产品创新管理: 如何树立愿景: 如何实现产品战略 计划 实施产品开发: 商业化,营销计划,推广活动 管理产品生命周期: 新式走向市场的流程:...
Flutter+SpringBoot实现ChatGPT流实输出
FlutterSpringBoot实现ChatGPT流式输出、上下文了连续对话 最终实现Flutter的流式输出上下文连续对话。 这里就是提供一个简单版的工具类和使用案例,此处页面仅参考。 服务端 这里直接封装提供工具类,修改自己的apiKey即可使用,支持连续…...
淘宝天猫粉丝福利购店铺优惠券去哪里找到领取网站?
淘宝天猫优惠券去哪里找到领取网站? 领取淘宝天猫粉丝福利购优惠券可通过百度搜索:草柴,进入草柴官方网站 或 手机应用商店搜索:草柴,下载安装草柴APP,就可以领取淘宝天猫优惠券; 草柴APP如何领…...
【考研复习】union有关的输出问题
文章目录 遇到的问题正确解答拓展参考文章 遇到的问题 首次遇到下面的代码时,感觉应该输出65,323。深入理解union的存储之后发现正确答案是:67,323. union {char c;int i; } u; int main(){u.c A;u.i 0x143;printf("%d,%d\n", u.c, u.i); …...
Android学习之路(16) Android 数据库Litepal
一.LitePal的介绍 Litepal是Android郭霖大神的一个开源Android数据库的开源框架,它采用了对象关系映射(ORM)的模式,这是让我们非常好的理解的数据库,一个实体类对应我们数据库中的一个表。该库中还封装了许多的方法&a…...
Redis持久化(RDB/AOF)
"在哪里走散,你都会 找 到 我。" 认识持久化 我们在接触Mysql事务的时候,一定了解过Mysql事务的四个特性: "原子性(A)一致性(C)隔离性(I)持久性(D)" 而其中持久性其实与持久化是一回事,所谓持久与不持久&#x…...
小谈设计模式(15)—观察者模式
小谈设计模式(15)—观察者模式 专栏介绍专栏地址专栏介绍 观察者模式核心思想主要角色Subject(被观察者)ConcreteSubject(具体被观察者)Observer(观察者)ConcreteObserver࿰…...
简单工厂模式 创建型模式(非GoF经典设计模式)
简单工厂模式是属于创建型模式,也因为工厂中的方法一般设置为静态,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工…...
PE文件之导入表
1. 导入表 2. 显示导入表信息的例子 ; 作用: 将RVA地址转成FOA即文件偏移 ; 参数: _pFileHdr 指向读到内存中文件的基址指针 ; _dwRVA 目标RVA地址 ; 返回: 目标RVA转成文件偏移的值 RVA2FOA PROC USES esi edi edx, _pFileHdr:PTR BYTE, _dwRVA:DWORDmov esi, _pFil…...
二、码制及其转换
原码 根据我们所学可知,数字电路的逻辑电路是通过输出0和1来表示二进制数的,那么这个二进制数的正负又该怎么表示呢? 答案是在这个二进制数的最高位作为符号位来表示正负性,用0正数,用1表示负数,在这种表达…...
在pycharm中出现下载软件包失败的解决方法
一. 一般情况下我们会选择在设置中下载软件包,过程如下. 1. 直接点击左上角的文件, 再点击设置, 再点击项目, 在右边选择python解释器,点击号,输入要下载的软件包, 在下面的一系列的包中选择相对应的包,点击安装就可以了,有的时候我们下载的是最新的版本,如果要下载固定的版本…...
10.0 探索API调试事件原理
本章笔者将通过Windows平台下自带的调试API接口实现对特定进程的动态转存功能,首先简单介绍一下关于调试事件的相关信息,调试事件的建立需要依赖于DEBUG_EVENT这个特有的数据结构,该结构用于向调试器报告调试事件。当一个程序发生异常事件或者…...
文心一言 VS 讯飞星火 VS chatgpt (104)-- 算法导论10.1 2题
二、用go语言,说明如何在一个数组 A[1…n]中实现两个栈,使得当两个栈的元素个数之和不为 n 时,两者都不会发生上溢。要求 PUSH 和 POP 操作的运行时间为 O(1)。 文心一言: 在这个问题中,我们要在一个数组 A[1…n] 中…...
检测防火墙是否开启、判断程序是否加入防火墙白名单(附源码)
VC常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)https://blog.csdn.net/chenlycly/article/details/124272585C软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...&a…...
vtk 动画入门 1 代码
实现效果如图: #include <vtkAutoInit.h> //VTK_MODULE_INIT(vtkRenderingOpenGL2); //VTK_MODULE_INIT(vtkInteractionStyle); VTK_MODULE_INIT(vtkRenderingOpenGL2); VTK_MODULE_INIT(vtkInteractionStyle); //VTK_MODULE_INIT(vtkRenderingFreeType); #in…...
【VR】【unity】如何在VR中实现远程投屏功能?
【背景】 目前主流的VD应用,用于娱乐很棒,但是用于工作还是无法效率地操作键鼠。用虚拟键盘工作则显然是不现实的。为了让自己的头显能够起到小面积代替多显示屏的作用,自己动手开发投屏VR应用。 【思路】 先实现C#的投屏应用。研究如何将C#投屏应用用Unity 3D项目转写。…...
怎样做网站建设方案/网络销售员每天做什么
基于 转载于:https://www.cnblogs.com/qcjd/p/9324863.html...
xampp怎么做网站/免费企业网站建设
小程序日历 日历 源码见https://github.com/treadpit/wx_calendar <p class"tip">日历模板面板支持手势左右滑动</p> 提供 template 模板引入 1. 引入wxml及wxss // example.wxml <import src"../../template/calendar/index.wxml"/> …...
wordpress外联插件/太原seo推广
亲爱的BCGSoft用户,我们非常高兴地宣布BCGControlBar Professional for MFC和BCGSuite for MFC v31.0正式发布!全新的CBCGPMultiViewFrameWnd类(实现多视图单文档界面)、新增主题CBCGPNumericIndicatorImpl、在高DPI模式下改进的功…...
农安县建设局官方网站/开发一个app软件多少钱
决策树算法ID3和C4.5实现鸾尾花分类预测ID3和C4.5算法原理简单介绍1、这两个算法差别不是特别大,一个是用信息增益来判断,一个是用信息增益率来判断,在sklearn库中指定 criterion“entropy” 即可,只是准确度不一样。2、这两个算法…...
四川住房和城乡建设九大员网站/宁德市人社局
小学语文“三学小组”模式口语交际课型教学流程及基本要求一、教学流程小学语文口语交际课“三学小组”模式,即每一个口语交际的学习有三个阶段:预学、互学、评学。预学有“了解话题、体验情境”两个学习环节;互学有“研究话题、展示交际”两…...
怎样做海外淘宝网站/武汉网站营销seo方案
计算机硬件系统实验报告PAGEPAGE 1计算机硬件系统实验报告RISC模型微处理器设计学 号:姓 名: 陆 二 庆指导教师: 陈智勇 老师专 业: 计算机应用技术日期:2006-10-171 实验题目设计一台RISC模型机…...