[动画+注释详解]数据结构 - 直接插入排序

news2024/11/26 23:50:40

一. 直接插入排序算法的实现

1.1 基本思想

直接插入排序(Straight Insertion Sort)是一种简单直观的排序算法,它的基本思想是将一个待排序的记录插入到已经排序好的有序表中,从而得到一个新的、记录数增加1的有序表。

实际中,我们玩扑克牌时,就用到了插入排序的思想

1.2 代码的分析与详解

1. 新手村 - 有序区间的单趟排序

欢迎来到新手村,只有我们把单趟排序的逻辑先搞清楚,我们才能够真正熟练掌握直接插入排序算法

对于单趟的逻辑,我们把已排好的最后一个元素的位置设为end,把将要排序的数据的位置设为end+1,我们要将这个待插入的数据保存起来,因为在比较的过程中可能会造成数据的后移,那这个数就会被覆盖了

接着将待插入的数据与有序区间的最后一个数进行比较,如果待插入的数据比arr[end]小,那么让arr[end]后移,然后arr[end]前面的数据又组成了一个新的有序区间,让新区间最后一个位置继承end,继续往前比较,那么我们就要将这段逻辑放在一个循环里。这个循环什么时候结束呢?就是当这个【end < 0】为止

若是在中途比较的过程中发现有比待插入数据还要小或者相等的数,就停止比较,跳出这个循环。因为随着有序区间中数的后移,end后一定会空出一个位置,此时呢执行a[end + 1] = tmp;就可以将这个待插入数据完整地放入有序区中并且使这个有序区依旧保持有序

代码实现 

// 定义变量 end,表示当前元素的前一个位置
int end;
// 将待插入元素保存在临时变量 temp 中
int temp = arr[end + 1];
// 在当前元素之前的已排序部分进行插入排序,直到找到适当位置插入 temp
while (end >= 0)
{
    // 如果待插入元素小于当前元素,则将当前元素向右移动一位
    if (temp < arr[end])
    {
        arr[end + 1] = arr[end]; // 向右移动当前元素
        end--; // 继续向左移动
    }
    else
    {
        break; // 如果待插入元素大于等于当前元素,则说明找到了插入位置,跳出循环
    }
}
arr[end + 1] = temp; // 将 temp 插入到正确的位置

2. 高手村 - 无序区间的循环排序

读到这相信新手村的代码已经能熟练掌握了,那么接下来我们去往高手村领教更厉害的代码吧

注意:循环的结束条件是:i < n - 1,而不是 i < n,若是写成i < n,那么end最后为n-1,而temp = end +1也即temp=arr[n],数组的下标只能到n-1,现在要去访问下标n会造成越界访问,那么这个位置就会出现一个随机值

代码实现

void InsertSort(int* a, int n)
{
    // 不可以用 < n,否则在最后的迭代中,tmp会尝试访问 a[n],造成越界。
    for (int i = 0; i < n - 1; ++i)
    {
        int end = i;
        int tmp = a[end + 1]; // 将end后一个位置的元素保存起来,这是待插入的元素

        // 进行内部的while循环来找到tmp应该插入的位置
        while (end >= 0)
        {
            if (tmp < a[end]) // 如果tmp小于当前位置的元素
            {
                a[end + 1] = a[end]; // 将当前元素后移
                end--; // 向前移动end
            }
            else
            {
                // 如果找到了一个不大于tmp的元素,停止移动
                break;
            }
        }
        // 在正确的位置插入tmp
        a[end + 1] = tmp;
    }
}

三. 时间复杂度和空间复杂度

时间复杂度

  1. 最好情况(Best Case):

    • 情景:当输入数组已经是有序的,每次比较仅发生一次即可确认插入位置。
    • 计算:对于每个元素(从第二个开始),我们比较一次,然后插入,总共进行 𝑛−1n−1 次操作。
    • 时间复杂度:O(n)
  2. 最坏情况(Worst Case):

    • 情景:当输入数组完全逆序,每次插入的元素都必须比较到最前面才能找到插入位置。
    • 计算
      • 第一个元素认为已排序。
      • 第二个元素在最坏的情况下需要比较1次。
      • 第三个元素需要比较2次。
      • ...
      • 第 𝑛n 个元素需要比较 𝑛−1n−1 次。
      • 因此,总的比较次数是 1+2+⋯+(𝑛−1)=(𝑛−1)𝑛21+2+⋯+(n−1)=2(n−1)n​,近似于 𝑂(𝑛2)O(n2)。
    • 时间复杂度:O(n²)
  3. 平均情况(Average Case):

    • 情景:考虑所有可能的数组排列,平均每个元素需要比较一半的已排序序列长度。
    • 计算
      • 平均比较次数与移动次数也是近似于二次函数,类似于最坏情况的计算。
    • 时间复杂度:O(n²)

