常见的七大排序

目录

前言

冒泡排序

选择排序

插入排序

堆排序

希尔排序

快排

归并排序


前言

本文介绍七种常见的排序方式:冒泡排序,选择排序,插入排序,堆排序,希尔排序,快排,归并排序

冒泡排序

将每2个相邻的数依次进行前后对比,如果前大于后则还位,一轮后最大的将排到最后面

再将长度减1重复进行就可以得到有序的数据了

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

空间复杂度:O(1)

代码展示

void maopao(int arr[], int sz)
{int i = 0;for (i = 0; i < sz - 1; i++){int j = 0;for (j = 0; j < sz-1-i; j++){if (arr[j] > arr[j + 1]){int tmp = arr[j+1];arr[j + 1] = arr[j];arr[j] = tmp;}}}
}

选择排序

从数组中选择最小元素,将它与数组的第一个元素交换位置。再从数组剩下的元素中选择出最小的元素,将它与数组的第二个元素交换位置。不断进行这样的操作,直到将整个数组排序。

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

空间复杂度:O(1)

代码展示

void Swap(int* p1, int* p2)
{int tmp = *p1;*p1 = *p2;*p2 = tmp;
}
void SelectSort(int* a, int n)
{int begin = 0, end = n - 1;while (begin < end){int mini = begin, maxi = begin;for (int i = begin + 1; i <= end; ++i){if (a[i] > a[maxi]){maxi = i;}if (a[i] < a[mini]){mini = i;}}Swap(&a[begin], &a[mini]);Swap(&a[end], &a[maxi]);++begin;--end;}
}

插入排序

将第一个数记录后与前一个数比较如果小于前面的数则将前面的数后移,再将从第二个数开始重复直到最后的数比完即可

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

空间复杂度:O(1)

代码展示

void insertsort(int* a, int n)
{//[0, n-1]for (int i = 0; i < n - 1; i++){//[0,end]有序 end+1位置的值插入[0,end],保持有序int end = i;int tmp = a[end + 1];while (end >= 0){if (tmp < a[end]){a[end + 1] = a[end];--end;}else{break;}}a[end + 1] = tmp;}
}

 

希尔排序

又称“分组插入排序”

先将整个待排元素序列分割成若干个子序列(一般为数组长度/3+1,+1保证最后一个gap一定是1)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小,即gap==1)时,再对全体元素进行一次直接插入排序

时间复杂度:大约O(N ^ 1.3)

空间复杂度:O(1)

代码展示

void Shellsort(int* a, int n)
{int gap = n;while (gap > 1){// +1保证最后一个gap一定是1// gap > 1时是预排序// gap == 1时是插入排序gap = gap / 3 + 1;for (size_t i = 0; i < n - gap; ++i){int end = i;int tmp = a[end + gap];while (end >= 0){if (tmp < a[end]){a[end + gap] = a[end];end -= gap;}else{break;}}a[end + gap] = tmp;}}
}

堆排序

将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了

向上排序的时间复杂度为N*logN

而向下排序的时间复杂度为N

所以最好使用向下拍序

向下排序整理好数据为堆后

再将头尾互换数组大小-1后

再使用向下排序

这样得出来的数组就有序了

总共时间复杂度为N*logN

升序建大堆降序建小堆

时间复杂度:O(n*logn)

空间复杂度:O(1)

代码展示

void Swap(HPDataType* p1, HPDataType* p2)
{HPDataType tmp = *p1;*p1 = *p2;*p2 = tmp;
}void AdjustUp(HPDataType* a, int child)
{// 初始条件// 中间过程// 结束条件int parent = (child - 1) / 2;//while (parent >= 0)while (child > 0){if (a[child] < a[parent]){Swap(&a[child], &a[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}
}void AdjustDown(HPDataType* a, int n, int parent)
{// 先假设左孩子小int child = parent * 2 + 1;while (child < n)  // child >= n说明孩子不存在,调整到叶子了{// 找出小的那个孩子if (child + 1 < n && a[child + 1] < a[child]){++child;}if (a[child] < a[parent]){Swap(&a[child], &a[parent]);parent = child;child = parent * 2 + 1;}else{break;}}
}int main()
{int a[10] = { 8,7,5,3,6,4,2,9,4,89 };int n = sizeof(a) / sizeof(a[0]);// 降序,建小堆// 升序,建大堆// 向上调整建堆 O(N*logN)/*for (int i = 1; i < n; i++){AdjustUp(a, i);}*/// 向下调整建堆 O(N)for (int i = (n - 1 - 1) / 2; i >= 0; i--){AdjustDown(a, n, i);}// O(N*logN)int end = n - 1;while (end > 0){Swap(&a[0], &a[end]);AdjustDown(a, end, 0);--end;}return 0;
}

快排

右数找小于key的数停下,左数找大于key的数停下来,左右数互换后继续走,如果碰头与key换

再将0~key-1的数快排,key+1~n的数快排

为提升效率

使用三数取中

小区间优化

时间复杂度:O(n*logn)

空间复杂度:On*logn)

