[数据结构] 排序#插入排序希尔排序

标题:[数据结构] 排序#插入排序&希尔排序

@水墨不写bug



目录

(一)插入排序

实现思路:

插入排序实现: 

(二)希尔排序

希尔排序的基本思想: 

希尔排序的实现:


正文开始:

        排序是日常生活中常见的对数据的需求,排序有多重不同的方法,每一种方法都有各自的优缺点,本文来为你介绍两个思路类似的排序方法:插入排序和希尔排序。

(一)插入排序

       

        时间复杂度:O(N^2)

        空间复杂度:O(1)

        特点:元素越接近有序,插入排序的效率越高。

        稳定性:稳定

实现思路:

主要过程: 

        对于区间一个有序区间 [0,end] 将区间后的一个元素 nums[end+1] 插入到有序区间内。

由于nums[end+1]在移动元素时会被覆盖,需要一个临时变量tem暂时存储 nums[end+1],具体来说,将tem与nums[end]进行比较,如果

tem < nums[end]

则将end处的数据后移:

nums[end+1] = nums[end]

并将end--,继续比较。

如果

tem>=nums[end]

说明已经到达要插入的位置,直接break。

在出循环之后,将tem插入正确的位置即可:

nums[end+gap] = tem

整体实现注意事项:

        1.在实现过程中,可以先写内层循环,完成内层逻辑,再写外层循环。

        2.对于内层循环,进行循环的条件是 end>=0 ,由于外层循环end从0开始,如果内层进行循环的条件是end>0,那么如果end = 0,就无法进入循环。

        3.如何确定外层循环的区间?

        左区间从零开始;对于最大的区间,由于要将最后一个元素(size-1位置)插入到前面的区间 [0,size-2]内,所以end最大可取  size-2 。

        则区间为:

                [0,size-2](两闭区间)或者[0,size-1)(左闭右开区间)。

插入排序实现: 

#include<iostream>
#include<vector>
using namespace std;void InsertSort(vector<int>& nums)
{//外层循环,end从0开始遍历for (int i = 0; i < nums.size()-1; i++){//[0,end] end+1int end = i;int tem = nums[end + 1];//内层循环,end>=0时要进入循环while (end >= 0){if (nums[end] > tem){nums[end + 1] = nums[end];--end;}elsebreak;}nums[end + 1] = tem;}
}
void Print(vector<int> v)
{for (const auto& e : v)cout << e << " ";cout << endl;
}
int main()
{vector<int> nums = { 55,9,8,6,7,59,75,89,12,50 };Print(nums);InsertSort(nums);Print(nums);return 0;
}

 


(二)希尔排序

        希尔排序简单来说就是对插入排序的优化,它与插入排序的整体思路是一致的。想要写好希尔排序,就必须要讲究一个层次感,你需要明白希尔排序的几层循环到底是在干什么


希尔排序的基本思想: 

分组:

        将数组中间距为gap的数据分为一组,如图所示:(gap == 3)

可以将一组数据分为gap组:

        我们将每一组数据看做是一个小组(group),对于每一个小组,想要将他们排序,自然需要移动,由于小组内部数据相距gap,所以移动的步幅也是gap。

希尔第一层次:

        也就是插入排序内层循环的逻辑,唯一不同的是将步幅从1改为gap。

实现的操作:

        将一个数据 nums[end+gap] 插入到已经有序的区间 [0,end] 内部,并在插入后使整个区间保持有序。

        由于nums[end+gap]在移动元素时会被覆盖,需要一个临时变量tem暂时存储 nums[end+gap],具体来说,将tem与nums[end]进行比较,如果

tem < nums[end]

则将end处的数据后移:

nums[end+gap] = nums[end]

并将end-=gap,继续比较。

如果

tem>=nums[end]

说明已经到达要插入的位置,直接break。

在出循环之后,将tem插入正确的位置即可:

nums[end+gap] = tem

实现参考:

int end;
int tem = nums[end + gap];
while (end >= 0)
{if (tem < nums[end]){nums[end + gap] = nums[end];end -= gap;}elsebreak;
}
nums[end + gap] = tem;

 希尔第二层次:

        也就是插入排序外层循环的逻辑。

实现的操作:

        由于随着插入的进行,区间不断扩大,第二层次作用是不断改变区间的右端,和定位并保存需要插入的元素 nums[end+gap] 。

实现参考:

for (int i = 0; i < n - gap; i += gap)
{int end = i;int tem = nums[end + gap];while (end >= 0){if (tem < nums[end]){nums[end + gap] = nums[end];end -= gap;}elsebreak;}nums[end + gap] = tem;
}