空间复杂度

  • 直接插入排序是一种原地排序算法。
  • 空间复杂度为 O(1),因为除了输入数组外,只需要一个额外的临时变量用于存放当前要插入的值

四. 总结

直接插入排序在最好情况下非常高效,适用于数据已经部分排序的场景。然而,在最坏和平均情况下,它的效率较低,特别是对于大规模数据。其主要优点是实现简单,排序稳定,且在数据规模较小或基本有序的情况下表现良好。

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

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

相关文章

Oracle对空值(NULL)的 聚合函数 排序

除count之外sum、avg、max、min都为null&#xff0c;count为0 Null 不支持加减乘除&#xff0c;大小比较&#xff0c;相等比较&#xff0c;否则只能为空&#xff1b;只能用‘is [not] null’来进行判断&#xff1b; Max等聚合函数会自动“过滤null” null排序默认最大&#xf…

特别的时钟特别的倒计时

念念不忘的歌曲&#xff1a;Thats Why You Go Away <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title&…

线上线下交友社区系统,支持打包小程序/公众号/H5,源码交付!

上网交友的好处有很多&#xff0c;以下是一些主要的好处&#xff1a; 1. 拓展人际关系&#xff1a;通过上网交友可以认识更多的人&#xff0c;拓展自己的社交圈。这有助于扩大自己的视野、增加人生经验和开阔心胸。 2. 找到志同道合的朋友&#xff1a;在网络上&#xff0c;我们…

《面向云计算的零信任体系第1部分:总体架构》行业标准正式发布

中华人民共和国工业和信息化部公告2024年第4号文件正式发布行业标准&#xff1a;YD/T 4598.1-2024《面向云计算的零信任体系 第1部分&#xff1a;总体架构》&#xff08;后简称“总体架构”&#xff09;&#xff0c;并于2024年7月1日正式施行。 该标准由中国信通院牵头&#xf…

装饰器模式、代理模式、适配器模式对比

装饰器模式、代理模式和适配器模式都是结构型设计模式&#xff0c;它们的主要目标都是将将类或对象按某种布局组成更大的结构&#xff0c;使得程序结构更加清晰。这里将装饰器模式、代理模式和适配器模式进行比较&#xff0c;主要是因为三个设计模式的类图结构相似度较高、且功…

如何讲好ppt演讲技巧(4篇)

如何讲好ppt演讲技巧&#xff08;4篇&#xff09; 如何讲好PPT演讲技巧&#xff08;四篇&#xff09; **篇&#xff1a;精心准备&#xff0c;奠定演讲基础 一个成功的PPT演讲&#xff0c;离不开精心的准备。首先&#xff0c;要确定演讲的主题和目标&#xff0c;确保演讲内容清…

SpringMVC进阶(自定义拦截器以及异常处理)

文章目录 1.自定义拦截器1.基本介绍1.说明2.自定义拦截器的三个方法3.流程图 2.快速入门1.Myinterceptor01.java2.FurnHandler.java3.springDispatcherServlet-servlet.xml配置拦截器4.单元测试 3.拦截特定路径1.拦截指定路径2.通配符配置路径 4.细节说明5.多个拦截器1.执行流程…

七彩虹(Colorful)隐星P16 2023款笔记本电脑原装出厂Win11系统镜像下载 带建Recovery一键还原功能

七彩虹原厂Windows预装OEM专用系统&#xff0c;恢复出厂开箱状态一模一样 适用型号&#xff1a;隐星P16 23 链接&#xff1a;https://pan.baidu.com/s/1Ig5MQMiC8k4VSuCOZRQHUw?pwdak5l 提取码&#xff1a;ak5l 原厂W11系统自带所有驱动、出厂时自带的主题与专用壁纸、系…

第 4 篇 : Netty客户端互发图片和音/视频

说明 因为图片和音/视频不能确定其具体大小, 故引入MinIO。客户端之间只发送消息, 通过上传/下载来获取额外信息 1. MinIO搭建(参考前面文章), 并启动 2. 登录MinIO创建3个Bucket: image、voice、video 3. 客户端改造 3.1 修改 pom.xml <?xml version"1.0" …

浅谈OpenCV 粗略计算工件轮廓面积和外接圆直径(Emgu.CV)

