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

算法 -排序 -插入,选择

博客主页:【夜泉_ly】
本文专栏:【算法】
欢迎点赞👍收藏⭐关注❤️

在这里插入图片描述

文章目录

  • 💡插入排序
    • 1. ➡️直接插入排序
      • 📖简介
      • 💡实现思路
      • 📝具体示例
      • 🖼️示意图
      • 💻代码实现
    • 2. ⬆️希尔排序
      • 📖简介
      • 💡实现思路
      • 🖼️示意图
      • 💻代码实现
  • 💡选择排序
    • 1. 🔄选择排序
      • 📖简介
      • 💡实现思路
      • 🖼️示意图
      • 💻代码实现
    • 2. 🏰堆排序
      • 🖼️示意图

💡插入排序

插入排序可以分为直接插入排序和希尔排序。

1. ➡️直接插入排序

📖简介

直接插入排序常用于处理数据量较小的情况,其思想和打牌类似,都是将新元素插入到有序数组。
时间复杂度为 O ( N 2 ) O(N^2) O(N2) 。如果数据量过大,直接插入排序会因频繁的挪动数据降低效率。

💡实现思路

实现的思路:

  • 定义一个指针 end ,初始为0,表示已排序数组的结束位置。
  • 取牌,用一个临时变量 tmp 存储 end + 1处的值,表示待插入的值。
  • 挪牌,将已排序的数组中小于 tmp 的向后挪动一个位置。(这里 end + 1 的值已被保存,可以直接覆盖)
    • 定义 cur 指向 end
    • 如果 cur 处的值大于 tmp,将该值向后挪动一位,然后cur--
    • 结束条件为 cur <= -1 或者 cur 处的值小于等于 tmp
  • 插入,将 tmp 插入 cur + 1处,然后 end++
  • 结束条件为 end >= size - 1 ,即所有元素都已排序。

📝具体示例

下面是具体示例:
待排序数组:
在这里插入图片描述
首先,定义一个指针 end ,指向 0 处,表示已排序手牌:
在这里插入图片描述
取牌,用一个临时变量 tmp 存储 end + 1处的值,表示待插入的手牌:
在这里插入图片描述
挪牌:(当cur == -1,停止挪牌)
在这里插入图片描述
插入:(将tmp插入cur + 1处)
在这里插入图片描述

第二轮取牌加挪牌:(当cur处的值小于 tmp,也停止挪牌)
在这里插入图片描述
插入:
在这里插入图片描述
之后,重复上述过程即可。


🖼️示意图

插入排序 − 示意图 插入排序 -示意图 插入排序示意图

在这里插入图片描述)


💻代码实现

最后是代码实现:

void InsertSort(int* arr, int size)
{int end = 0;while (end != size - 1){int tmp = arr[end + 1];int cur = end;while (cur > -1 && arr[cur] > tmp){arr[cur + 1] = arr[cur];cur--;}arr[cur + 1] = tmp;end++;}
}

2. ⬆️希尔排序

📖简介

希尔排序是插入排序的升级版,本质是通过分组进行插入排序,可以将较大的数据尽快的挪到数组后面,从而减少挪动数据的次数,提高了效率。
时间复杂度大约为 O(N ^ 1.3),具体时间复杂度会随分组的标准而变。

💡实现思路

实现的思路:

  • 定义 gap ,初始值为 size/3 + 1,间隔为 gap 的数被分到一组。
  • 对每组进行插入排序
    • 定义一个指针 end ,初始为0,表示已排序数组的结束位置。
    • 取牌,用一个临时变量 tmp 存储 end + gap处的值,表示待插入的值。
    • 挪牌,将已排序的数组中小于 tmp 的向后挪动一个位置。(这里 end + gap 的值已被保存,可以直接覆盖)
      • 定义 cur 指向 end
      • 如果 cur 处的值大于 tmp,将该值向后挪动一位,然后cur -= gap
      • 结束条件为 cur <= -1 或者 cur 处的值小于等于 tmp
    • 插入,将 tmp 插入 cur + gap处,然后 end++
    • 结束条件为 end >= size - gap ,即所有元素都已排序。
  • gap = gap/3 + 1
  • gap == 1 为最后一次排序,此时变为直接插入排序。(经过了预处理,此时的直接插入排序效率大大提高)

🖼️示意图

希尔排序 − 示意图 希尔排序 -示意图 希尔排序示意图
在这里插入图片描述


💻代码实现

下面是代码实现:

void ShellSort(int* arr, int size)
{int gap = size;while (gap != 1){gap = gap / 3 + 1;int end = 0;while (end < size - gap){int tmp = arr[end + gap];int cur = end;while (cur > -1 && arr[cur] > tmp){arr[cur + gap] = arr[cur];cur -= gap;}arr[cur + gap] = tmp;end++;}}
}

💡选择排序

选择排序分为选择排序和堆排序。

