【初阶数据结构篇】归并排序、计数排序

文章目录

须知

💬 欢迎讨论:如果你在学习过程中有任何问题或想法,欢迎在评论区留言,我们一起交流学习。你的支持是我继续创作的动力!

👍 点赞、收藏与分享:觉得这篇文章对你有帮助吗?别忘了点赞、收藏并分享给更多的小伙伴哦!你们的支持是我不断进步的动力!
🚀 分享给更多人:如果你觉得这篇文章对你有帮助,欢迎分享给更多对C++感兴趣的朋友,让我们一起进步!

 1. 归并排序

基本思想

 归并排序(MERGE-SORT)是建⽴在归并操作上的⼀种有效的排序算法,该算法是采⽤分治法(Divide andConquer)的⼀个⾮常典型的应⽤。将已有序的⼦序列合并,得到完全有序的序列;即先使每个 ⼦序列有序,再使⼦序列段间有序。若将两个有序表合并成⼀个有序表,称为⼆路归并。归并排序核 ⼼步骤:

1.1 分析 

 。归并排序:先递归,再合并的排序算法(分治法)

。对数组中第一个元素的下标和最后一个元素的下标进行分解,直至为最后一个元素,再进行合并

。合并思想:对两个数组的元素进行合并

注意:我们应另外创建一个数组存储排序后的结果,会覆盖原始数值。

1.2 代码:

void _MergeSort(int* arr, int left, int right, int* tmp)
{if (left >= right){return;}int mid = (left + right) / 2;//[left,mid] [mid+1,right]_MergeSort(arr, left, mid, tmp);_MergeSort(arr, mid + 1, right, tmp);//合并//[left,mid] [mid+1,right]int begin1 = left, end1 = mid;int begin2 = mid + 1, end2 = right;int index = begin1;while (begin1 <= end1 && begin2 <= end2){if (arr[begin1] < arr[begin2]){tmp[index++] = arr[begin1++];}else {tmp[index++] = arr[begin2++];}}//要么begin1越界但begin2没有越界  要么begin2越界但begin1没有越界while (begin1 <= end1){tmp[index++] = arr[begin1++];}while (begin2 <= end2){tmp[index++] = arr[begin2++];}//[left,mid] [mid+1,right]//把tmp中的数据拷贝回arr中for (int i = left; i <= right; i++){arr[i] = tmp[i];}
}void MergeSort(int* arr, int n)
{int* tmp = (int*)malloc(sizeof(int) * n);_MergeSort(arr, 0, n - 1, tmp);free(tmp);
}

复杂度分析
时间复杂度:递归深度logn,对于每一层来说都是会把所有元素遍历一次,例如在递归第一层(二叉树第一层的函数栈桢)把原区间分为了两个区间,最后回归的时候就是合并两个有序数组,会把其中元素都遍历一次;其他层都同理为n,总计O(nlogn)
空间复杂度:递归深度logn,开辟n个元素的空间,为O(n)

 排序稳定性:很稳定

2. 计数排序(非比较排序)

计数排序⼜称为鸽巢原理,是对哈希直接定址法的变形应⽤

哈希直接定址法

关键字的某个线性函数值作为散列地址

直接定址法获取得到的散列函数有点就是简单,均匀也不会产生冲突

但问题是这需要事先知道关键字的分布情况

适合查找表较小且连续的情况

由于这样的限制,在现实应用中,此方法虽然简单,但却并不常用

2.1 分析 

 

 

 步骤:

  • 第一步,确定数组最大值和最小值,遍历
  • 第二步,申请空间并初始化
  • 第三步,统计每个数据出现的个数
  • 根据申请的数组下标递增依次往原数组放数据

将对应下标加上min就是原始数据,数组下标对应的值出现几次就说明该数出现几次。

2.2 代码:

void CountSort(int* arr, int n)
{//根据最大值最小值确定数组大小int max = arr[0], min = arr[0];for (int i = 1; i < n; i++){if (arr[i] > max){max = arr[i];}if (arr[i] < min){min = arr[i];}}int range = max - min + 1;int* count = (int*)malloc(sizeof(int) * range);if (count == NULL){perror("malloc fail!");exit(1);}//初始化range数组中所有的数据为0memset(count, 0, range * sizeof(int));//统计数组中每个数据出现的次数for (int i = 0; i < n; i++){count[arr[i] - min]++;}//取count中的数据,往arr中放int index = 0;for (int i = 0; i < range; i++){while (count[i]--){arr[index++] = i + min;}}
}
  • 复杂度分析
  • 时间复杂度:找最大和最小值为N,统计个数也是遍历原数组为N,最后往原数组放数据,相当于遍历一次新数组为range,加上把N个数据放到原数组,所以总时间复杂度O(N+range)
  • 空间复杂度:O(range)

特点: 

计数排序在数据范围集中时,效率很⾼,但是适⽤范围及场景有限。

比如只能用来排整数数据。

 3. 各排序性能比较

// 测试排序的性能对⽐
void TestOP()
{srand(time(0));const int N = 100000; int* a1 = (int*)malloc(sizeof(int) * N);int* a2 = (int*)malloc(sizeof(int) * N);int* a3 = (int*)malloc(sizeof(int) * N);int* a4 = (int*)malloc(sizeof(int) * N);int* a5 = (int*)malloc(sizeof(int) * N);int* a6 = (int*)malloc(sizeof(int) * N);int* a7 = (int*)malloc(sizeof(int) * N);int* a8 = (int*)malloc(sizeof(int) * N);for (int i = 0; i < N; ++i){a1[i] = rand();a2[i] = a1[i];a3[i] = a1[i];a4[i] = a1[i];a5[i] = a1[i];a6[i] = a1[i];a7[i] = a1[i];a8[i] = a1[i];}int begin7 = clock();BubbleSort(a7, N);int end7 = clock();int begin1 = clock();InsertSort(a1, N);int end1 = clock();int begin2 = clock();ShellSort(a2, N);int end2 = clock();int begin3 = clock();SelectSort(a3, N);int end3 = clock();int begin4 = clock();HeapSort(a4, N);int end4 = clock();int begin5 = clock();QuickSort(a5, 0, N - 1);//QuickSortNonR(a5, 0, N - 1);int end5 = clock();int begin6 = clock();MergeSort(a6, N);int end6 = clock();int begin8 = clock();CountSort(a8, N);int end8 = clock();printf("InsertSort:%d\n", end1 - begin1);printf("ShellSort:%d\n", end2 - begin2);printf("SelectSort:%d\n", end3 - begin3);printf("HeapSort:%d\n", end4 - begin4);printf("QuickSort:%d\n", end5 - begin5);printf("MergeSort:%d\n", end6 - begin6);printf("BubbleSort:%d\n", end7 - begin7);printf("CountSort:%d\n", end8 - begin8);free(a1);free(a2);free(a3);free(a4);free(a5);free(a6);free(a7);free(a8);
}

4. 排序算法复杂度及稳定性分析

稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的 相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,⽽在排序后的序列中,r[i]仍在r[j]之 前,则称这种排序算法是稳定的;否则称为不稳定的。

简单来说就是:重复的数据在排序前后相对位置是否发生改变

 

4.1 稳定性验证案例

直接选择排序:5 8 5 2 9
希尔排序:5 8 2 5 9
堆排序:2 2 2 2
快速排序:5 3 3 4 3 8 9 10 11

相信通过这篇文章你对数据结构(归并排序)的有了初步的了解。如果此篇文章对你学习数据结构有帮助,期待你的三连,你的支持就是我创作的动力!!! 

下一篇文章再会!!!

 

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

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

相关文章

移远通信5G RedCap模组RG255C-CN通过中国电信5G Inside终端生态认证

