当前位置: 首页 > news >正文

八大排序源码(含优化)

文章目录

  • 1、直接插入排序
  • 2、希尔排序
  • 3、选择排序
  • 4、冒泡排序
  • 5、堆排序
  • 6、快速排序
    • 快速排序递归实现
      • 霍尔法
      • 挖坑法
      • 前后指针法
      • 快速排序小区间优化
    • 快速排序非递归实现
  • 7、归并排序
    • 归并排序递归实现
    • 归并排序非递归
  • 8、计数排序

大家好,我是纪宁,这篇文章是关于八大排序的源代码,具体实现过程会在后续文章中介绍。

1、直接插入排序

时间复杂度O(N^2),原数据越有序,效率越高。
当原数据有序时,则时间复杂度为O(N)。原数据倒序时,时间复杂度为O(N^2)
在这里插入图片描述

void InsertSort(int* a, int n)//直接插入排序
{for (int i = 0; i < n - 1; i++){int end = i;int tmp = a[end+1];while (end >= 0){if (a[end] >tmp){a[end + 1] = a[end];}else{break;}end--;}a[end + 1] = tmp;}
}

2、希尔排序

时间复杂度:O(N^1.3) 空间复杂度:O(1)
希尔排序是插入排序的优化,整体思路是先预排序,使原数据更接近有序,等到gap==1时,就变成了直接插入排序。

