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

数据结构-排序

本节目标:

1.排序的概念及其运用
2.常见排序算法的实现
3.排序算法复杂度及稳定性分析
 

1.排序的概念及其应用 

1.1排序的概念 

排序就是按照某个我们设定的关键字,或者关键词,递增或者递减,完成这样的操作就是排序。

1.2排序的应用 

排序在日常生活中很常见的,想前几天刚出的软科高校排名,就用到了排序的思想,关键词就是软科,按照递增的顺序排列。如下图所示:

 

以及我们上淘宝的时候,也会用到排序的思想,我们想买个手机,筛选条件,按照个人选择不同给出的答案不同,用的人注重品牌,有的人注重价格,有的女孩更注重像素,如下图所示: 

 

1.3常见的排序算法 

2.常见的排序算法实现 

2.1插入排序 

2.1.1基本思想 

其实插入排序的思想,几乎我们每个人都会,插入排序就像我们打的扑克,从未知的一副牌中,我们开始往手里揭牌,拿起第一张放在手中,再次拿起一张牌的时候,就要和手里的牌对比,如果比手里的牌大就往后排,如果比手里的牌小的话,就排在这张牌之前,以此类推。一副牌拿完之后,我们手里的牌也就按照递增的顺序排好了。 

2.1.2直接插入排序: 

 当插入第i(i>=1)个元素时,前面的array[0],array[1],…,array[i-1]已经排好序,此时用array[i]的排序码与array[i-1],array[i-2],…的排序码顺序进行比较,找到插入位置即将array[i]插入,原来位置上的元素顺序后移。图解如下:

当插入的数比前一个数字还大时:

当插入的数字比数组中所有的数都要小的时候: 

 

 动态图解如下:

  

插入排序

代码实现:

void InsertSort(int* a, int n)
{//遍历数组中所有元素for (int i = 1; i < n; i++){//单趟排序int end = i - 1;int temp = a[i];//temp存储的是元素数值while (end >= 0)//一直比较到 数组第一个元素完成{if (temp < a[end]){a[end + 1] = a[end];--end;}else // 包含两种情况,一种temp比所有元素都大,另一种temp比所有元素都小{break;}}a[end + 1] = temp;}
}

 结果对比:

在主程序中,我们调用插入排序函数,并查看最终是否实现 有序排序。 

void TestInsertSort()
{int a[] = { 3,5,1,6,2,3,7,9,0,8 };PrintArray(a, sizeof(a) / sizeof(int));InsertSort(a, sizeof(a) / sizeof(int));PrintArray(a, sizeof(a) / sizeof(int));
}int main()
{TestInsertSort();return 0;
}

 

 分析总结:

直接插入排序时间复杂度:最坏情况下,逆序有序,每个元素都要一个个比较,最终形成等差数列, 1 +2 +3 + ........N 时间复杂度为 O(N^2) ;最好的情况下,有序,1 + 1 + 1 + .......1时间复杂度为O(N)  总结来看 对于插入排序,元素集合越接近有序,算法时间效率越高。

2.1.3希尔排序(缩小增量排序):  

     希尔排序也是插入排序的一种,它又称缩小增量排序法,他其实是在插入排序上的一种优化,通过上面的分析,我们知道插入排序时间复杂度最好的情况,也就是接近有序的时候,他的时间复杂度为 O(N),最坏的情况下 无序的时候 为 O(N^2)。如果我们能先让数组接近有序之后,在对他进行排序,会大大减小算法时间复杂度。所以希尔大佬就研究出了希尔排序。

它的实现主要通过两步骤,第一步:预排序,让数组接近有序,第二步:插入排序。

分组预排:

  将无序的数组,按照间隙gap进行分组,将数组分成n/gap组,然后分组进行插入排序,因为有了gap所以时间复杂度会减小,如下图所示:

 

 分组直接插入排序:

 

gap为3排序实现结果: 

 当gap依次减小,数组慢慢接近有序,最后gap为1时候,数组已经近似有序,再插入排序依次,数组就会实现有序的同时,算法时间复杂度最低。

代码实现:

void ShellSort(int* a, int n)
{int gap = 3;for (int j = 0; j < gap; j++){for (int i = j; i <n- gap; i += gap){//单趟排序int end = i;int temp =a[i + gap];//temp存储的是元素数值 i + gap 要在数组之内 不可以越界while (end >= 0)//一直比较到 数组第一个元素完成{if (temp < a[end]){a[end + gap] = a[end];end = end - gap;}else // 包含两种情况,一种temp比所有元素都大,另一种temp比所有元素都小{break;}}a[end + gap] = temp;}}}

 改进一下:

void ShellSort(int* a, int n)
{int gap = 3;for (int i = 0; i <n- gap; i ++){//单趟排序int end = i;int temp =a[i + gap];//temp存储的是元素数值 i + gap 要在数组之内 不可以越界while (end >= 0)//一直比较到 数组第一个元素完成{if (temp < a[end]){a[end + gap] = a[end];end = end - gap;}else // 包含两种情况,一种temp比所有元素都大,另一种temp比所有元素都小{break;}}a[end + gap] = temp;}
}

 我们发现gap越大虽然,跑的很快但是不接近有序,gap越小跑的慢,但是接近有序,所以需要设计合适的gap,减少复杂度的同时,保证最后一次排序 gap为1,通常 我们设计的gap,为n / 2,或者 n/3 - 1。

具体代码如下:

void ShellSort(int* a, int n)
{int gap =  n ;while (gap > 1){gap /= 2;//gap = gap/3 - 1;for (int i = 0; i <n- gap; i ++){//单趟排序int end = i;int temp =a[i + gap];//temp存储的是元素数值 i + gap 要在数组之内 不可以越界while (end >= 0)//一直比较到 数组第一个元素完成{if (temp < a[end]){a[end + gap] = a[end];end = end - gap;}else // 包含两种情况,一种temp比所有元素都大,另一种temp比所有元素都小{break;}}a[end + gap] = temp;}}
}

 结果:

 

分析总结: 

 希尔排序的时间复杂度分析:

 

 对于外层:是我们熟悉的二分或者三分 复杂度 最后为logN

 对于内部两层,当gap很大时候,可以看成N,当gap很小时,经过多次预排序,接近有序 复杂度也是N,我们在以gap/3分析中间的变化:图解分析如下:

所以 我们可以说 希尔排序时间复杂度近似 N*logN 但是每次预排都会有增益,他分组之后复杂度应该近似下图:

所以,虽然希尔的时间复杂度近似在N*logN这个等级,但是要比其大一点,查阅相关资料,对于希尔时间复杂度,通常是这么说的

 

2.2选择排序 

2.2.1基本思想:

 每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完 。

2.2.2直接选择排序

在元素集合array[i]--array[n-1]中选择关键码最大(小)的数据元素
若它不是这组元素中的最后一个(第一个)元素,则将它与这组元素中的最后一个(第一个)元素交换在剩余的array[i]--array[n-2](array[i+1]--array[n-1])集合中,重复上述步骤,直到集合剩余1个元素

 直接选择排序单趟寻找到最大的或最小的,实现升序的话就与最左边的交换,降序就与最右边交换,我们可以用代码实现左右共同查找的方式。如下所示:

void SelectSort(int* a, int n)
{//初试状态int left = 0;int right = n - 1;while (left < right){//取最小值,最大值下标为最左边的 位置int min = left, max = left;for (int i = left + 1; i < right; i++){if (a[i] < a[min]){min = i;}else if (a[i] > a[max]){max = i;}}swap(&a[left], &a[min]);if (left == max) //防止出现 left位置上放的是最大值{max = min;}swap(&a[right], &a[max]);left++;right--;}
}

结果分析:

选择排序的时间复杂度,还是比较low的不管怎么选,都是O(N^2) 。

2.2.3堆排序

堆排序是我们的老朋友了,堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。它是通过堆来进行选择数据。需要注意的是排升序要建大堆,排降序建小堆。

代码如下:

//向下调整
void AjustDown(int* a, int n, int parent)
{int child = parent * 2 + 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 = parent * 2 + 1;}else{break;}}}
void HeapSort(int* a, int n)
{for (int i = (n - 1 - 1) / 2; i >= 0; i--) // 从最后一个节点的父亲 开始向下调整 保证父亲比孩子大{AjustDown(a, n, i);}int end = n - 1;while (end > 0){swap(&a[end], &a[0]); // 交换 根节点 和最后一个位置的数值AjustDown(a, end, 0);--end;}
}

总结:

堆排的时间复杂度 ,我们在堆排序那个章节推过,这里我直接说结论:o(N * logN)。
 

相关文章:

数据结构-排序

本节目标&#xff1a; 1.排序的概念及其运用 2.常见排序算法的实现 3.排序算法复杂度及稳定性分析 1.排序的概念及其应用 1.1排序的概念 排序就是按照某个我们设定的关键字&#xff0c;或者关键词&#xff0c;递增或者递减&#xff0c;完成这样的操作就是排序。 1.2排…...

ROS话题通信自定义+发布订阅代码--03

话题通信自定义msg 在 ROS 通信协议中&#xff0c;数据载体是一个较为重要组成部分&#xff0c;ROS 中通过 std_msgs 封装了一些原生的数据类型,比如:String、Int32、Int64、Char、Bool、Empty… 但是&#xff0c;这些数据一般只包含一个 data 字段&#xff0c;结构的单一意味…...

【MySQL】实验七 视图

文章目录 1. 建立city值为上海、北京的顾客视图2. 建立城市为上海的客户2016年的订单信息视图3. SQL视图:建立视图AVG_CJ4. SQL视图:建立视图IS_STUDENT5. SQL视图:建立视图CJ_STUDENT6. SQL视图:根据视图CJ_STUDENT创建视图CJ_TJ1. 建立city值为上海、北京的顾客视图 建立…...

Linux常见操作命令【三】

一、系统资源 1.1 ps&#xff08;process staus&#xff09; ps -ef e显示所有进程、f全格式 ps -aux 显示所有包含其他使用者的进程 ps -ef | grep CCC 查找含有CCC进程的格式 ps -u username 显示指定进程用户信息1.2 kill kill 12345 杀死进程12345 kill -KILL…...

C-关键字(下)

文章目录循环控制switch-case-break-defaultdo-while-forgetchar()break-continuegotovoidvoid*returnconstconst修饰变量const修饰数组const修饰指针指针补充const 修饰返回值volatilestruct柔型数组union联合体联合体空间开辟问题利用联合体的性质,判断机器是大端还是小端enu…...

关于电商商品数据API接口列表,你想知道的(详情页、Sku信息、商品描述、评论问答列表)

目录 一、商品数据API接口列表 二、商品详情数据API调用代码item_get 三、获取sku详细信息item_sku 四、获得淘宝商品评论item_review 五、数据说明文档 进入 一、商品数据API接口列表 二、商品详情数据API调用代码item_get <?php// 请求示例 url 默认请求参数已经URL…...

232:vue+openlayers选择左右两部分的地图,不重复,横向卷帘

第232个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+openlayers项目中自定义js实现横向卷帘。这个示例中从左右两个选择框中来选择不同的地图,做了不重复的处理,即同一个数组,两部分根据选择后的状态做disabled处理,避免重复选择。 直接复制下面的 vue+openlayers…...

溯源取证-内存取证 高难度篇

今天的场景依然是windows场景&#xff0c;只不过此次场景分为两个镜像&#xff0c;本次学习主要学习如何晒别钓鱼邮件、如何提取钓鱼邮件、如何修复损坏的恶意文件、如何提取DLL动态链接库文件 本次需要使用的工具&#xff1a; volatility_2.6_lin64_standalone readpst clams…...

JAVA语言中的代理模式

代理可以进一步划分为静态代理和动态代理&#xff0c;代理模式在实际的生活中场景很多&#xff0c;例如中介、律师、代购等行业&#xff0c;都是简单的代理逻辑&#xff0c;在这个模式下存在两个关键角色&#xff1a; 目标对象角色&#xff1a;即代理对象所代表的对象。 代理…...

最后一步:渲染和绘制

浏览器的工作步骤如下&#xff1a; URL>字符流>词&#xff08;token&#xff09;流>DOM树&#xff08;不含样式信息的 DOM&#xff09;>DOM树CSS规则&#xff08;含样式信息的 DOM&#xff09;>根据样式信息&#xff0c;计算了每个元素的位置和大小>根据这些…...

C++类和对象终章——友元函数 | 友元类 | 内部类 | 匿名对象 | 关于拷贝对象时一些编译器优化

文章目录&#x1f490;专栏导读&#x1f490;文章导读&#x1f337;友元&#x1f33a;概念&#x1f33a;友元函数&#x1f341;友元函数的重要性质&#x1f33a;友元类&#x1f341;友元类的重要性质&#x1f337;内部类&#xff08;不常用&#xff09;&#x1f33a;内部类的性…...

拼多多按关键字搜索商品 API

一、拼多多平台优势&#xff1a; 1、独创拼团模式 拼团拼单是拼多多独创的营销模式&#xff0c;其特点是基于人脉社交的裂变传播&#xff0c;非常具有传播性。 由于本身走低价路线&#xff0c;加上拼单折扣&#xff0c;商品的分享和人群裂变效果非常明显&#xff0c;电商前期…...

全链路日志追踪

背景 最近线上的日志全局追踪 traceId 不好使了&#xff0c;不同请求经常出现重复的 traceId&#xff0c;或者通过某个请求的 traceId 追踪搜索&#xff0c;检索出了与该请求完全不相干的日志。我领导叫我去排查解决这个问题&#xff0c;这里我把我排查的过程思路以及如何解决…...

ZYNQ:【1】深入理解PS端的TTC定时器(Part1:原理+官方案例讲解)

碎碎念&#xff1a;好久不见&#xff0c;甚是想念&#xff01;本期带来的是有关ZYNQ7020的内容&#xff0c;我们知道ZYNQ作为一款具有硬核的SOC&#xff0c;PS端很强大&#xff0c;可以更加便捷地实现一些算法验证。本文具体讲解一下里面的TTC定时器&#xff0c;之后发布的Part…...

蓝牙设备如何自定义UUID

如何自定义UUID 所有 BLE 自定义服务和特性必须使用 128 位 UUID 来识别&#xff0c;并且要确保基本 UUID 与 BLE 定义的基本 UUID&#xff08;00000000-0000-1000-8000-00805F9B34FB&#xff09;不一样。基本 UUID 是一个 128 位的数值&#xff0c;根据该值可定义标准UUID&am…...

好看的html登录界面,

界面效果&#xff1a; 代码&#xff1a; <!DOCTYPE html> <html><head><title>Login Page</title><style>body {background-color: #f2f2f2;font-family: Arial, sans-serif;}form {background-color: #fff;border-radius: 5px;box-shado…...

Java模拟星空

目录 前言 JavaFX基础 1. GraphicsContext 2. AnimationTimer 代码实现 完整代码 前言 看了Python模拟星空很漂亮&#xff0c;Java也应该必须有一个&#xff01; 环境&#xff1a;只需要JDK1.8就好&#xff01;不需要外部包&#xff01;&#xff01;&#xff01; Jav…...

YGG 代表 Web3 Gaming 参加 2023 年游戏开发者大会

Yield Guild Games&#xff08;YGG&#xff09;在 2023 年 3 月 20 日至 24 日在加州旧金山举行的游戏开发者大会&#xff08;GDC&#xff09;上大显身手&#xff0c;这是游戏开发者的重要交流学习活动。虽然 GDC 本身提供了多种多样的活动&#xff0c;包括讲座、小组讨论、圆桌…...

水库安全运行智慧管理平台解决方案筑牢防汛“安全墙”

解决方案 水库安全运行智慧管理系统解决方案&#xff0c;系统主要由降雨量监测站、水库水位监测站、大坝安全监测中的渗流量、渗流压力和变形监测站及视频和图像监测站等站点组成&#xff0c;同时建立规范、统一的监测平台&#xff0c;集数据传输、信息共享、数据储存于一体&a…...

Exchange升级部署方案

目录 前言 一、需求分析 二、升级前准备 1.备份当前 Exchange Server 数据...

ESP32读取DHT11温湿度数据

芯片&#xff1a;ESP32 环境&#xff1a;Arduino 一、安装DHT11传感器库 红框的库&#xff0c;别安装错了 二、代码 注意&#xff0c;DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练

前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1)&#xff1a;从基础到实战的深度解析-CSDN博客&#xff0c;但实际面试中&#xff0c;企业更关注候选人对复杂场景的应对能力&#xff08;如多设备并发扫描、低功耗与高发现率的平衡&#xff09;和前沿技术的…...

2.Vue编写一个app

1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

Rapidio门铃消息FIFO溢出机制

关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系&#xff0c;以下是深入解析&#xff1a; 门铃FIFO溢出的本质 在RapidIO系统中&#xff0c;门铃消息FIFO是硬件控制器内部的缓冲区&#xff0c;用于临时存储接收到的门铃消息&#xff08;Doorbell Message&#xff09;。…...

九天毕昇深度学习平台 | 如何安装库?

pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子&#xff1a; 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...

IP如何挑?2025年海外专线IP如何购买?

你花了时间和预算买了IP&#xff0c;结果IP质量不佳&#xff0c;项目效率低下不说&#xff0c;还可能带来莫名的网络问题&#xff0c;是不是太闹心了&#xff1f;尤其是在面对海外专线IP时&#xff0c;到底怎么才能买到适合自己的呢&#xff1f;所以&#xff0c;挑IP绝对是个技…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用

文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么&#xff1f;1.1.2 感知机的工作原理 1.2 感知机的简单应用&#xff1a;基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...

力扣热题100 k个一组反转链表题解

题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...

0x-3-Oracle 23 ai-sqlcl 25.1 集成安装-配置和优化

是不是受够了安装了oracle database之后sqlplus的简陋&#xff0c;无法删除无法上下翻页的苦恼。 可以安装readline和rlwrap插件的话&#xff0c;配置.bahs_profile后也能解决上下翻页这些&#xff0c;但是很多生产环境无法安装rpm包。 oracle提供了sqlcl免费许可&#xff0c…...