排序方法大汇总

以下所有排序方法均以排升序为例

一.插入排序

1.直接插入排序

1>方法介绍:假定前n个数据有序,将第n+1个数据依次与前n个数据相比,若比第i个数据小且比第i-1个数据大则插入两者之间

2>时间复杂度:O(N^2)

   空间复杂度:O(1)

   稳定性:稳定

3>代码实现:

//插入排序
void InsertSort(int* a, int n)
{//在前n个数据有效情况下,将第n+1个数据往前面插入,并保持有序for (int j = 1; j < n; j++){for (int i = j; i > 0; i--){if (a[i] < a[i - 1]){Swap(&a[i], &a[i - 1]);}}}
}

补:当数据量非常大时,直接插入排序的效率会大大降低,这时我们可以采用每次相差gap个数据进行插入排序,依次减小gap,直至gap==1,可以提高效率,这就是所谓的希尔排序

2.希尔排序

1>方法介绍:

1)预排序+直接插入排序

先选定一个gap,从第一个数据开始,按gap进行跳隔分组,对区间端点处的数据进行插入排序,依次向后进行gap间隔分组,直至遇到和第一次分组重合的元素;再减小gap的数值,重复上述操作,直至gap==1(最后依次相当于直接插入排序,不过此时数组已经接近有序,效率会大大提高)

2)对于gap的确定:大量实现表明,gap=gap/3+1最为合适,+1是为了保证最后一次gap==1

2>时间复杂度:O(N^1.3)   

   注:不同的书中对于希尔排序的时间复杂度描述不一样,读者记住该数值即可

   空间复杂度:O(1)

   稳定性:不稳定

3>代码实现:

void ShellSort(int* a, int n)
{int gap = n;while (gap > 1){//改变每次跳的间隔,不断精细化gap = gap / 3 + 1;//所有分组for (int j = 0; j < gap; j++){//仅针对一种划分方法for (int i = j; i < n - gap; i += gap){if (a[i] > a[i + gap]){Swap(&a[i], &a[i + gap]);}}}}
}

二.选择排序

1.选择排序

1>方法介绍:在每一次遍历数组时找出最大值和最小值,分别放在首尾,逐渐向中间逼近

2>时间复杂度:O(N^2)

   空间复杂度:O(1)

   稳定性:稳定

3>代码实现:

//选择排序
void SelectSort(int* a, int n)
{int begin = 0;int end = n - 1;while (begin <= end){int mini = begin;int maxi = begin;//寻找最大值,最小值的下标for (int i = begin+1; i <= end; i++){if (a[mini] > a[i]){mini = i;}if (a[maxi] < a[i]){maxi = i;}}Swap(&a[begin], &a[mini]);//防止出现begin处的值被使用两次的情况if (begin == maxi){maxi = mini;}Swap(&a[end], &a[maxi]);begin++;end--;}
}

2.堆排序

1>方法介绍:

1)利用数组中的数据建大堆,交换最后一个数据与第一个数据进行调整,使前n-1个数据仍为大堆,重复操作

2)利用数组中的数据建大堆的方法:利用向下调整法(具体可参考小编二叉树的顺序结构的博客),从非叶子节点的最后一个父节点开始向下调整

2>时间复杂度:O(N*logN)

   空间复杂度:O(1)

   稳定性:稳定

3>代码实现:

void AdjustDown(int* a,int size, int parent)
{int child = parent * 2 + 1;while (child < size){if ((child+1)<size && a[child] < a[child + 1]){child++;}if (a[parent] < a[child]){Swap(&a[parent], &a[child]);parent = child;child = parent * 2 + 1;}else{break;}}
}void HeapSort(int* a, int n)
{//建大堆for (int i = (n-1-1)/2; i >=0 ; i--){AdjustDown(a, n, i);}int end = n - 1;while (end>0){Swap(&a[0], &a[end]);AdjustDown(a, end, 0);end--;}
}

三.交换排序

1.冒泡排序

1>方法介绍:两两比较,将大数沉底,依次进行,直至有序

2>时间复杂度:O(N^2)

   空间复杂度:O(1)

   稳定性:稳定

3>代码实现:

void BubbleSort(int* a, int n)
{for (int j = 0; j < n; j++){int flag = 0;for (int i = 0; i < n - j-1; i++){if (a[i] > a[i + 1]){Swap(&a[i], &a[i + 1]);flag = 1;}}if (flag == 0){break;}}
}

