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

【初阶数据结构】详解插入排序 希尔排序(内含排序的概念和意义)

点点关注

文章目录

  • 前言
  • 1. 排序的概念及其应用
    • 1.1 排序的概念
    • 1.2 排序的应用
  • 2. 插入排序
    • 2.1 基本思想
    • 2.2 插入排序的代码实现
    • 2.3 插入排序算法总结
  • 3. 希尔排序
    • 3.1 基本思想
    • 3.2 希尔排序的代码实现
    • 3.3 希尔排序的特征总结

前言

初级数据结构系列已经进入到了排序的部分了。相信大家听到"排序"这个词,第一时间会想到冒泡排序,因为这个是大家学习C语言时,遇到的第一个真正意义上的排序算法。那么在这个系列中,有八大排序算法,都会给大家一一讲解它的实现思路,以及对应的代码实现!

那么在本文中,我们就开启排序算法的第一个章节 —— “插入排序” 和 “希尔排序”。
哈哈哈

1. 排序的概念及其应用

在正式讲解插入排序和希尔排序之前,我要带着大家理解我们为什么需要排序?以及排序在我们生活中有什么应用?学完这些之后,大家也许对排序算法就不会那么迷茫了。

1.1 排序的概念

排序:所谓排序,就是时一串记录,按照我们特定且可行的想法,递增或递减的排列起来的操作。

排序是一项操作!

1.2 排序的应用

看到这里,大家可以打开京东商城,当你想买一台新的手机时,却不知如何入手。你可能会选择按好评数来进行排序,从而选出好评率最高的手机。在这个过程,就用到了排序的思想。

在这里插入图片描述

再如,我们的大学按照教学资源以及教学能力,也能进行排序:
大学排名
当然,生活中还有很多例子都是用到了排序的思想。这就是所谓处处有排序!

好了,在了解完排序的重要性之后,我们就要正式迈入学习插入排序和希儿排序的殿堂中了。
哈哈哈

2. 插入排序

插入排序,通常我们也称它为直接插入排序。

2.1 基本思想

在一个有序的数组中,按照一定的规则插入待排序的数字。

详细一点说的话,就是:

算法思路:
先从单趟排序讲起,我们可以选择待插入的数字与从排序好的数组末端的数进行比较。若发现该值比待插入的数字要大,则将盖子往后挪动一位,接着继续往前面进行比较。若发现该值比待插入的数字要小,说明该值的后面一个位置就是待插入数字应该插入的位置,我们就可以结束循环了。

单趟排序讲完了之后,就可以将一个完整的插入排序了。
如果你真的认证解读了单趟插入排序的思路,你会发现插入排序不过如此!

其实一个完成的插入排序就是在循环地跑单趟排序,循环地初始条件为从待插入数组的第二个元素小标开始。每当单趟排序跑完之后,我们都得设置循环条件的值(一开始比较数组末端的位置)。因为你已经排好了部分数组,每当来一个新数字就得在拍好数组中插入,重复上述过程。

下面我给大家展示插入排序算法的动图,希望大家能够结合上述的话语,仔细观看:

插入排序

2.2 插入排序的代码实现

void InsertSort(int* a, int n)
{for (int i = 1; i < n; i++){int end = i - 1; //待排序数组的末端//也可以写成int tmp = a[end + 1]; int tmp = a[i];  //tmp存放的是待插入的数值while (end >= 0){if (tmp < a[end]) //待插入数字与数组末端的值进行比较{a[end + 1] = a[end];end--;}else{break;}}a[end + 1] = tmp;}}

2.3 插入排序算法总结

根据上面的代码,我们可以总结出一些关于插入排序算法的特征:

  1. 元素集合越接近有序,直接插入排序算法的时间效率就越高
  2. 时间复杂度:O(N^2)
  3. 空间复杂度:O(1),它是一种稳定的排序算法
  4. 稳定性:稳定

3. 希尔排序

希尔排序又称缩小增量排序。

3.1 基本思想

先选定一个整数(gap),把待排序的数据分成个别组。分组的标准就是所有距离为gap的数据分在同一组,并对每一组内的记录进行排序。然后,缩小gap的值,重复上述分组和排序的工作。当gap = 1时,就相当于直接插入排序了。

上面这个思想很重要,是理解希尔排序的核心!

给大家举个例子:
分组情况

3.2 希尔排序的代码实现

void ShellSort(int* a, int n)
{int gap = n;while (gap > 1){//gap /= 2;gap = gap / 3 + 1;for (int j = 0; j < gap; j++){//就是在对每组(隔gap位置的数字)的数据进行插入排序for (int i = j; i < n; i += gap){int end = i - 1;int tmp = a[i];while (end >= 0){if (tmp < a[end]){a[end + 1] = a[end];end--;}else{break;}}a[end + 1] = tmp;}}}

3.3 希尔排序的特征总结

  • 希尔排序是对直接插入排序的优化。
  • 当gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,数组已经接近有序的了,这样就会很快。这样整体而言,可以达到优化的效果。我们实现后可以进行性能测试的对比。
  • 希尔排序的时间复杂度不好计算,因为gap的取值方法很多,导致很难去计算。但是我们一般认为希尔排序算法的时间复杂度为O( N ∗ l o g N N*log N NlogN),但是如果我们是追求一个严谨读者,那它的时间复杂度为O(N1.3)。

好了,到这里本文就结束了。如果觉得本文还不错的话,麻烦给偶点个赞吧!
哈哈哈


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

相关文章:

  • 《Windows PE》3.2.3 NT头-扩展头
  • Zig开发环境搭建
  • C++学习笔记----8、掌握类与对象(二)---- 成员函数的更多知识(1)
  • 基于小程序+Vue + Spring Boot的进销存库存出库入库统计分析管理系统
  • 用Python实现运筹学——Day 8: 对偶理论的经济解释
  • VMware Aria Automation 8.18 发布,新增功能概览
  • plt等高线图的绘制
  • cmd下的管理员权限闪退 原理分析
  • 【分布式微服务云原生】消息队列全解析:原理、应用场景与主流MQ对比
  • c# iTextSharp 读取PDF
  • 每日学习一个数据结构-NFA非确定有限状态机
  • 短链接生成-短链接-短网址-短链接生成接口-短链接转换接口-短网址URL生成-短链接地址-短网址-短域名-短链接【快证api】
  • 1.7 编码与调制
  • json是什么
  • 7天的Django实战学习计划
  • JavaScript 指南
  • Golang | Leetcode Golang题解之第449题序列化和反序列化二叉搜索树
  • linux中使用docker命令时提示权限不足
  • 自然语言处理问答系统最新技术
  • 嵌入式必懂微控制器选型:STM32、ESP32、AVR与PIC的比较分析