希尔第三层次:

        前两层次实现了对一个group的排序,第三层就是要实现对所有group的排序。

实现的操作:

        外层创造循环变量j,对区间起点 i 制造偏移量:

for (int j = 0; j < gap; j++)
{for (int i = j; i < n - gap; i += gap){int end = i;int tem = nums[end + gap];while (end >= 0){if (tem < nums[end]){nums[end + gap] = nums[end];end -= gap;}elsebreak;}nums[end + gap] = tem;}
}

 希尔第四层次:

        前三层次完成了对某一特定gap下的预排序。第四层次就是要通过gap来逐渐让数组接近有序。

        gap的意义是让数据跳动的步幅增大,不同的大小的gap拥有不同的效果:

        如果gap较大,数据跳动的步幅更大,数据的移动更快,但是更不容易接近有序。

        对于较小的gap,数据步幅减小,数据移动的较慢,但是更容易接近有序;当gap取可取得的最小值1时,整个排序逻辑就会退化为插入排序。

实现的操作:

        通过特定的策略逐渐减小gap。

        经过研究,gap每次除三效果最好,但是为了避免gap小于1,于是在每次除三后再加上1,这样就是一种gap的取值策略。


void ShellSort(vector<int>& nums)
{int n = nums.size();int gap = n;while (gap > 1){gap = gap / 3 + 1;//....}
}

希尔排序的实现:


void ShellSort(vector<int>& nums)
{int n = nums.size();int gap = n;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 tem = nums[end + gap];while (end >= 0){if (tem < nums[end]){nums[end + gap] = nums[end];end -= gap;}elsebreak;}nums[end + gap] = tem;}}}
}

完~

未经作者同意禁止转载

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

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

相关文章

IT入门知识第八部分《人工智能》(9/10)

1.引言 在当今数字化时代&#xff0c;人工智能&#xff08;AI&#xff09;和机器学习&#xff08;ML&#xff09;已成为推动技术革新的关键力量。它们不仅改变了我们与机器的互动方式&#xff0c;还极大地拓展了解决问题的可能性。本文将深入探讨人工智能和机器学习的基础&…

KDTree 简单原理与实现

介绍 K-D树是一种二叉树的数据结构&#xff0c;其中每个节点代表一个k维点&#xff0c;可用于组织K维空间中的点&#xff0c;其中K通常是一个非常大的数字。二叉树结构允许对多维空间中的点进行非常有效的搜索&#xff0c;包括最近邻搜索和范围搜索&#xff0c;树中的每个非叶…

Java毕业设计 基于SSM vue新生报到系统小程序 微信小程序

Java毕业设计 基于SSM vue新生报到系统小程序 微信小程序 SSM 新生报到系统小程序 功能介绍 学生 登录 注册 忘记密码 首页 学校公告 录取信息 录取详情 师资力量 教师详情 收藏 评论 用户信息修改 宿舍安排 签到信息 在线缴费 教室分配 我的收藏管理 我要发贴 我的发贴 管理…

【基于R语言群体遗传学】-7-遗传变异(genetic variation)

一些新名词 Continuous time: 连续时间&#xff0c;是指不间断流动的时间&#xff0c;不以单位时间形式出现。 Diffusion: 扩散&#xff0c;是指粒子从高浓度区域向低浓度区域的被动净移动。 Discrete time: 离散时间&#xff0c;是指被划分为单位的时间&#xff0c;例如每个…

动手学深度学习(Pytorch版)代码实践 -计算机视觉-48全连接卷积神经网络(FCN)

48全连接卷积神经网络&#xff08;FCN&#xff09; 1.构造函数 import torch import torchvision from torch import nn from torch.nn import functional as F import matplotlib.pyplot as plt import liliPytorch as lp from d2l import torch as d2l# 构造模型 pretrained…

Python内存优化的实战技巧详解

概要 Python是一种高级编程语言,以其易读性和强大的功能而广受欢迎。然而,由于其动态类型和自动内存管理,Python在处理大量数据或高性能计算时,内存使用效率可能不如一些低级语言。本文将介绍几种Python内存优化的技巧,并提供相应的示例代码,帮助在开发中更高效地管理内…

Banana Pi BPI-M4 Berry创建热点和设置静态IP

create_ap是一个帮助快速创建Linux上的WIFI热点的脚本&#xff0c;并且支持bridge和NAT模式&#xff0c;能够自动结合hostapd, dnsmasq和iptables完成WIFI热点的设置&#xff0c;避免了用户进行复杂的配置&#xff0c;github地址如下&#xff1a; https://github.com/oblique/…