2.快排序

1>方法介绍:

1)选定左边的数据为key,定义Left,Right两个下标,先让R先走,如果找到比key小的数据则停下来,再让L走,如果找到比key大的数据则停下来,交换这两个数据,再重复操作,直至L与R相遇,交换相遇位置的数据(一定比key小)和key。此时key左边的数据全部比key小,右边的数据全部比key大,对key左边和右边的两个数组再进行上述操作(递归实现),若数组中只有一个数据或L大于R则停下来

2)优化1:若数组为逆序排列,则只进行右侧的递归展开,若层数太多会导致栈溢出,为了避免逆序的情况,我们可以对key的取值做文章:要么随机取key,但随机性太大,pass;要么取左中右三者中居中的数据,与左边数据交换,仍让左边数据为key

3)优化2:当数组中的数据量过少时,利用递归排序的代价太大,此时我们可以选用其他方法来排这些数据,以提高性能

2>关于相遇位置的数据小于key的解释:

若最后是L遇R:由于R先走,并且R找到比key小的数据才停下来,故R停下来的位置处的数据小于key,此时L走一直未找到比key大的数据直至与R相遇,所以相遇位置的数据小于key

若最后是R遇L:由于R先走,在最后一次R走前,L找到比key大的数据,R找到比key小的数据,两者进行交换,故L所在位置的数据是比key小的数据,之后R向前走,一直为找不到比key大的数据,直至与L相遇,所以相遇位置的数据小于key

综上所述:相遇位置的数据必定小于key

3>时间复杂度:O(N*logN)

   空间复杂度:O(logN)

   稳定性:不稳定

4>代码实现:

int GetMidi(int* a,int left, int right)
{int mid = (right + left) / 2;if (a[left] < a[mid]){if (a[mid] < a[right]){return mid;}else if (a[right] < a[left]){return left;}else{return right;}}else{if (a[mid] > a[right]){return mid;}else if (a[right] > a[left]){return left;}else{return right;}}
}//当数组为逆序时,递归层次太多,可能造成栈溢出,导致性能低下
//解决方法:1.将key取头,尾,中间三者中居中的值(三数取中)
//          2.进行随机选取key(该法不确定性太大,不推荐)
//当数据太少用递归进行排序会浪费空间,故可以在最后10个数据排序时改用其他方法排序,以提高性能
void QuickSort(int* a, int left,int right)
{if (left >= right){return;}//小区间优化if ((right - left + 1 ) < 10){InsertSort(a+left, right - left + 1);}else{int midi = GetMidi(a, left, right);Swap(&a[midi], &a[left]);int keyi = left;int begin = left;int end = right;while (begin < end){//右边先走,找比key小的值while (begin < end && a[keyi] < a[end]){end--;}//左边后走,找比key大的值while (begin < end && a[keyi] > a[begin]){begin++;}//交换左右值Swap(&a[begin], &a[end]);}//将相遇位置的数据与key位置的数据交换Swap(&a[begin], &a[keyi]);QuickSort(a, left, keyi - 1);QuickSort(a, keyi + 1, right);}}

四.归并排序

1.方法介绍:

1)按后序遍历的思想将数组分成若干份左右小区间

2)将数组细分成若干小组,让他们在自己的小组内有序,然后再让它与相邻的组别有序,依次向上归并

3)开辟一个新数组用于盛放已排序的数据,在一次归并后需将tmp中的数据拷贝回原数组中,以保证下一组更大区间的数据归并时是有序的

2.时间复杂度:O(N*logN)

   空间复杂度:O(N)

   稳定性:稳定

3.代码实现:

void _MergeSort(int* a, int* tmp, int begin, int end)
{if (begin>=end)return;int midi = (begin + end) / 2;_MergeSort(a, tmp, begin, midi);_MergeSort(a, tmp, midi+1, end);//归并//[begin,mid],[mid+1,end]int begin1 = begin, end1 = midi;int begin2 = midi + 1, end2 = end;int i = 0;while (begin1 <= end1 && begin2 <= end2){if (a[begin1] < a[begin2]){tmp[i++] = a[begin1++];}else{tmp[i++] = a[begin2++];}}while (begin1 <= end1){tmp[i++] = a[begin1++];}while (begin2 <= end2){tmp[i++] = a[begin2++];}memcpy(a + begin, tmp + begin, sizeof(end - begin + 1));}void MergeSort(int* a, int n)
{int* tmp = (int*)malloc(sizeof(int) * n);if (tmp == NULL){perror("malloc fail");return;}_MergeSort(a, tmp, 0, n - 1);free(tmp);tmp = NULL;
}

注:对于快排和归并还有非递归的方法,考虑到篇幅,小编就不在这篇博客中介绍,如果有兴趣的小伙伴可以看看小编的下一篇博客了解以下哟

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

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

相关文章

BUUCTF中的密码题目解密

BUUCTF 1.MD5 题目名称就是MD5&#xff0c;这个题目肯定和md5密码有关&#xff0c;下载题目&#xff0c;打开后发现这确实是一个md5加密的密文 Md5在线解密网站&#xff1a;md5在线解密破解,md5解密加密 经过MD5在线解密网站解密后&#xff0c;获取到flag为&#xff1a;flag{…

网络编程TCP

White graces&#xff1a;个人主页 &#x1f649;专栏推荐:Java入门知识&#x1f649; &#x1f649; 内容推荐:Java网络编程(下)&#x1f649; &#x1f439;今日诗词: 壮士当唱大风哥, 宵小之徒能几何&#xff1f;&#x1f439; ⛳️点赞 ☀️收藏⭐️关注&#x1f4ac;卑微…

CentOS7单用户模式,救援模式操作记录

CentOS7单用户模式&#xff0c;救援模式操作记录 1. 单用户模式 单用户模式进入不需要密码&#xff0c;无网络连接&#xff0c;拥有root权限&#xff0c;禁止远程登陆。一般用于用于系统维护&#xff0c;例如忘记root密码后可以通过进入单用户模式进行重置。 开机启动&#…

数据结构 实验 1

题目一&#xff1a;用线性表实现文具店的货品管理问题 问题描述&#xff1a;在文具店的日常经营过程中&#xff0c;存在对各种文具的管理问题。当库存文具不足或缺货时&#xff0c;需要进货。日常销售时需要出库。当盘点货物时&#xff0c;需要查询货物信息。请根据这些要求编…

使用低代码系统的意义与价值主要体现在哪里?

使用低代码系统的意义与价值主要体现在以下几个方面&#xff0c;这些观点基于驰骋低代码设计者的专业洞察和行业经验&#xff1a; 快速原型创建&#xff1a; 低代码平台通过提供图形化界面和预构建的模块&#xff0c;极大地加速了系统原型的创建过程。这意味着企业能够更快地验…

60 关于 SegmentFault 的一些场景 (1)

前言 呵呵 此问题主要是来自于 帖子 月经结贴 -- 《Segmentation Fault in Linux》 这里主要也是 结合了作者的相关 case, 来做的一些 调试分享 当然 很多的情况还是 蛮有意思 本文主要问题如下 1. 访问可执行文件中的 只读数据 2. 访问不存在的虚拟地址 3. 访问内核地址…

嵌入式工程师人生提质的十大成长型思维分享

大家好,作为一名嵌入式开发者,很多时候,需要考虑个人未来的发展,人生旅途复杂多变,时常面临各种各样的挑战。如何在这个复杂多变的社会中稳步向前,不断成长,成为每个人都应该思考的问题。实际上,思维方式的差异决定我们应对挑战的能力与成长的速度。 第一:寻找自我坐…

HNCTF2022 REVERSE

[HNCTF 2022 WEEK2]esy_flower 简单花指令 Nop掉 然后整段u c p然后就反汇编 可能反编译的不太对&#xff0c;&#xff0c;看了别人的wp就是ida反编译的有问题 #include<stdio.h> #include<string.h> int main() {int i,j;char ch[]"c~scvdzKCEoDEZ[^roDICU…

微软远程连接工具:Microsoft Remote Desktop for Mac 中文版

Microsoft Remote Desktop 是一款由微软开发的远程桌面连接软件&#xff0c;它允许用户从远程地点连接到远程计算机或虚拟机&#xff0c;并在远程计算机上使用桌面应用程序和文件。 下载地址&#xff1a;https://www.macz.com/mac/5458.html?idOTI2NjQ5Jl8mMjcuMTg2LjEyNi4yMz…

C++进阶之AVL树+模拟实现

目录 目录 一、AVL树的基本概念 1.1 基本概念 二、AVL树的模拟实现 2.1 AVL树节点的定义 2.2 插入操作 2.3 旋转操作 2.4 具体实现 一、AVL树的基本概念 1.1 基本概念 二叉搜索树虽可以缩短查找的效率&#xff0c;但如果数据有序或接近有序二叉搜索树将退化为单支树&…

山东大学软件学院项目实训-创新实训-基于大模型的旅游平台(二十四)- 微服务(4)

目录 8. http客户端Feign 8.1 feign远程调用 8.2 feign自定义配置 8.3 feign性能优化 8.4 feign最佳实践 8. http客户端Feign 8.1 feign远程调用 RestTemplate存在的问题 &#xff1a; 代码可读性差 参数复杂URL难以维护 Feign是声明式的http客户端 使用步骤 &#xf…

飞书API(11):阿里云MaxCompute分区表入库

一、引入 前面入库阿里云 MaxCompute 的数据都是读取之后直接写入&#xff0c;保留数据最新的状态&#xff0c;如果我要保留历史的状态&#xff0c;怎么办呢&#xff1f;MaxCompute 表有一个分区功能&#xff0c;可以自行定义分区。我们可以使用 MaxCompute 表的分区功能&…

远程自动锁定平面

目录 Ubuntu 系统上 方法一&#xff1a;使用 SSH 重新连接 方法二&#xff1a;解锁当前会话 方法三&#xff1a;通过 SSH 解锁会话 方法四&#xff1a;禁用自动锁屏&#xff08;如果合适&#xff09; windows系统 方法三&#xff1a;修改组策略设置 Ubuntu 系统上 远程…

重生之我要精通JAVA--第七周笔记

文章目录 IO流字符流字符流原理解析flush和close方法 文件拷贝代码文件加密解密修改文件中的数据 缓冲流字节缓冲流字符缓冲流例题 转换流序列化流序列化流/对象操作输出流 反序列化流序列化流/反序列化流的细节汇总打印流字节打印流字符打印流 解压缩流压缩流Commons-io常见方…

网络空间安全数学基础·环

4.1 环与子环 &#xff08;理解&#xff09; 4.2 整环、除环、域 &#xff08;熟练&#xff09; 4.3 环的同态、理想 &#xff08;掌握&#xff09; 4.1 环与子环 定义&#xff1a;设R是一非空集合&#xff0c;在R上定义了加法和乘法两种代数运算&#xff0c; 分别记为ab和a…

java收徒、java面试辅导、java辅导、java就业辅导

&#x1f497;博主介绍&#xff1a;✌全网粉丝1W,CSDN作者、博客专家、全栈领域优质创作者&#xff0c;博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f31f;文末获取源码数据库&#x1f31f; 感兴趣的可以先收藏起来&#xff0c;还…

MMPose-RTMO推理详解及部署实现(下)

目录 前言一、RTMO推理(Python)1. RTMO预测2. RTMO预处理3. RTMO后处理4. RTMO推理 二、RTMO推理(C)1. ONNX导出2. RTMO预处理3. RTMO后处理4. RTMO推理 三、RTMO部署1. 源码下载2. 环境配置2.1 配置CMakeLists.txt2.2 配置Makefile 3. ONNX导出4. engine生成5. 源码修改6. 运行…

HCP;IDA;ABIDE(孤独症)磁共振数据库下载

ABIDE https://fcon_1000.projects.nitrc.org/indi/abide/abide_II.html 根据研究目的和研究目的选择不同站点的数据—不同站点的数据 HCP-IDE https://ida.loni.usc.edu/project_info.jsp 点击下载-图像集合 选择研究对象 全选-下载

边缘密度分布图 | ggExtra包/aplot拼图/ggpubr包 等的实现方法

概述&#xff1a;aplot 拼图效果好 根据网友探索[1]&#xff0c;总结如下&#xff1a; ggExtra 包的拼图间隙有点大&#xff0c;图例在主图和边缘图之间&#xff0c;除非去掉图例&#xff0c;否则没法看。aplot包的默认拼图间隙很小&#xff0c;比较美观&#xff0c;图例在外…

Cyber Weekly #9

赛博新闻 1、OpenAI&#xff1a;GPTs向全部用户开放&#xff0c;使用GPT-4o OpenAI宣布所有ChatGPT免费用户现在可以在GPT商店中使用GPTs&#xff0c;并且这些GPTs现在使用最新的GPT-4o模型。 2、马斯克 vs. Yann LeCun 这一周&#xff0c;AI圈最热闹的莫过于马斯克和LeCun的…