代码展示

void Swap(int* p1, int* p2)
{int tmp = *p1;*p1 = *p2;*p2 = tmp;
}int GetMidi(int* a, int left, int right)
{int midi = (left + right) / 2;// left midi rightif (a[left] < a[midi]){if (a[midi] < a[right]){return midi;}else if (a[left] < a[right]){return right;}else{return left;}}else // a[left] > a[midi]{if (a[midi] > a[right]){return midi;}else if (a[left] < a[right]){return left;}else{return right;}}
}
void InsertSort(int* a, int n)
{//  [0, n-1]for (int i = 0; i < n - 1; i++){// [0, n-2]是最后一组// [0,end]有序 end+1位置的值插入[0,end],保持有序int end = i;int tmp = a[end + 1];while (end >= 0){if (tmp < a[end]){a[end + 1] = a[end];--end;}else{break;}}a[end + 1] = tmp;}
}
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[left], &a[midi]);int keyi = left;int begin = left, end = right;while (begin < end){// 右边找小while (begin < end && a[end] >= a[keyi]){--end;}// 左边找大while (begin < end && a[begin] <= a[keyi]){++begin;}Swap(&a[begin], &a[end]);}Swap(&a[keyi], &a[begin]);keyi = begin;// [left, keyi-1] keyi [keyi+1, right]Quicksort(a, left, keyi - 1);Quicksort(a, keyi + 1, right);}
}

归并排序

将该数组依次分割成两个数组,直到每个数组只有一个元素,再将相邻的2个数组比较有序后合并再将2个元素的数组之间合并,依次完成实现最终数组有序

时间复杂度:O(n*logn)

空间复杂度:On)

代码展示

void _MergeSort(int* a, int* tmp, int begin, int end)
{if (begin >= end)return;int mid = (begin + end) / 2;// 如果[begin, mid][mid+1, end]有序就可以进行归并了_MergeSort(a, tmp, begin, mid);_MergeSort(a, tmp, mid + 1, end);// 归并int begin1 = begin, end1 = mid;int begin2 = mid + 1, end2 = end;int i = begin;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, (end - begin + 1) * sizeof(int));
}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/diannao/32849.shtml

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

相关文章

Linux使用——查看发行版本、内核、shell类型等基本命令

先做快照 虚拟机中编辑网络 关机 普通账户和管理员账户 互相对照 localhost相当于IP 参数: 短格式:以减号(-)开头&#xff0c;参数字母 长格式:以2个减号(--)后跟上完整的参数单词 当前发行版本 [rootserver ~]# cat /etc/redhat-release Red Hat Enterprise Linux release 9.…

压缩示例代码libarchive,zlib