时钟系统框图(时钟树)解析

时钟系统框图&#xff08;时钟树&#xff09;解析 文章目录 时钟系统框图&#xff08;时钟树&#xff09;解析1、时钟树2、 4个时钟源&#xff1a;$HSI、HSE、LSI、LSE$3、PLL锁相环倍频输出4、系统时钟的来源5、Enable CSS&#xff08;时钟监视系统&#xff09;6、几个重要的时…

微软与OpenAI/谷歌与三星的AI交易受欧盟重点关注

近日&#xff0c;欧盟委员会主管竞争事务的副主席玛格丽特维斯塔格(Margrethe Vestager)在一次演讲中透露&#xff0c;欧盟反垄断监管机构将就微软与OpenAI的合作&#xff0c;以及谷歌与三星达成的AI协议寻求更多第三方意见。这意味着微软与 OpenAI、谷歌与三星的 AI 交易及合作…

杰理科技AD142A语音芯片,语音玩具方案—云信通讯

语音玩具产品市场的需求量比较大&#xff0c;从前简单的发光玩具&#xff0c;到各种动作的电子玩具&#xff0c;再到如今的语音录音灯光动作玩具&#xff0c;可见玩具行业也是在不断地演变。 杰理语音芯片AD142A4的优势主要是支持录音、录变音、语音播放&#xff0c;广泛应用于…

【Android】Android基础--显式Intent和隐式Intent

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌…

【数据结构】常见四类排序算法

1. 插入排序 1.1基本思想&#xff1a; 直接插入排序是一种简单的插入排序法&#xff0c;其基本思想是&#xff1a;把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中&#xff0c;直到所有的记录插入完为止&#xff0c;得到一个新的有序序列 。实际中我们…

SQL Server 2022数据库对象

《SQL Server 2022从入门到精通&#xff08;视频教学超值版&#xff09;》图书介绍-CSDN博客 数据库对象是数据库的组成部分&#xff0c;数据表、视图、索引、存储过程以及触发器等都是数据库对象。 &#xff08;1&#xff09;数据库的主要对象是数据表&#xff0c;数据表是一…

深圳航空顶象验证码逆向,和百度验证码训练思路

声明(lianxi a15018601872) 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 前言(lianxi a…

encrypt decrypt CA

encrypt & decrypt & CA 加密解密证书

基于java+springboot+vue实现的大学生就业需求分析系统(文末源码+Lw)233

摘 要 信息数据从传统到当代&#xff0c;是一直在变革当中&#xff0c;突如其来的互联网让传统的信息管理看到了革命性的曙光&#xff0c;因为传统信息管理从时效性&#xff0c;还是安全性&#xff0c;还是可操作性等各个方面来讲&#xff0c;遇到了互联网时代才发现能补上自…

A股继续3000以下震荡,而国外股市屡创新高,人民币反弹能带动A股吗?

今天的A股&#xff0c;让人愤愤不已&#xff0c;你知道是为什么吗&#xff1f;盘面上出现3个耐人寻味的重要信号&#xff0c;一起来看看&#xff1a; 1、今天两市一度回踩2920点&#xff0c;让股民的心都开始悬起来了。而午后市场行情有了转变&#xff0c;下跌的股票开始明显变…

在centos7上部署mysql8.0

1.安装MySQL的话会和MariaDB的文件冲突&#xff0c;所以需要先卸载掉MariaDB。查看是否安装mariadb rpm -qa | grep mariadb 2. 卸载mariadb rpm -e --nodeps 查看到的文件名 3.下载MySQL安装包 MySQL官网下载地址: MySQL :: Download MySQL Community Serverhttps://dev.mys…

c/c++ 程序运行的过程分析

c/c编译基础知识 GNU GNU&#xff08;GNU’s Not Unix!&#xff09;是一个由理查德斯托曼&#xff08;Richard Stallman&#xff09;在1983年发起的自由软件项目&#xff0c;旨在创建一个完全自由的操作系统&#xff0c;包括操作系统的内核、编译器、工具、库、文本编辑器、邮…

线性代数基础概念:矩阵

目录 线性代数基础概念&#xff1a;矩阵 1. 矩阵的定义 2. 矩阵的运算 3. 矩阵的特殊类型 4. 矩阵的秩 5. 矩阵的初等变换 6. 矩阵的特征值与特征向量 7. 矩阵的应用 8. 矩阵总结 总结 线性代数基础概念&#xff1a;矩阵 矩阵是线性代数中的另一个重要概念&#xff0…