前言 最近领导在做库房工具管理这块的功能&#xff0c;希望能集成OpenCV 粗略的计算出工具的长度&#xff0c;以方便用户再归还工具的时候&#xff0c;提示用户该放在那种尺寸的盒子里面&#xff0c;这便是这篇文章的由来。 我们的系统是基于.net开发的&#xff0c;所以采用的是…

Memory augment is All You Need for image restoration 论文翻译

目录 一.介绍 二.实际工作 A.图像阴影去除 B.图像去雨 C.存储模块的开发 三.网络结构 A.内存扩充 B.损失函数设计 四.实验 A.与最先进方法的比较 B.MemoryNet消融研究 五.结论 CVPR2023 MemoryNet 记忆增强是图像恢复所需要的一切 论文地址https://arxiv.org/abs/…

就业班 第三阶段(nginx) 2401--4.26 day5 nginx5 nginx https部署实战

三、HTTPS 基本原理 1、https 介绍 HTTPS&#xff08;全称&#xff1a;HyperText Transfer Protocol over Secure Socket Layer&#xff09;&#xff0c;其实 HTTPS 并不是一个新鲜协议&#xff0c;Google 很早就开始启用了&#xff0c;初衷是为了保证数据安全。 近些年&…

大型零售企业,适合什么样的企业邮箱大文件解决方案?

大型零售企业通常指的是在全球或特定地区内具有显著市场影响力和知名度的零售商。这些企业不仅在零售业务收入上达到了惊人的规模&#xff0c;而且在全球范围内拥有广泛的销售网络和实体店铺。它们在快速变化的零售行业中持续创新&#xff0c;通过实体店、电商平台等多种渠道吸…

「C++ 内存管理篇 1」C++动态内存分配

目录 〇、C语言的动态内存分配方式 一、C的动态内存分配方式 1. 什么是C的动态内存分配&#xff1f; 2. 为什么需要C的动态内存分配&#xff1f; a. new的优势 b. new的不足 c. delete的优势 d. 总结 3. 怎么使用new和delete? a. 对于内置类型 b. 对于自定义类型 c. 为什么ne…

python学习笔记----循环语句(四)

一、while循环 为什么学习循环语句 循环在程序中同判断一样&#xff0c;也是广泛存在的&#xff0c;是非常多功能实现的基础&#xff1a; 1.1 while循环语法 while 条件表达式:# 循环体# 执行代码这里&#xff0c;“条件表达式”是每次循环开始前都会评估的表达式。如果条件…

【血泪教训】Altium Designer隐藏覆铜层导致PCB电路板未加工隐藏层

Altium Designer隐藏覆铜层导致PCB电路板未加工隐藏层 血泪教训&#xff01;&#xff01;&#xff01; 事情经过是这样的 测试板PCB Layout完成后&#xff0c;隐藏铺铜层&#xff0c;方便check&#xff0c;隐藏操作如下图所示&#xff0c;选择“隐藏所有”或“隐藏选中铺铜”…

Redis基本數據結構 ― String

Redis基本數據結構 ― String 介紹常用命令範例1. 為字串鍵設值/取得字串鍵的值2. 查看字串鍵的過期時間3. 如何為key設置時間?4. 如何刪除指定key?5. 如何增加value的值?6. 獲取value值的長度 介紹 字串鍵是Redis中最基本的鍵值對類型&#xff0c;這種類型的鍵值對會在數據…

【python技术】使用akshare抓取东方财富所有概念板块,并把指定板块概念的成分股保存excel 简单示例

最近有个想法&#xff0c;分析A股某个概念成分股情况进行分析&#xff0c;第一反应是把对应概念板块的成分股爬取下来。说干就干 下面是简单示例 import akshare as ak import pandas as pddef fetch_and_save_concept_stocks(name):# 获取指定股票概念的成分股&#xff0c;并…

机器学习每周挑战——百思买数据

最近由于比赛&#xff0c;断更了好久&#xff0c;从五一开始不会再断更了。这个每周挑战我分析的较为简单&#xff0c;有兴趣的可以将数据集下载下来试着分析一下&#xff0c;又不会的我们可以讨论一下。 这是数据集&#xff1a; import pandas as pd import numpy as np impo…

Leetcode-面试题 02.02. 返回倒数第 k 个节点

目录 题目 图解 代码 面试题 02.02. 返回倒数第 k 个节点 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/kth-node-from-end-of-list-lcci/description/ 题目 实现一种算法&#xff0c;找出单向链表中倒数第 k 个节点。返回该节点的值。 注意&…