文章目录 前言一、zlib库在内存中对数据进行压缩&#xff0c;defalteInit函数默认压缩为zlib格式在内存中将数据压缩为gzip格式 二、libarchive库压缩为tar.gz文件 总结 前言 记录用C/C实现数据压缩的代码 一、zlib库 home page: https://zlib.net/ manual: https://zlib.n…

Java日常探秘-从小疑问到实践智慧的编程之旅(1)

文章目录 前言一、Git中回滚操作的方式二、加密为第三方服务&#xff0c;需要rpc&#xff0c;怎么提高效率三、加解密需求&#xff0c;逻辑能够尽量收敛四、加解密优化五、加解密的rpc失败了处理机制六、优化MySQL查询总结 前言 所有分享的内容源于日常思考和实践&#xff0c;…

C++设计模式——Flyweight享元模式

一&#xff0c;享元模式简介 享元模式是一种结构型设计模式&#xff0c;它将每个对象中各自保存一份数据的方式改为多个对象共享同一份数据&#xff0c;该模式可以有效减少应用程序的内存占用。 享元模式的核心思想是共享和复用&#xff0c;通过设置共享资源来避免创建过多的实…

MSPM0G3507——定时器例程1——TIMA_periodic_repeat_count

以下示例以周期模式配置TimerA0&#xff0c;并使用重复计数功能每隔2秒切换一次GPIO。注意&#xff1a;重复计数功能特定于TimerA0实例&#xff0c;而不是其他TimerA实例。这里是一次500毫秒&#xff0c;重复了四次 主函数&#xff1a; #include "ti_msp_dl_config.h&quo…

Clickhouse备份恢复_Docker环境下的clickhouse如何备份恢复

总结&#xff1a; Docker环境的下的clickhouse备份&#xff0c;不能使用clickhouse-backup&#xff0c;因为clickhouse-client只能备份Docker环境下的clickhouse的元数据 Docker环境的下的clickhouse备份&#xff0c;可以使用TCP的clickhouse-client的9000或HTTP的8123连接clic…

20240621日志:大模型压缩-从闭源大模型蒸馏

目录 1. 核心内容2. 方法2.1 先验估计2.2 后验估计2.3 目标函数 3. 交叉熵损失函数与Kullback-Leibler&#xff08;KL&#xff09;损失函数 location&#xff1a;beijing 涉及知识&#xff1a;大模型压缩、知识蒸馏 Fig. 1 大模型压缩-知识蒸馏 1. 核心内容 本文提出在一个贝…

Program-of-Thoughts(PoT):结合Python工具和CoT提升大语言模型数学推理能力

Program of Thoughts Prompting:Disentangling Computation from Reasoning for Numerical Reasoning Tasks github&#xff1a;https://github.com/wenhuchen/Program-of-Thoughts 一、动机 数学运算和金融方面都涉及算术推理。先前方法采用监督训练的形式&#xff0c;但这…

英语笔记-专升本

2024年6月23日15点01分&#xff0c;今天自己听老师讲了一张试卷&#xff0c;自己要开始不断地进行一个做事&#xff0c;使自己可以不断地得到一个提升&#xff0c;自己可以提升的内容&#xff0c; 英语试卷笔记 ------------------------------------ | 英语试卷笔记 …

使用Python监控网络连接状态并自动启动和关闭软件

通过 Python 编写一个网络连接状态监测程序&#xff0c;以 Synology Drive软件为例。通过如下代码实现来演示如何监控网络连接状态并自动启动和关闭相关软件。 程序首先通过 ping 命令检查内网或外网的连接状态。如果连接的是外网&#xff0c;则程序会检查 Synology Drive 软件…

发表在SIGMOD 2024上的高维向量检索/向量数据库/ANNS相关论文

前言 SIGMOD 2024会议最近刚在智利圣地亚哥结束&#xff0c;有关高维向量检索/向量数据库/ANNS的论文主要有5篇&#xff0c;涉及混合查询&#xff08;带属性或范围过滤的向量检索&#xff09;优化、severless向量数据库优化、量化编码优化、磁盘图索引优化。此外&#xff0c;也…