近日&#xff0c;移远通信5G RedCap模组RG255C-CN荣获中国电信颁发的5G Inside终端生态认证证书。这表明&#xff0c;该产品在5G基本性能、网络兼容性、安全特性等方面已经过严格评测且表现优异&#xff0c;将进一步加速推动5G行业终端规模化应用。 中国电信5G Inside终端生态认…

Towards Reasoning in Large Language Models: A Survey

文章目录 题目摘要引言什么是推理?走向大型语言模型中的推理测量大型语言模型中的推理发现与启示反思、讨论和未来方向 为什么要推理?结论题目 大型语言模型中的推理:一项调查 论文地址:https://arxiv.org/abs/2212.10403 项目地址: https://github.com/jeffhj/LM-reason…

Android Studio | 修改镜像地址为阿里云镜像地址,启动App

在项目文件的目录下的 settings.gradle.kts 中修改配置&#xff0c;配置中包含插件和依赖项 pluginManagement {repositories {maven { urluri ("https://www.jitpack.io")}maven { urluri ("https://maven.aliyun.com/repository/releases")}maven { urlu…

Python | Leetcode Python题解之第564题数组嵌套

题目&#xff1a; 题解&#xff1a; class Solution:def arrayNesting(self, nums: List[int]) -> int:ans, n 0, len(nums)for i in range(n):cnt 0while nums[i] < n:num nums[i]nums[i] ni numcnt 1ans max(ans, cnt)return ans

2024-11-17 -MATLAB三维绘图简单实例

