【数据结构】插入排序——直接插入排序 和 希尔排序

直接插入排序 和 希尔排序

  • 一、直接插入排序
  • 二、直接插入排序的弊端
  • 三、希尔排序
    • (1)对插入排序的联想
    • (2)希尔排序的思路
  • 四、直接插入排序和希尔排序效率对比
      • 1>随机生成10000个数
      • 2>我们随机生成100000个数
      • 3>我们随机生成1000000个数
      • 4>希尔排序的时间复杂度

一、直接插入排序

我们要如何理解直接插入排序呢?

在这里插入图片描述

假设tmp之前的数都被我们拍好了,tmp就是我们要插入的数
让tmp之前的数与tmp进行对比,若比tmp大就将他们向后移动

在这里插入图片描述
当遇到比tmp小的数就将tmp插入到该数的后面
这样能保证tmp所在的位置:
前面是比tmp小的数
后面是比tmp大的数

当走完循环就可以完成排序

动图演示:
在这里插入图片描述

//插入排序
void InsertSort(int* a, int n)
{for (int i = 0; i < n - 1; i++){//保存已经拍好序的前 i 个数的下标int end = i;//保存要插入的数,一会儿会被覆盖int tmp = a[i + 1];//单次循环while (end >= 0 && a[end] > tmp){//若前一个数比 tmp 大则将该数填到后面,t--a[end + 1] = a[end--];}a[end + 1] = tmp;}
}

在这里插入图片描述
我们看到我们这里的循环条件是 i < n - 1
因为当 i 为倒数第二个数时
插入的数为倒数第一个数
在这里插入图片描述
代码运行:
在这里插入图片描述

二、直接插入排序的弊端

直接插入排序有什么弊端呢?

我们想如果我们要排一个升序
在这里插入图片描述

1>
数组中是升序排列的数:
那么我们每次进入循环都不需要额外进行移动
也就是不用进入循环,移到次数为 0
那么它的时间复杂度是O(N)

在这里插入图片描述

2>
数组中是降序排列的数:
那么我们每次进入循环都要进行移动
并且假设我们要将第 i 个数插入,移动次数为 i - 1
那么它的时间复杂度是O(N ^ 2)

所以直接插入排序的效率是很不稳定的

三、希尔排序

(1)对插入排序的联想

但是插入排序真的不可取吗?
插入排序在最好的情况时间复杂度时O(N)
但是插入排序的效率受到数组原顺序的影响很大
假如要拍一个升序,而最大的数在第一位
那么最大的这个数要移动的次数很多

那么我们想,如果我们可以让插入排序的时间复杂度接近O(N)
那它的效率一定非常高
所以我们想到:
如果我们可以让原来要移动很多次数的数移动的次数变少,就可以提高它的效率

(2)希尔排序的思路

如果我们想让原来要移动次数很多的数,它的移动次数变少
那么我们就要改变它的移动步子大小
我们把步子的这个大小叫gap
我们假设gap = 3
在这里插入图片描述
进行一次插入
在这里插入图片描述

将 end = i + gap 位置的数插入,使得和 i = 0 位置的数进行交换

最终效果:
在这里插入图片描述
我们发现最大的数原先需要 9 次才能移动到最后
但现在仅仅需要三次就到最后了
这样就使我们的排序效率提高
那我们下一次只要从 i = 1 的位置开始
一直到 i < gap
这样就把整个数组进行了初次排序

我们先来分析一次步子大小为 gap 的排序
下面是一次插入的代码:

//每次跳的步子大小
int gap;
for (int j = 0; j < gap; j++)
{//单次排序for (int i = j; i < n - gap; i += gap){//保存拍好序的前面最后数的下标int end = i;//保存要插入数的值int tmp = a[i + gap];//循环while (end >= 0 && a[end] > tmp){a[end + gap] = a[end];end -= gap;}a[end + gap] = tmp;}
}

先看内层:
单次排序开始
每次将 end = i + gap 处的数插入
与 i = 0 进行比较
随后再将 i += gap
相当于将 end = i + gap + gap 处的数插入

那么在什么时候截止呢?
这时我们要往外层看
我们又进行了一层循环
我们设 j = 0 就是第一次开始插入的位置
为了将整个数组都进行该处理
我们每次将 j++
当 j < gap 时就将 0 到 gap - 1 前的数都处理了
也将整个数组都进行了一次 gap 步的排序
如果不理解可以将上面图中 gap = 3 的情况带入理解

那么我们再反过来看 i 的停止条件
以 gap 等于 3 为例
当 i = 1 或者 i = 2 时
再后面 end = i + gap时,会超出范围
在这里插入图片描述

所以当 i < n - gap 时,就可以处理完全部的数

接下来看下面的图:

在这里插入图片描述
在这里插入图片描述
有没有发现什么,是不是当 gap = 1 时两边的代码就一样了

所以我们接下来就要考虑 gap 的取值了
经过人们的研究,人们发现 gap 每次取 1 / 3 时效率最高
所以就有了下面的代码:

//希尔排序
void ShellSort(int* a, int n)
{int gap = n - 1;while (gap != 1){//每次跳的步子大小gap = gap / 3 + 1;for (int j = 0; j < gap; j++){//单次排序for (int i = j; i < n - gap; i += gap){//保存拍好序的前面最后数的下标int end = i;//保存要插入数的值int tmp = a[i + gap];//循环while (end >= 0 && a[end] > tmp){a[end + gap] = a[end];end -= gap;}a[end + gap] = tmp;}}}
}

为什么我们要取 gap 时要 gap / 3 + 1
因为当 gap 等于 2 时,再除 3 会等于 0
那么这个 +1 就是为了使 gap 最终会等于 1
动图演示:
在这里插入图片描述

四、直接插入排序和希尔排序效率对比

1>随机生成10000个数

让直接插入排序和希尔排序进行比较:
在这里插入图片描述
在这里插入图片描述

2>我们随机生成100000个数

在这里插入图片描述

3>我们随机生成1000000个数

在这里插入图片描述
再往后的就不测了,插入排序跑不动了

4>希尔排序的时间复杂度

直接说结论希尔排序的时间时间复杂度为:
O(N ^ 1.3)

很抽象,这个我是不会算,当时听到也感觉惊为天人

在这里插入图片描述

但是我们可以探究一下
第一次 gap 我们的最大交换次数
(gap / 3) * 3 此时gap为n
gap / 3 为组数,而 *3是没组最大的交换次数

第二次 gap 我们的最大交换次数
(gap / 3 / 3)* 3 * 3
理应是这样的对吧?
可是要是真的是这样我们第一次不是白处理了嘛
第一次我们已经将要移动次数较多的数移动到后面了
那这个最大交换次数是不可能的
所以就会变得快

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

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

相关文章

python使用turtle画图快速入门,轻松完成作业练习

turtle介绍 turtle是一个绘图库&#xff0c;可以通过编程进行绘图。其模拟了一个乌龟在屏幕上的运动过程。该库通常用于给青少年学习编程&#xff0c;当然&#xff0c;也可以使用其进行作图。 在一些学校中&#xff0c;可能在python学习的课程中&#xff0c;要求完成turtle绘…

K8S群集调度二

一、污点(Taint) 和 容忍(Tolerations) 1.1、污点(Taint) 设置在node上是对pod的一种作用 节点的亲和性&#xff0c;是Pod的一种属性&#xff08;偏好或硬性要求&#xff09;&#xff0c;它使Pod被吸引到一类特定的节点 而Taint 则相反&#xff0c;它使节点能够排斥一类特…

分布式唯一ID生成(二): leaf

文章目录 本系列前言号段模式双buffer优化biz优化动态step源码走读 雪花算法怎么设置workerId解决时钟回拨源码走读 总结 本系列 漫谈分布式唯一ID分布式唯一ID生成&#xff08;二&#xff09;&#xff1a;leaf&#xff08;本文&#xff09;分布式唯一ID生成&#xff08;三&am…

MVDR:最小方差无失真响应技术解析

目录 什么是MVDR&#xff1f;MVDR的工作原理主要步骤MVDR的应用场景MVDR的优势与挑战结论 什么是MVDR&#xff1f; MVDR&#xff08;Minimum Variance Distortionless Response&#xff0c;最小方差无失真响应&#xff09;是一种用于信号处理中的自适应滤波技术&#xff0c;广…

Flink安装和Flink CDC实现数据同步

一&#xff0c;Flink 和Flink CDC 1&#xff0c; Flink Apache Flink是一个框架和分布式处理引擎&#xff0c;用于对无界和有界数据流进行有状态计算。 中文文档 Apache Flink Documentation | Apache Flink 官方文档 &#xff1a;https://flink.apache.org Flink 中文社区…

【React.js】AntDesignPro左侧菜单栏栏目名称不显示的解决方案

作者&#xff1a;CSDN-PleaSure乐事 欢迎大家阅读我的博客 希望大家喜欢 使用环境&#xff1a;WebStorm 目录 问题概述 原因 解决方案 解决方法 潜在问题修改 最终效果呈现 额外内容 管理员界面路由配置 WebStorm背景更换 法一&#xff1a; 法二&#xff1a; 问题概…

MCU面试题

面试题 1、Crotex-M 处理器才用的架构是"v7" Cortex-M3处理器是基于ARMv7-M架构的处理器&#xff0c;支持更丰富的指令集&#xff0c;包括许多32位指令&#xff0c;这些指令可以高效的使用高位寄存器。另外&#xff0c;M3还支持&#xff1a; 查表跳转指令和条件执行&…

Mysql COUNT() 函数详解

在使用Mysql的时候&#xff0c;作为开发者&#xff0c;聚合函数是肯定会用到的&#xff0c;下面就来说说我们常用到的统计行数的聚合函数 COUNT()。 COUNT() 的几种用法 说到COUNT() 函数&#xff0c;最常用的几种方法就是 COUNT(*) 、COUNT(1)、 COUNT(column)&#xff0c;那…

基于SSM的图书馆座位预约系统+lw示例参考

#1.项目介绍 系统角色&#xff1a;管理员、普通用户功能模块&#xff1a;管理员&#xff08;用户管理、座位管理、座位分类管理、图书馆管理、预约信息管理、退座管理、系统管理等&#xff09;、普通用户&#xff08;信息查看、图书馆管理、个人中心、座位预约等&#xff09;技…

【数字图像处理+MATLAB】计算并显示灰度图像的直方图(Histogram):使用 imhist 函数

引言 imhist 是 MATLAB 中的一个函数&#xff0c;用于计算并显示图像的直方图。 直方图是一种统计工具&#xff0c;用于显示图像中各个亮度级别的像素数量。直方图的垂直轴表示像素数量&#xff0c;水平轴表示亮度级别。 函数详解 基本语法&#xff1a; imhist(I) imhist(I…

了解云计算工作负载保护的重要性及必要性

云计算de小白 云计算技术的快速发展使数据和应用程序安全成为一种关键需求&#xff0c;而不仅仅是一种偏好。随着越来越多的客户公司将业务迁移到云端&#xff0c;保护他们的云工作负载&#xff08;指所有部署的应用程序和服务&#xff09;变得越来越重要。云工作负载保护&…

windows server2019下载docker拉取redis等镜像并运行项目

一、基本概念 1、windows server 指由微软公司开发的“Windows”系列中的“服务器”版本。这意味着它是基于Windows操作系统的&#xff0c;但专门设计用于服务器环境&#xff0c;而不是普通的桌面或个人用户使用。主要用途包括服务器功能、用户和资源管理、虚拟化等 2、dock…

0. 渲染游戏画面

1 用到的函数 # initialize env env gym.make() frame env.render() frame np.transpose(frame, (1, 0, 2)) # 调整图像方向 frame pygame.surfarray.make_surface(frame) screen.blit(frame, (0, 0)) pygame.display.flip()1.1 检查图像的形状 首先&#xff0c;我们…

【西藏】《西藏自治区本级政务信息化项目建设和运维费用预算支出标准》(藏财建〔2024〕68号)-省市费用标准解读系列08

2024年9月1日&#xff0c;西藏自治区财政厅和经济和信息化厅正式施行最新信息化建设和运维项目预算支出标准《西藏自治区本级政务信息化项目建设和运维费用预算支出标准》&#xff08;藏财建〔2024〕68号&#xff09;&#xff08;以下简称“68号文”&#xff09;。同时&#xf…

Autosar CP Transformer规范工作原理和应用场景导读

一、AUTOSAR规范中Transformer的主要功能和分类 &#xff08;一&#xff09;主要功能 数据转换与处理 从运行时环境&#xff08;RTE&#xff09;获取数据&#xff0c;进行序列化&#xff08;将复杂数据结构转换为线性字节数组&#xff09;或其他转换操作&#xff08;如添加校…

【网络安全 | 并发问题】Nginx重试机制与幂等性问题分析

未经许可,不得转载。 文章目录 业务背景Nginx的错误重试机制proxy_next_upstream指令配置重试500状态码非幂等请求的重试问题幂等性和非幂等性请求non_idempotent选项的使用解决方案业务背景 在现代互联网应用中,高可用性(HA)是确保系统稳定性的关键要求之一。为了应对服务…

天津营业执照注销流程

营业执照不注销会有什么影响&#xff1f;1、公司不经营&#xff0c;放几年自动注销&#xff1f;真相&#xff1a;不管放多长时间&#xff0c;公司是不会自动注销的。相反&#xff0c;放任长久不维护&#xff0c;公司会出现异常&#xff0c;营业执照被吊销&#xff0c;公司股东、…

MySQL数据库专栏(五)连接MySQL数据库C API篇

摘要 本篇文章主要介绍通过C语言API接口链接MySQL数据库&#xff0c;各接口功能及使用方式&#xff0c;辅助类的封装及调用实例&#xff0c;可以直接移植到项目里面使用。 目录 1、环境配置 1.1、添加头文件 1.2、添加库目录 2、接口介绍 2.1、MySql初始化及数据清理 2.1.…

计算机课程管理:Spring Boot实现的工程认证路径

摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了基于工程教育认证的计算机课程管理平台的开发全过程。通过分析基于工程教育认证的计算机课程管理平台管理的不足&#xff0c;创建了一个计算机管理基于工程教育认…