void ShellSort(int* arr, int n)
{int gap = n;while (gap > 1){gap = gap / 3 + 1;//gap也可以 /=2;奇特数字必须保证gap最后的值为1for (int i = 0; i < n - gap; i++){int end = i;int tmp = arr[end + gap];while (end >= 0){if (tmp < arr[end]){arr[end + gap] = arr[end];}else{break;}end -= gap;}arr[end + gap] = tmp;}}
}

3、选择排序

时间复杂度:O(N^2) 空间复杂度:O(1)
每次选择一个最大或者最小的数,使其出现在正确的位置。
在这里插入图片描述

void SelectSort(int* a, int n)
{for (int j = 0; j < n; j++){int mini = j;int maxi= n - j-1;for (int i = j; i < n-j; i++){if (a[i] < a[mini]){mini = i;}if (a[i] > a[maxi]){maxi = i;}}Swap(&a[mini], &a[j]);if (maxi == j){maxi = mini;//最大值如果在 j 这个位置的话,结果这个位置被换成了min 的值}Swap(&a[maxi], &a[n-1-j]);}
}

4、冒泡排序

时间复杂度:O(N^2) 空间复杂度:O(1)
思路最简单的排序,所有程序员的白月光!
在这里插入图片描述

void BubbleSort(int* a, int n)//冒泡排序
{for (int i = 0; i < n; i++){int ret = 0;//如果一趟后ret还等于0,说明数据已经有序for (int j = 0; j < n - i - 1; j++){if (a[j] > a[j + 1]){Swap(&a[j], &a[j + 1]);ret = 1;}}if (ret == 0)break;}
}

5、堆排序

时间复杂度:O(N*logN) 空间复杂度:O(1)
建堆的时候可以采用向上调整和向下调整建堆,而排序的时候只能使用向下调整算法。
排升序建大堆,降序建小堆。

void Adjustup(int* a, int child)//向上调整
{int parent = (child - 1) / 2;while (parent >= 0){if (a[child] > a[parent]){Swap(&a[child], &a[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}
}void Adjustdown(int* a, int parent, int n)//向下调整
{int child = 2 * parent + 1;while (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 = 2 * parent + 1;}else{break;}}
}void HeapSort(int* arr, int sz)
{//第一步,建堆向上调整建堆//for (int i = 1; i < sz; i++)//{//	Adjustup(arr, i); //}//向下调整建堆for (int i = (sz - 1) / 2; i >= 0; i--){Adjustdown(arr, i, sz - 1);}int end = sz - 1;while (end > 0){Swap(&arr[0], &arr[end]);Adjustdown(arr, 0, end);end--;}
}

6、快速排序

时间复杂度:O(N*logN) 空间复杂度:O(1)

快速排序递归实现

霍尔法

在这里插入图片描述

int QuickSortPart1(int*a,int left,int right)//霍尔版本
{int* Maxi = (&a[left], &a[right], &(a[(left + right) / 2]));//三数取中Swap(&a[left], Maxi);//换到最左边int key = a[left];int keyi = left;while (left<right){while (left<right && a[right]>=key){right--;}while (left < right && a[left] <= key){left++;}Swap(&a[left], &a[right]);}Swap(&a[keyi], &a[left]);return left;
}
void QuickSort(int*arr, int begin, int end)
{if (begin >= end)//等于是只有一个数需要排,大于是没有数需要排{return;}int keyi = QuickSortPart1(arr, begin, end);/*int keyi = QuickSortPart2(arr, begin, end);int keyi = QuickSortPart3(arr, begin, end);*/QuickSort(arr, begin, keyi - 1);QuickSort(arr, keyi + 1, end);
}

挖坑法

在这里插入图片描述

int QuickSortPart2(int* arr, int left, int right)//挖坑法
{int* Maxi = (&arr[left], &arr[right], &(arr[(left + right) / 2]));Swap(&arr[left], Maxi);int holei = left;int hole = arr[left];while (left < right){while (left < right && arr[right] >= hole){right--;}arr[holei] = arr[right];holei = right;while (left < right && arr[left] <= hole){left++;}arr[holei] = arr[left];holei = left;}arr[holei] = hole;return left;
}
void QuickSort(int*arr, int begin, int end)
{if (begin >= end)//等于是只有一个数需要排,大于是没有数需要排{return;}/*int keyi = QuickSortPart1(arr, begin, end);*/int keyi = QuickSortPart2(arr, begin, end);/*int keyi = QuickSortPart3(arr, begin, end);*/QuickSort(arr, begin, keyi - 1);QuickSort(arr, keyi + 1, end);
}

前后指针法

在这里插入图片描述

int QuickSortPart3(int* a, int left, int right)//快排快慢指针
{int* Maxi = (&a[left], &a[right], &(a[(left + right) / 2]));Swap(&a[left], Maxi);int keyi = left;int prev = left;int cur = left+1;while (cur <= right){if (a[cur] < a[keyi]&& ++prev!= cur){Swap(&a[prev], &a[cur]);}cur++;}Swap(&a[prev],&a[keyi]);return prev;
}void QuickSort(int*arr, int begin, int end)
{if (begin >= end)//等于是只有一个数需要排,大于是没有数需要排{return;}//*int keyi = QuickSortPart1(arr, begin, end);*///int keyi = QuickSortPart2(arr, begin, end);int keyi = QuickSortPart3(arr, begin, end);QuickSort(arr, begin, keyi - 1);QuickSort(arr, keyi + 1, end);
}

快速排序小区间优化

void QuickSort1(int* a, int begin, int end)
{if (begin >= end)return;// 小区间优化,小区间不再递归分割排序,降低递归次数if ((end - begin + 1) > 10){int keyi = PartSort3(a, begin, end);// [begin, keyi-1] keyi [keyi+1, end]QuickSort1(a, begin, keyi - 1);QuickSort1(a, keyi + 1, end);}else{InsertSort(a + begin, end - begin + 1);//直接插入排序}
}

快速排序非递归实现

快排非递归要用栈来实现

void QuickSortNorn(int* a, int begin, int end)
{ST st;//创建数组栈STInit(&st);//初始化栈STPush(&st, end);//入栈STPush(&st, begin);//入栈while (!STEmpty(&st))//判空{int left = STTop(&st);//取栈顶数据STPop(&st);//出栈int right = STTop(&st);STPop(&st);int keyi = QuickSortPart1(a, left,right);if (keyi + 1 < right){STPush(&st, right);STPush(&st, keyi + 1);}if (keyi - 1 > left){STPush(&st, keyi - 1);STPush(&st, left);}}STDestroy(&st);//销毁栈
}

7、归并排序

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

归并排序递归实现

在这里插入图片描述

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

归并排序非递归

void _MergeSortNonr(int* a, int* tmp, int begin, int end)
{int gap = 1;while (gap <= end){for (int i = 0; i <= end; i += 2 * gap){int begin1 = i, end1 = i + gap - 1;int begin2 = i + gap, end2 = i + 2 * gap - 1;int index = i;if (begin2 > end){break;}if (end2 > end){end2 = end;//对范围进行修正}while (begin1 <= end1 && begin2 <= end2){if (a[begin1] < a[begin2]){tmp[index++] = a[begin1++];}else{tmp[index++] = a[begin2++];}}while (begin1 <= end1){tmp[index++] = a[begin1++];}while (begin2 <= end2){tmp[index++] = a[begin2++];}memcpy(a + i, tmp + i, sizeof(int) * (end2-i+1));//拷贝回原数组}gap *= 2;}}
void MergeSortNonr(int* a, int n)//归并排序非递归
{int* tmp = (int*)malloc(sizeof(int) * n);_MergeSortNonr(a, tmp, 0, n - 1);free(tmp);tmp = NULL;
}

8、计数排序

时间复杂度:O(MAX(N,range)) 空间复杂度:O(range)

void CountSort(int* a, int n)//计数排序
{//先找最大值和最小值int maxi = 0, mini = 0;for (int i = 1; i < n; i++){if (a[i] > a[maxi]){maxi = i;}if (a[i] < a[mini]){mini = i;}}int max = a[maxi], min = a[mini];int range = a[maxi] - a[mini]+1;int* count = (int*)malloc(sizeof(int) * range);memset(count, 0, sizeof(int) * range);for (int j = 0; j < n; j++){count[a[j] - min]++;}int i = 0;for (int j = 0; j < n; j++){while (count[j]--){ a[i++] = j + min;}}
}

相关文章:

八大排序源码(含优化)

文章目录 1、直接插入排序2、希尔排序3、选择排序4、冒泡排序5、堆排序6、快速排序快速排序递归实现霍尔法挖坑法前后指针法快速排序小区间优化 快速排序非递归实现 7、归并排序归并排序递归实现归并排序非递归 8、计数排序 大家好&#xff0c;我是纪宁&#xff0c;这篇文章是关…...

单调队列---数据结构与算法

简介 队列也是一种受限制的线性表和栈相类似&#xff0c;栈是先进后出&#xff0c;而队列是先进先出&#xff0c;就好像一没有底的桶&#xff0c;往里面放东西&#xff0c;如图 在这里也是用数组来实现队列&#xff0c;用数组实现的叫做顺序队列 队列的数组模拟 const int N…...

小程序如何使用自定义组件

使用自定义组件的步骤如下&#xff1a; 创建自定义组件&#xff1a;在小程序项目根目录下的 components 文件夹中创建一个文件夹&#xff0c;然后在该文件夹中创建一个 .json 文件、一个 .wxml 文件和一个 .js 文件&#xff0c;这三个文件分别对应组件的配置、模板和逻辑。 在…...

归并排序含非递归版

目录 1.归并排序的原理 2.实现归并排序 2.1框架 2.2区间问题和后序遍历 2.3归并并拷贝 2.4归并排序代码 2.5测试 3.非递归实现归并排序 3.1初次实现 3.2测试 3.3修改 3.4修改测试 1.归并排序的原理 归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治…...

项目进展(八)-编写代码,驱动ADS1285

一、代码 根据芯片的数据手册编写部分驱动&#xff0c;首先看部分引脚的波形&#xff1a; DRDY: CS&#xff1a; 首先在代码初始化时连续写入三个寄存器&#xff1a; void WriteReg(uint8_t startAddr, uint8_t *regData, uint8_t number) {uint8_t i0;// 循环写number1次…...

【MyBatis-Plus】快速精通Mybatis-plus框架—快速入门

大家在日常开发中应该能发现&#xff0c;单表的CRUD功能代码重复度很高&#xff0c;也没有什么难度。而这部分代码量往往比较大&#xff0c;开发起来比较费时。 因此&#xff0c;目前企业中都会使用一些组件来简化或省略单表的CRUD开发工作。目前在国内使用较多的一个组件就是…...

docker 安装kafka

运行容器 zookeeper: [rootk8s-master ~]# docker run -d --restartalways --log-driver json-file --log-opt max-size100m --log-opt max-file2 --name zookeeper -p 2181:2181 -v /etc/localtime:/etc/localtime zookeeper c603f292813cfd6e2b16fff88a9767cc86fc9bba34d82…...

容器内获得apiserver地址

1.容器的Env的KUBENETES_SERVICE_HOST字段 roottomcat01-69fc8f859b-w9btn:/tmp# env | grep KUBERNETES_SERVICE_HOST10.96.0.1 KUBERNETES_SERVICE_HOST10.96.0.12.通过域名查询 nslookup getent hosts roottomcat01-69fc8f859b-w9btn:/tmp# getent hosts kubernetes.def…...

linux服务端c++开发工具介绍(vscode版)

本文适合于有一定c开发经验&#xff0c;但是还不明确如何到linux服务端开发程序的同学。 一、vscode 几年前用的是ssh到云服务上&#xff0c;再用vim在云上开发的形式 ssh dongbeijing.dbj11.158.142.176 vim hello.c 现今&#xff0c;由于vscode比较好用&#xff0c;这几年…...

Linux常用命令大全

Linux常用命令大全 一、文件&目录管理1. 文件和目录操作命令2. 查看文件及内容处理命令3. 文件压缩及解压缩命令4. 搜索文件命令5. 其他 二、Linux 软件包管理三、用户管理1. 用户管理2. 查看系统用户登陆信息的命令 四、进程管理五、网络通信1. 基础网络操作命令2. 深入网…...

Python中取2023, 9, 1——2023, 10, 31的全部时间

使用datetime.date()函数定义了开始和结束日期。然后&#xff0c;我们使用datetime.timedelta()类创建了一个时间范围&#xff0c;其中n表示从开始日期到结束日期之间的天数。最后&#xff0c;我们使用一个for循环迭代时间范围内的日期&#xff0c;并打印每个日期。示例代码演示…...

创建django文件

1、在指定目录里打开终端&#xff0c;输入D:\Softwares\Anaconda3\envs\pytorch\Scripts\django-admin .exe startproject 名称 &#xff0c;即可在对应目录里创建django文件。...

全排列[中等]

优质博文&#xff1a;IT-BLOG-CN 一、题目 给定一个不含重复数字的数组nums&#xff0c;返回其所有可能的全排列。你可以按任意顺序返回答案。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&#xff1a;[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] 示例…...

mybatise-plus的id过长问题

一、问题情景 笔者在做mp插入数据库(id已设置为自增)操作时&#xff0c;发现新增数据的id过长&#xff0c;结果导致前端JS拿到的数据出现了精度丢失问题&#xff0c;原因是后端id的类型是Long。在网上查了一下&#xff0c;只要在该属性上加上如下注解就可以 TableId(value &q…...

图示矩阵分解

特征值与特征向量 设 A A A 是 n 阶矩阵&#xff0c;如果存在数 λ \lambda λ 和 n 维非零列向量 x x x&#xff0c;满足关系式&#xff1a; A x λ x ( 1 ) Ax \lambda x\quad\quad(1) Axλx(1) 则数 λ \lambda λ 称为矩阵 A A A 的特征值&#xff0c;非零向量 x…...

六、互联网技术——数据存储

文章目录 一、存储系统层次结构二、按照重要性分类三、磁盘阵列RAID三、RAID基础四、磁盘阵列分级五、数据备份与恢复六、容灾与灾难恢复 一、存储系统层次结构 常见的三层存储体系结构如下图所示&#xff0c;分为高速缓冲存储器、主存储器和外存储器。 二、按照重要性分类 …...

六、vpp 流表+负载均衡

草稿&#xff01;&#xff01;&#xff01; vpp node其实就是三个部分 1、plugin init 2、set command 3、function 实现功能&#xff0c;比如这里的流表 今天我们再用VPP实现一个流表的功能 一、流表 1.1流表----plugin init VLIB_REGISTER_NODE 注册流表节点 // 注册流…...

word已排序好的参考文献,插入新的参考文献,序号更新

原排序好的文献序号。 现在在3号后面插入一个新文献。4&#xff0c;5号应该成为5&#xff0c;6 这时在3号后面&#xff0c;回车&#xff0c;就会自动的增长。如下图&#xff1a; 但是如果手滑&#xff0c;把[4]删除了如何排序&#xff1f;&#xff1f; 如下图&#xff1a; …...

二叉树的顺序存储——堆——初识堆排序

前面我们学过可以把完全二叉树存入到顺序表中&#xff0c;然后利用完全二叉树的情缘关系&#xff0c;就可以通过数组下标来联系。 但是并不是把二叉树存入到数组中就是堆了&#xff0c;要看原原来的二叉树是否满足&#xff1a;所有的父都小于等于子&#xff0c;或者所有的父都…...

CYEZ 模拟赛 9

A a ⊥ b ⇒ a − b ⊥ a b (1) a \perp b \Rightarrow a-b \perp ab \tag {1} a⊥b⇒a−b⊥ab(1) 证明&#xff1a; gcd ⁡ ( a , b ) gcd ⁡ ( b , a − b ) \gcd(a,b) \gcd(b, a-b) gcd(a,b)gcd(b,a−b)&#xff0c;故 a − b ⊥ b a - b \perp b a−b⊥b&#xff0c;同…...

typescript: Builder Pattern

/*** file: CarBuilderts.ts* TypeScript 实体类 Model* Builder Pattern* 生成器是一种创建型设计模式&#xff0c; 使你能够分步骤创建复杂对象。* https://stackoverflow.com/questions/12827266/get-and-set-in-typescript* https://github.com/Microsoft/TypeScript/wiki/…...

WPS/word 表格跨行如何续表、和表的名称

1&#xff1a;具体操作&#xff1a; 将光标定位在跨页部分的第一行任意位置&#xff0c;按下快捷键ctrlshiftenter&#xff0c;就可以在跨页的表格上方插入空行&#xff08;在空行可以写&#xff0c;表1-3 xxxx&#xff08;续&#xff09;&#xff09; 在空行中输入…...

Python的NumPy库(一)基础用法

NumPy库并不是Python的标准库&#xff0c;但其在机器学习、大数据等很多领域有非常广泛的应用&#xff0c;NumPy本身就有比较多的内容&#xff0c;全部的学习可能涉及许多的内容&#xff0c;但我们在这里仅学习常见的使用&#xff0c;这些内容对于我们日常使用NumPy是足够的。 …...

uniapp app 导出excel 表格

直接复制运行 <template><view><button click"tableToExcel">导出一个表来看</button><view>{{ successTip }}</view></view> </template><script>export default {data() {return {successTip: }},metho…...

【RabbitMQ】常用消息模型详解

文章目录 AMQP协议的回顾RabbitMQ支持的消息模型第一种模型(直连)开发生产者开发消费者生产者、消费者开发优化API参数细节 第二种模型(work quene)开发生产者开发消费者消息自动确认机制 第三种模型(fanout)开发生产者开发消费者 第四种模型(Routing)开发生产者开发消费者 第五…...

图像拼接后丢失数据,转tiff报错rasterfile failed: an unknown

图像拼接后丢失数据 不仅是数据丢失了&#xff0c;还有个未知原因报错 部分数据存在值不存在的情况 原因 处理遥感数据很容易&#xff0c;磁盘爆满了 解决方案 清理一些无用数据&#xff0c;准备买个2T的外接硬盘用着了。 然后重新做处理...

Nginx之日志模块解读

目录 基本介绍 配置指令 access_log&#xff08;访问日志&#xff09; error_log&#xff08; 错误日志&#xff09; 基本介绍 Nginx日志主要分为两种&#xff1a;access_log(访问日志)和error_log(错误日志)。Nginx日志主要记录以下信息&#xff1a; 记录Nginx服务启动…...

latex方程组编写,一种可以保证方程编号自适应的方法

问题描述&#xff1a; 在利用latex编写方程组时&#xff0c;可以有很多种方法&#xff0c;但不总是编辑好的公式能够显示出编号&#xff0c;故提出一种有效的方程组编写方法 方法&#xff1a; \begin{equation}X_{ t1}\left \{ \begin{matrix}\frac{x_{i}}{a} \quad\quad 0&l…...

深度学习基础 2D卷积(1)

什么是2D卷积 2D参数量怎么计算 以pytorch为例子&#xff0c;2D卷积在设置的时候具有以下参数&#xff0c;具有输入通道的多少&#xff08;这个决定了卷积核的通道数量&#xff09;&#xff0c;滤波器数量&#xff0c;这个是有多少个滤波器&#xff0c;越多提取的特征就越有用…...

OpenCV DNN C++ 使用 YOLO 模型推理

OpenCV DNN C 使用 YOLO 模型推理 引言 YOLO&#xff08;You Only Look Once&#xff09;是一种流行的目标检测算法&#xff0c;因其速度快和准确度高而被广泛应用。OpenCV 的 DNN&#xff08;Deep Neural Networks&#xff09;模块为我们提供了一个简单易用的 API&#xff0…...