【C语言】数据结构——排序(一)

💗个人主页💗
⭐个人专栏——数据结构学习⭐
💫点击关注🤩一起学习C语言💯💫

目录

  • 导读:
  • 数组打印与交换
  • 1. 插入排序
    • 1.1 直接插入排序
      • 1.1.1 基本思想
      • 1.1.2 实现代码
      • 1.1.3 图解
    • 1.2 希尔排序
      • 1.2.1 基本思想
      • 1.2.2 实现代码
      • 1.2.3 图解
  • 2. 选择排序
    • 2.1 直接选择排序
      • 2.1.1 基本思想
      • 2.1.2 实现代码
      • 2.1.3 图解
    • 2.2 堆排序
      • 2.2.1 基本思想
      • 2.2.2 实现代码
      • 图解

导读:

我们在前面学习了单链表,顺序表,栈和队列,小堆,链式二叉树。
今天我们来学习排序,包括直接插入排序,希尔排序,选择排序,堆排序,冒泡排序,快排以及归并排序。
冒泡排序,快排和归并排序我们放在之后分析,今天主要来分析前面的。
关注博主或是订阅专栏,掌握第一消息。

数组打印与交换

为了方便我们来测试每个排序是否完成,我们来写个打印数组和交换两数的函数,方便我们后续的打印与交换。

void PrintArray(int* a, int n)
{for (int i = 0; i < n; i++){printf("%d ", a[i]);}printf("\n");
}void Swap(int* p1, int* p2)
{int tmp = *p1;*p1 = *p2;*p2 = tmp;
}

1. 插入排序

插入排序分为直接插入排序和希尔排序。
基本思想:

把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列。

1.1 直接插入排序

1.1.1 基本思想

直接插入排序是一种简单直观的排序算法,其基本思想是将待排序的元素一个个插入到已排好序的部分中,从而逐步构建已经排序的序列。

  1. 首先,将待排序序列的第一个元素视为已排序部分,可以认为该部分只包含一个元素。
  2. 然后,依次将后面的元素插入到已排序部分中的正确位置。假设要插入的元素为A,那么从已排序部分的最后一个元素开始向前遍历,如果当前元素大于A,则将当前元素后移一位;反之,找到A应该插入的位置,将其插入到该位置。
  3. 重复步骤2,直到所有的元素都被插入到已排序部分中。

直接插入排序的时间复杂度为O(n^2),其中n为待排序序列的长度。辅助空间复杂度为O(1),是一种稳定的排序算法。

1.1.2 实现代码