1. 🔄选择排序

📖简介

选择排序是一种比较简单直观的排序,其思想就是不断从待排序的数组中选出符合要求的数据。

由于每次选数要遍历一遍数组,而重复次数为数组长度,因此时间复杂度为 O ( N 2 ) O(N^2) O(N2)。实际用处不大,因为它不会管数据长什么样,都会从头遍历到尾,不如直接插入排序。这也给了我们一个启示:斗地主发牌时,要边拿牌边排序(插入排序),不能拿到一把牌后再排序(选择排序)。

💡实现思路

实现的思路:

  • 定义一个指针 end ,初始为-1,表示已排序数组的结束位置。(最开始还没有选出最小值,所以是 -1)
  • 选择,用一个指针 curend + 1遍历到尾,用另一个指针 min 记录最小值的位置。
  • 交换,将 end + 1 处的值与 min 处的值交换。
  • end++,继续下一轮。
  • 结束条件为 end >= size - 1 ,即所有元素都已排序。

🖼️示意图

选择排序 − 示意图 选择排序 -示意图 选择排序示意图
在这里插入图片描述


💻代码实现

下面是代码实现:

void SelectSort(int* arr, int size)
{int end = -1;while (end < size - 1){int cur = end + 1;int min = cur;while (cur < size){if (arr[cur] < arr[min])min = cur;cur++;}swap(arr[end + 1], arr[min]);end++;}
}

当然,还可以稍微优化一下,即将 end 改为 left ,同时增加一个指针 right
实现思路:

  • 定义一个指针 left ,初始为-1,表示选出最小元素的结束位置。
  • 定义一个指针 right ,初始为size,表示选出最大元素的结束位置。
  • 选择,用一个指针 curleft + 1遍历到 right - 1,用两个指针 minmax 记录最小、大值的位置。
    • 交换时,如果 left + 1处的值为最大值,即left + 1 == max,交换left + 1min后,left + 1处变为最小值,min处变为最大值。因此,为了保证交换的正确性,在这种情况下可以让 max = min
  • 交换,将 left + 1 处的值与 min 处的值交换,将 right - 1 处的值与 max 处的值交换。
  • left++,right--,继续下一轮。
  • 结束条件为 left >= right ,即所有元素都已排序。

下面是代码实现:

void SelectSort2(int* arr, int size)
{int left = -1, right = size;while (left < right){int cur = left + 1;int max = cur, min = cur;while (cur < right){if (arr[cur] > arr[max])max = cur;if (arr[cur] < arr[min])min = cur;cur++;}if (max == left + 1)max = min;swap(arr[left + 1], arr[min]);swap(arr[right - 1], arr[max]);left++, right--;}
}

2. 🏰堆排序

堆排序,这个我在数据结构-堆-详解中讲过了,此处略。


🖼️示意图

堆排序 − 示意图 堆排序 -示意图 堆排序示意图
在这里插入图片描述


在这里插入图片描述


希望本篇文章对你有所帮助!并激发你进一步探索编程的兴趣!
本人仅是个C语言初学者,如果你有任何疑问或建议,欢迎随时留言讨论!让我们一起学习,共同进步!


http://www.mrgr.cn/news/68635.html

相关文章:

  • 地图框架之mapbox——(二)
  • IT部门如何平衡业务需求与公司战略,IT的目标到底是让谁满意?
  • SQL server增删改查语句和实例
  • Kafka 源码 KRaft 模式本地运行
  • ubuntu 22.04 server 安装 mysql 5.7.40 LTS
  • J2EE平台
  • 2024外贸独立站指南:3个提高转化的问题所在!
  • 反反爬-课上实验
  • LLM | 论文精读 | CVPR | 基于问题驱动图像描述的视觉问答增强引言
  • 【专题】2024年全球生物医药交易报告汇总PDF洞察(附原数据表)
  • 企业高效运转秘诀,揭秘工单系统双重价值
  • 【vue2.7.16系列】手把手教你搭建后台系统__刷新问题(17)
  • SpringMVC学习记录(五)之SpringMVC其他扩展
  • 关于我、重生到500年前凭借C语言改变世界科技vlog.16——万字详解指针概念及技巧
  • 44.第二阶段x86游戏实战2-C++HOOK提取游戏lua
  • LeetCode:485.最大连续1的个数——简单题简单做
  • Python matplotlib库 grid()网格线函数讲解
  • echarts设置tooltip宽高
  • AI和大模型技术在网络脆弱性扫描领域的最新进展与未来发展趋势
  • Docker配置及简单应用
  • 揭秘集装箱箱号自动识别原理,箱号识别算法
  • 智慧城市路面垃圾识别系统产品介绍方案
  • 5万加购上线即断货,双11洗衣机品类打破增长难关
  • npx创建项目时,error fetch failed.TypeError: fetch failed
  • Linux服务器修改网络配置
  • 2.1 >关于桌面环境