微信小程序入门2

微信开发者工具的安装方法 1.打开微信开发者工具下载页面 在微信小程序管理后台的左侧边栏中选择“开发工具”&#xff0c;然后选择“开发者工具”&#xff0c;即可找到微信开发者工具的下载页面。 2.打开微信开发者工具的下载链接页面 单击“下载” 按钮下载&#xff0c;即…

离线linux通过USB连接并使用手机网络

离线linux通过USB连接并使用手机网络 引场景 引 离线环境要安装一些软件特别麻烦&#xff0c;要自己去官网下载对应的包&#xff0c;然后上传到服务器上&#xff0c;再解压&#xff0c;编译&#xff0c;执行&#xff0c;配置变量等等&#xff0c;错一步都可能安装失败。有网络…

越复杂的CoT越有效吗?Complexity-Based Prompting for Multi-step Reasoning

Complexity-Based Prompting for Multi-step Reasoning 论文&#xff1a;https://openreview.net/pdf?idyf1icZHC-l9 Github&#xff1a;https://github.com/FranxYao/chain-of-thought-hub 发表位置&#xff1a;ICLR 2023 Complexity-Based Prompting for Multi-step Reason…

网络攻击有哪些新兴的威胁和防御策略

最新网络攻击威胁 近期&#xff0c;网络攻击的威胁呈现出新的趋势和特点。DDoS攻击仍然是一种严重的威胁&#xff0c;其次数和规模在过去一年中显著增长&#xff0c;攻击者技术不断升级&#xff0c;攻击成本逐渐降低。此外&#xff0c;攻击者的手段越来越多样化&#xff0c;包…

Simple-STNDT使用Transformer进行Spike信号的表征学习(三)训练与评估

文章目录 1. 评估指标2. 训练准备3. debug测试4. train-val函数 1. 评估指标 import numpy as np from scipy.special import gammaln import torchdef neg_log_likelihood(rates, spikes, zero_warningTrue):"""Calculates Poisson negative log likelihood g…

Java面试题:通过实例说明工厂模式和抽象工厂模式的用法,以及它们在解耦中的作用

工厂模式和抽象工厂模式是创建型设计模式中的两种&#xff0c;主要用于对象的创建&#xff0c;并且通过将对象的创建过程封装起来&#xff0c;来实现代码的解耦和灵活性。下面通过具体实例来说明这两种模式的用法及其在解耦中的作用。 工厂模式&#xff08;Factory Method Pat…

STM32 - LED灯 蜂鸣器

&#x1f6a9; WRITE IN FRONT &#x1f6a9; &#x1f50e; 介绍&#xff1a;"謓泽"正在路上朝着"攻城狮"方向"前进四" &#x1f50e;&#x1f3c5; 荣誉&#xff1a;2021|2022年度博客之星物联网与嵌入式开发TOP5|TOP4、2021|2222年获评…

Pytest框架中pytest.mark功能

文章目录 mark功能 1. 使用pytest.mark.skip 2. 使用pytest.mark.skipif 3. 使用 pytest.mark.xfail 4使用pytest.mark.parametrize 5 使用pytest.mark.自定义标记 6 使用pytest.mark.usefixtures pytest 的mark功能在pytest官方文档是这样解释的&#xff1a; https://…

Rust:使用 Warp 框架编写基于 HTTPS 的 RESTful API

在 Rust 中使用 Warp 框架编写基于 HTTPS 的 RESTful API&#xff0c;你需要首先设置好 TLS/SSL 证书以启用 HTTPS。以下是一个基本的步骤指南&#xff1a; 步骤 1: 安装 Rust 和 Cargo 确保你已经安装了 Rust 和 Cargo。你可以从 Rust 官网 下载并安装 Rust。 步骤 2: 创建…