void InsertSort(int* a, int n)
{int i = 0;for (i = 0; i < n - 1; i++){int end = i;int tmp = a[end + 1];// end往前移动while (end >= 0){// 如果tmp小于a[end] 让a[end]往后移动//也就是移动到end+1的位置if (tmp < a[end]){a[end + 1] = a[end];end--;}else{break;}}//循环结束 此时找到了比tmp小的数值 //把tmp的值放在其后面a[end + 1] = tmp;}
}void TestInsertSort()
{int arr[10] = { 5, 1, 8, 7, 3, 9, 2, 0, 4, 6 };int sz = sizeof(arr) / sizeof(arr[0]);InsertSort(arr, 10);//打印PrintArray(arr, 10);
}
int main()
{TestInsertSort();return 0;
}

1.1.3 图解

在这里插入图片描述

1.2 希尔排序

1.2.1 基本思想

希尔排序(Shell Sort)是一种排序算法,也被称为缩小增量排序。
基本思想是将待排序的数组分成若干个子序列,分别进行插入排序,然后逐步缩小增量,直到增量为1时进行最后一次排序。希尔排序的关键在于如何选择增量序列

  1. 初始化增量序列,通常取数组长度的一半作为初始增量,然后每次再缩小增量为前一次的一半。
  2. 对每个增量序列进行插入排序,从增量序列的第一个元素开始,将其与对应增量序列的后续元素逐个比较并插入到正确的位置。
  3. 缩小增量,重复步骤2,直到增量为1。
  4. 最后一次插入排序完成后,数组已经基本有序,但并不是完全有序的,此时再进行一次插入排序,将数组完全排序。

希尔排序的优点是相对于简单插入排序来说,移动的元素较少,比较次数也相对较少,可以提高排序效率。但是希尔排序的时间复杂度依赖于增量序列的选择,不同的增量序列可能会导致不同的排序效果。

1.2.2 实现代码

void ShellSort(int* a, int n)
{int gap = n;//gap > 1 时是预排序,目的让他接近有序//gap == 1是直接插入排序,目的是让他有序while (gap > 1){gap = gap / 3 + 1;int i = 0;//特别主要i的范围,避免越界for (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;}}
}void TestShellSort()
{int arr[10] = { 5, 1, 8, 7, 3, 9, 2, 0, 4, 6 };int sz = sizeof(arr) / sizeof(arr[0]);ShellSort(arr, 10);PrintArray(arr, 10);
}int main()
{TestShellSort();return 0;
}

1.2.3 图解

在这里插入图片描述

2. 选择排序

选择排序可以分为直接选择排序和堆排序。
基本思想:

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

2.1 直接选择排序

2.1.1 基本思想

直接选择排序算法的基本思想是找到待排序序列中的最小(或最大)元素,将它与序列的第一个元素交换位置,然后再从剩下的未排序序列中找到最小(或最大)元素,与序列的第二个元素交换位置,依次类推,直到整个序列排好序为止。

  1. 遍历待排序序列,假设第一个元素为当前最小(或最大)元素。
  2. 从当前元素的下一个位置开始遍历,如果找到比当前元素更小(或更大)的元素,则将其索引记为最小(或最大)元素的索引。
  3. 遍历完成后,将最小(或最大)元素与当前元素交换位置。
  4. 重复以上步骤,直到整个序列排好序为止。

直接选择排序算法的时间复杂度为O(n^2),其中n为序列的长度。

2.1.2 实现代码

void SelectSort(int* a, int n)
{int begin = 0;int end = n - 1;while (begin < end){int min = begin;int max = begin;for (int i = begin + 1; i <= end; i++){if (a[i] < a[min]){min = i;}if (a[i] > a[max]){max = i;}}// 把最小的值移到最前面Swap(&a[begin], &a[min]);// 如果max=begin代表第一个元素为最大值// 但是经过上个语句已经把第一个元素和最小的元素交换if (max == begin){max = min;}//最大值放到后面Swap(&a[end], &a[max]);++begin;--end;}
}
void TestSelectSort()
{int arr[10] = { 5, 1, 8, 7, 3, 9, 2, 0, 4, 6 };int sz = sizeof(arr) / sizeof(arr[0]);SelectSort(arr, 10);PrintArray(arr, 10);
}int main()
{TestSelectSort();return 0;
}

2.1.3 图解

在这里插入图片描述

2.2 堆排序

2.2.1 基本思想

堆排序算法的基本思想是利用堆的数据结构进行排序。堆是一种特殊的树状数据结构,分为大顶堆和小顶堆两种类型。
对于大顶堆,父节点的值大于或等于子节点的值;对于小顶堆,父节点的值小于或等于子节点的值。堆排序利用堆的性质,使得每次操作的时间复杂度为O(log n)。

  1. 构建初始堆:将待排序序列构建成一个大顶堆。
  2. 将堆顶元素(最大值)与堆的最后一个元素交换位置,然后堆的大小减1。这样就将最大值移到了序列的末尾。
  3. 对新的堆顶元素进行向下调整(即将堆的根节点调整到正确的位置),使得剩余的元素重新构建成一个大顶堆。
  4. 重复步骤2和步骤3,直到堆的大小为1,即完成排序。

主要思想是通过不断地交换堆顶元素和堆的最后一个元素,将最大值依次放到序列的末尾,同时不断地调整堆结构,使得剩余元素保持堆的性质。最后得到的序列就是按照从小到大排序的结果。
堆排序的时间复杂度是O(nlogn),其中n是序列的大小。堆排序是一种不稳定的排序算法,因为在构建大顶堆的过程中,相同大小的元素可能会交换位置。

2.2.2 实现代码

我们之前有实现过堆,所以我们在这里直接引用即可。

// 向下调整
void AdjustDown(int* a, int size, int parent)
{int child = parent * 2 + 1;while (child < size){// 假设左孩子大,如果解设错了,更新一下if (child + 1 < size && 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--){AdjustDown(a, n, i);}int end = n - 1;// 遍历循环while (end > 0){// 将当前最大元素(堆顶)放到数组末尾Swap(&a[0], &a[end]);// 重新调整剩余元素构建的堆AdjustDown(a, end, 0);--end;}
}
void TestHeapSort()
{int arr[10] = { 5, 1, 8, 7, 3, 9, 2, 0, 4, 6 };int sz = sizeof(arr) / sizeof(arr[0]);HeapSort(arr, sz);PrintArray(arr, 10);
}
int main()
{TestHeapSort();return 0;
}

图解

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

机器人中的数值优化之无约束优化

欢迎大家关注我的B站&#xff1a; 偷吃薯片的Zheng同学的个人空间-偷吃薯片的Zheng同学个人主页-哔哩哔哩视频 (bilibili.com) 本文ppt来自深蓝学院《机器人中的数值优化》

人工智能的新篇章:深入了解大型语言模型(LLM)的应用与前景

LLM&#xff08;Large Language Model&#xff09;技术是一种基于深度学习的自然语言处理技术&#xff0c;旨在训练能够处理和生成自然语言文本的大型模型。 LLM 技术的核心思想是使用深度神经网络&#xff0c;通过大规模的文本数据预训练模型&#xff0c;并利用这些预训练模型…

伪装目标检测的算术不确定性建模

Modeling Aleatoric Uncertainty for Camouflaged Object Detection 伪装目标检测的算术不确定性建模背景贡献实验方法Camouflaged Object Detection Network&#xff08;伪装目标检测框架&#xff09;Online Confidence Estimation Network&#xff08;在线置信度估计网络&…

【Week-P3】CNN天气识别

文章目录 一、环境配置二、准备数据三、搭建网络结构四、开始训练五、查看训练结果六、总结6.1 不改变学习率的前提下&#xff0c;将训练epoch分别增加到60、70、80、90&#xff08;1&#xff09;epoch 50 的训练情况如下&#xff1a;&#xff08;2&#xff09;epoch 60 的训…

Redis哨兵sentinel

是什么&#xff1f; 哨兵巡查监控后台master主机是否故障&#xff0c;如果故障根据投票数自动将某一个slave库变为master&#xff0c;就行对外服务&#xff0c;称为无人值守运维 能干嘛&#xff1f; 主从监控&#xff1a;监控主从redis库是否正常工作 消息通知&#xff1a;…

C++面向对象(OOP)编程-C++11新特性详解

C11作为一个重要的版本&#xff0c;引入了很多新的特性&#xff0c;解决了C语言本身很多遗留的内存泄露问题&#xff0c;并且提供了很多比较灵活的用法。引入的auto&#xff0c;智能指针、线程机制都使得C语言的灵活性、安全性、并发性有了很大的提升。 本文会比较详细的介绍C1…

YOLOv5改进 | 2023注意力篇 | FocusedLinearAttention聚焦线性注意力

一、本文介绍 本文给大家带来的改进机制是FLAttention&#xff08;聚焦线性注意力&#xff09;是一种用于视觉Transformer模型的注意力机制(但是其也可以用在我们的YOLO系列当中从而提高检测精度)&#xff0c;旨在提高效率和表现力。其解决了两个在传统线性注意力方法中存在的…

MySQL 数据库归档工具pt-archive 与归档数据的安全存储 与 为什么每次归档都少数...

开头还是介绍一下群&#xff0c;如果感兴趣PolarDB ,MongoDB ,MySQL ,PostgreSQL ,Redis, Oceanbase, Sql Server等有问题&#xff0c;有需求都可以加群群内&#xff0c;可以解决你的问题。加群请联系 liuaustin3 &#xff0c;&#xff08;共1780人左右 1 2 3 4 5&#xff0…

java球队信息管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 java Web球队信息管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql5…

开源预约挂号平台 - 从0到上线

文章目录 开源预约挂号平台 - 从0到上线演示地址源码地址可以学到的技术前端技术后端技术部署上线开发工具其他技术业务功能 项目讲解前端创建项目 - 安装PNPM - 使用VSCODE - 安装插件首页顶部与底部 - 封装组建 - 使用scss左右布局中间内容部分路由 - vue-routerBANNER- 走马…

HCIA-Datacom题库(自己整理分类的)——OSPF协议判断

1.路由表中某条路由信息的Proto为OSPF则此路由的优先级一定为10。√ 2.如果网络管理员没有配置骨干区域,则路由器会自动创建骨干区域&#xff1f; 路由表中某条路由信息的Proto为OSPF&#xff0c;则此路由的优先级一定为10。 当两台OSPF路由器形成2-WAY邻居关系时&#xff0…

小梅哥Xilinx FPGA学习笔记18——专用时钟电路 PLL与时钟向导 IP

目录 一&#xff1a;IP核简介&#xff08;具体可参考野火FPGA文档&#xff09; 二&#xff1a; 章节导读 三&#xff1a;PLL电路原理 3.1 PLL基本实现框图 3.2 PLL倍频实现 3.3 PLL分频实现 四: 基于 PLL 的多时钟 LED 驱动设计 4.1 配置 Clocking Wizard 核 4.2 led …

useReducer 的奇妙世界:探索 React 状态管理的新境界(上)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

首发卡密引流系统 支持短视频点赞/关注获取卡密

搭建教程&#xff1a; 环境要求&#xff1a;Nginx、MySQL 5.6、PHP 5.6 步骤&#xff1a; 将压缩包解压至网站根目录。 打开域名/install&#xff0c;按照提示填写数据库信息进行安装。 管理后台&#xff1a; URL&#xff1a;域名/admin 账号密码&#xff1a;admin/123456 …

人机协同编程pyqt/pyside界面开发——第一章pyqt/pyside编程基础

环境安装:https://www.bilibili.com/video/BV1wc411D7WF/ 特别说明本文章适用于出于科研需要,用到这部分技术的,对其中的技术细节并未作过多的探究。而把侧重点放在科研工作者,如何通过这项技术的使用来达到自己的目的。尽可能的做到需要什么讲什么,用到什么学什么。这可以…

关于“Python”的核心知识点整理大全48

目录 world_population.py 16.2.5 制作世界地图 americas.py 16.2.6 在世界地图上呈现数字数据 na_populations.py 16.2.7 绘制完整的世界人口地图 world_population.py 16.2.8 根据人口数量将国家分组 world_population.py 16.2.9 使用 Pygal 设置世界地图的样式 w…

腾讯云轻量服务器和云服务器区别对比(超详细)

腾讯云轻量服务器和云服务器CVM该怎么选&#xff1f;不差钱选云服务器CVM&#xff0c;追求性价比选择轻量应用服务器&#xff0c;轻量真优惠呀&#xff0c;活动 https://curl.qcloud.com/oRMoSucP 轻量应用服务器2核2G3M价格62元一年、2核2G4M价格118元一年&#xff0c;540元三…

elasticsearch系列四:集群常规运维

概述 在使用es中如果遇到了集群不可写入或者部分索引状态unassigned&#xff0c;明明写入了很多数据但是查不到等等系列问题该怎么办呢&#xff1f;咱们今天一起看下常用运维命令。 案例 起初我们es性能还跟得上&#xff0c;随着业务发展壮大&#xff0c;发现查询性能越来越不…

YOLOv5改进 | 2023Neck篇 | CCFM轻量级跨尺度特征融合模块(RT-DETR结构改进v5)

一、本文介绍 本文给大家带来的改进机制是轻量级跨尺度特征融合模块CCFM&#xff08;Cross-Scale Feature Fusion Module&#xff09;其主要原理是&#xff1a;将不同尺度的特征通过融合操作整合起来&#xff0c;以增强模型对于尺度变化的适应性和对小尺度对象的检测能力。我将…

Python - 深夜数据结构与算法之 Binary Search

目录 一.引言 二.二分查找的简介 1.查找条件 2.代码模版 3.查找示例 三.经典算法实战 1.Search-Rotated-List [33] 2.Sqrt-X [69] 3.Search-2D-Matrix [74] 4.Find-Rotated-Min [153] 5.Valid-Perfect-Square [367] 四.总结 一.引言 前面介绍了二叉树和堆&#xf…