1. x -1:0.05:1; y x; [X, Y] meshgrid(x, y); f (X, Y) (sin(pi * X) .* sin(pi * Y)) .^ 2.*sin(2.*X2.*Y); mesh(X, Y, f(X, Y)); % 调用函数f并传递X和Y xlabel(X-axis); ylabel(Y-axis); zlabel(Z-axis); title(Surface Plot of (sin(pi * X) .* sin(pi * Y)) .^ 2.*…

网络层9——虚拟专用网VPN和网络地址转换NAT

目录 一、为什么有虚拟专用网&#xff1f; 二、如何理解“虚拟专用网”&#xff1f; 三、IP隧道技术实现虚拟专用网 四、网络地址变换 一、为什么有虚拟专用网&#xff1f; 第一&#xff0c;IPv4只有32位&#xff0c;最多有40亿个全球唯一的IP地址数量不够&#xff0c;无法…

小程序如何完成订阅

小程序如何完成订阅 参考相关文档实践问题处理授权弹窗不再触发引导用户重新授权 参考相关文档 微信小程序实现订阅消息推送的实现步骤 发送订阅消息 小程序订阅消息&#xff08;用户通过弹窗订阅&#xff09;开发指南 实践 我们需要先选这一个模板&#xff0c;具体流程参考…

Oracle OCP认证考试考点详解082系列19

题记&#xff1a; 本系列主要讲解Oracle OCP认证考试考点&#xff08;题目&#xff09;&#xff0c;适用于19C/21C,跟着学OCP考试必过。 91. 第91题&#xff1a; 题目 解析及答案&#xff1a; 关于 Oracle 数据库中的索引及其管理&#xff0c;以下哪三个陈述是正确的&#x…

HuggingFace:基于YOLOv8的人脸检测模型

个人操作经验总结 1、YOLO的环境配置 github 不论base环境版本如何&#xff0c;建议在conda的虚拟环境中安装 1.1、创建虚拟环境 conda create -n yolov8-face python3.9conda create &#xff1a;创建conda虚拟环境&#xff0c; -n &#xff1a;给虚拟环境命名的…

2024-11-15 Element-ui的tab切换中table自适应宽度无法立即100%的问题

前言 今天在写一个统计图表的时候&#xff0c;将所有的table表格和echarts图表放到一个页面中&#xff0c;这样会在纵向上出现滚动条&#xff0c;上下滑动对用户体验不好&#xff0c;于是改成tab切换的形式 遇到的问题 正如标题所述&#xff0c;elementui在tab中使用table时&…

【汇编】c++游戏开发

由一起学编程创作的‘C/C项目实战&#xff1a;2D射击游戏开发&#xff08;简易版&#xff09;&#xff0c; 440 行源码分享来啦~’&#xff1a; C/C项目实战&#xff1a;2D射击游戏开发&#xff08;简易版&#xff09;&#xff0c; 440 行源码分享来啦~_射击c-CSDN博客文章浏览…

由播客转向个人定制的音频频道(1)平台搭建

项目的背景 最近开始听喜马拉雅播客的内容&#xff0c;但是发现许多不方便的地方。 休息的时候收听喜马拉雅&#xff0c;但是还需要不断地选择喜马拉雅的内容&#xff0c;比较麻烦&#xff0c;而且黑灯操作反而伤眼睛。 喜马拉雅为代表的播客平台都是VOD 形式的&#xff0…

k-近邻算法(K-Nearest Neighbors, KNN)详解:机器学习中的经典算法

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

pycharm分支提交操作

一、Pycharm拉取Git远程仓库代码 1、点击VCS > Get from Version Control 2、输入git的url&#xff0c;选择自己的项目路径 3、点击Clone&#xff0c;就拉取成功了 默认签出分支为main 选择develop签出即可进行开发工作 二、创建分支&#xff08;非必要可以不使用&#xf…

PySpark——Python与大数据

一、Spark 与 PySpark Apache Spark 是用于大规模数据&#xff08; large-scala data &#xff09;处理的统一&#xff08; unified &#xff09;分析引擎。简单来说&#xff0c; Spark 是一款分布式的计算框架&#xff0c;用于调度成百上千的服务器集群&#xff0c;计算 TB 、…

算法日记 26-27day 贪心算法

接下来的题目有些地方比较相似。需要注意多个条件。 题目&#xff1a;分发糖果 135. 分发糖果 - 力扣&#xff08;LeetCode&#xff09; n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。 你需要按照以下要求&#xff0c;给这些孩子分发糖果&#xff1a; 每…

Python绘制雪花

文章目录 系列目录写在前面技术需求完整代码代码分析1. 代码初始化部分分析2. 雪花绘制核心逻辑分析3. 窗口保持部分分析4. 美学与几何特点总结 写在后面 系列目录 序号直达链接爱心系列1Python制作一个无法拒绝的表白界面2Python满屏飘字表白代码3Python无限弹窗满屏表白代码4…

【一键整合包及教程】AI照片数字人工具EchoMimic技术解析

在数字化时代&#xff0c;人工智能&#xff08;AI&#xff09;正以前所未有的速度改变着我们的生活。EchoMimic&#xff0c;作为蚂蚁集团旗下支付宝推出的开源项目&#xff0c;不仅为数字人技术的发展掀开了新的一页&#xff0c;更为娱乐、教育、虚拟现实、在线会议等多个领域带…

STM32中断系统

目录 一、中断的基本概念 二、NVIC 1.NVIC的概念 2、NVIC的组成 3、NVIC的应用 4.NVIC的结构 三、外部中断EXTI 1.外部中断的概念 2.EXTI基本结构 四、EXTI外部中断的配置流程 1.开启APB2中的GPIO口/AFIO时钟 2.GPIO配置成输入模式 3.AFIO选择中断引脚 4.EXTI初始…

解锁远程AI工作流:Flowise搭配cpolar跨地域管理AI项目

文章目录 前言1. Docker安装Flowise2. Ubuntu安装Cpolar3. 配置Flowise公网地址4. 远程访问Flowise5. 固定Cpolar公网地址6. 固定地址访问 前言 如今&#xff0c;工作流自动化与人工智能的结合已成为提升生产力的重要手段。Flowise正是这样一个工具&#xff0c;通过直观的拖拽…