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

【数据结构】插入排序:直接插入排序、折半插入排序、希尔排序的学习知识总结

目录

1、排序的基本概念

2、直接插入排序

2.1 算法思想 

2.2 代码实现 

3、折半插入排序

3.1 算法思想

3.2 代码实现 

4、希尔排序

4.1 算法思想

4..2 代码实现 


1、排序的基本概念

排序是将一组数据按照预定的顺序排列的过程,排序的基本概念包括以下内容:

  1. 关键字:排序时按照哪个字段进行排序,该字段称为关键字。

  2. 排序规则:排序时按照升序或降序的方式排列。升序表示从小到大排列,降序表示从大到小排列。

  3. 稳定性:排序算法如果经过排序后,具有相同关键字的元素,排序前后的相对顺序是否保持不变。如果保持不变,该排序算法就是稳定的。

  4. 时间复杂度:排序算法进行排序所需要的时间复杂度。

  5. 空间复杂度:排序算法进行排序所需要的额外空间复杂度,即算法需要占用的额外内存大小。

2、直接插入排序

2.1 算法思想 

        直接插入排序算法的思想是将待排序的元素插入到已经排好序的元素序列中,从而得到一个新的、更大的有序序列。

        具体来说,算法从第二个元素开始遍历待排序序列,将当前元素插入到已经排好的元素序列中的正确位置上,使得插入后仍然保持有序。因为初始时已经有一个元素的有序序列,所以排序过程中每次插入的元素都将比已经排好序的元素序列中的元素小,因此不会影响已经排好序的元素序列的有序性。当遍历完整个序列,待排序序列就被完全插入到已经排好序的元素序列中,排序完成。

        直接插入排序的时间复杂度为O(n^2),空间复杂度为O(1)。虽然时间复杂度较高,但是对于小规模数据的排序效率较高,并且具有稳定性。

2.2 代码实现 

以下是C语言编写的直接插入排序并计数比较次数的程序:

#include <stdio.h>
#define MAXSIZE 100void InsertionSort(int A[], int n, int *cnt) {int i, j, temp;for(i = 1; i < n; i++) {temp = A[i];for(j = i - 1; j >= 0; j--) {(*cnt)++;if(A[j] > temp)A[j + 1] = A[j];elsebreak;}A[j + 1] = temp;}
}int main() {int A[MAXSIZE];int n, cnt = 0;printf("请输入待排序数列元素个数(不超过%d):", MAXSIZE);scanf("%d", &n);printf("请输入待排序数列:");for(int i = 0; i < n; i++)scanf("%d", &A[i]);InsertionSort(A, n, &cnt);printf("排序后结果:");for(int i = 0; i < n; i++)printf("%d ", A[i]);printf("\n比较次数:%d\n", cnt);return 0;
}

        程序中的 InsertionSort 函数实现了直接插入排序,并使用指针形参 cnt 对比较次数进行计数。主函数中首先输入待排序数列元素个数和数列元素,然后调用 InsertionSort 函数进行排序,并输出排序后的结果和比较次数。

下面是C语言在链式存储结构上设计直接插入排序算法的示例代码:

typedef struct Node {int data;struct Node *next;
}Node;void insertSort(Node **head) {if (*head == NULL || (*head)->next == NULL) {return;}Node *p = (*head)->next;(*head)->next = NULL; // 设置新的有序链表头节点while (p != NULL) {Node *q = p->next;Node *prev = NULL;Node *cur = *head;while (cur != NULL && cur->data < p->data) {prev = cur;cur = cur->next;}if (prev == NULL) { // 插入到头节点之前p->next = *head;*head = p;} else { // 插入到prev和cur之间prev->next = p;p->next = cur;}p = q;}
}

        此代码首先对链表的头节点进行判断,若链表为空或只有一个节点则不需要排序。然后指针p指向头节点的后继节点,将头节点的后继节点设为空,新的有序链表头节点为原链表的头节点。接下来,对p的每个节点进行插入排序操作,找到p应该插入的位置并插入。最后返回排好序的链表头节点。

3、折半插入排序

3.1 算法思想

        折半插入排序算法是插入排序算法的一种变种。它的基本思想是将待排序的序列分成两部分,前半部分为已排序好的部分,后半部分为未排序的部分。排序过程中,每次从未排序的部分中选出一个元素,通过折半查找的方式,找到它应该插入到已排序的部分中的哪个位置,然后再将的元素插入到已排序的部分中。

具体实现步骤如下:

1. 将待排序序列的第一个元素作为已排序的部分,剩下的元素作为未排序的部分。

2. 从未排序的部分中选出一个元素,通过二分查找找到它应该插入到已排序的部分中的位置。

3. 将该元素插入到已排序的部分中,同时将已排序的部分的长度增加1,未排序的部分的长度减少1。

4. 重复步骤2和步骤3,直到未排序的部分为空。

        折半插入排序算法相比于普通的插入排序算法,虽然查找的时间复杂度由O(n)降低为O(log n),但是这并不影响算法的总体时间复杂度,依然是O(n^2)。不过,在某些特定的场景下,折半插入排序算法的效率可能会比普通的插入排序算法更高。

3.2 代码实现 

        折半插入排序是插入排序的一种优化算法,它利用二分查找的思想来确定插入位置,从而减少比较和移动的次数,提高排序效率。

下面是C语言实现折半插入排序的示例代码:

void binary_insertion_sort(int arr[], int len) {int i, j, left, right, mid, tmp;for (i = 1; i < len; i++) {tmp = arr[i];left = 0;right = i - 1;// 找到插入位置while (left <= right) {mid = (left + right) / 2;if (tmp < arr[mid]) {right = mid - 1;} else {left = mid + 1;}}// 移动元素for (j = i - 1; j >= left; j--) {arr[j + 1] = arr[j];}// 插入元素arr[left] = tmp;}
}

        该算法的时间复杂度为O(nlogn),空间复杂度为O(1)。

4、希尔排序

4.1 算法思想

        希尔排序算法是插入排序的一种改进算法,也称为缩小增量排序。希尔排序的基本思想是将待排序序列分割成若干个子序列,对每个子序列进行插入排序,然后不断减小步长,直到步长为1,完成排序。

        具体实现时,先确定一个增量,在每个增量下将序列分成若干个小组,对每个小组进行插入排序。然后逐渐减小增量,重复上述操作,直到增量减小为1,再进行一次插入排序。不同的增量序列会影响希尔排序的效率,一般采用Hibbard增量序列或Sedgewick增量序列来提高排序效率。

        希尔排序算法时间复杂度为O(nlogn)到O(n^2)之间,取决于增量序列的选择。在一般情况下,希尔排序具有较好的排序效率和稳定性,特别适用于数据量较大、无序性较强的序列。

4..2 代码实现 

下面是C语言实现希尔排序的代码:

void shell_sort(int arr[], int len)
{int gap, i, j, temp;for (gap = len / 2; gap > 0; gap /= 2) {  // gap为步长,每次减半直到为1for (i = gap; i < len; i++) {temp = arr[i];for (j = i - gap; j >= 0 && arr[j] > temp; j -= gap) {arr[j + gap] = arr[j];  // 向后移动gap位}arr[j + gap] = temp;  // 插入到正确位置}}
}

        该代码首先将整个待排序序列分成若干个子序列,按照步长进行插入排序。然后逐渐缩小步长,直至为1,最后进行一次普通的插入排序,完成整个排序过程。

相关文章:

【数据结构】插入排序:直接插入排序、折半插入排序、希尔排序的学习知识总结

目录 1、排序的基本概念 2、直接插入排序 2.1 算法思想 2.2 代码实现 3、折半插入排序 3.1 算法思想 3.2 代码实现 4、希尔排序 4.1 算法思想 4..2 代码实现 1、排序的基本概念 排序是将一组数据按照预定的顺序排列的过程&#xff0c;排序的基本概念包括以下内容…...

Magic Battery for Mac:让你的设备电量管理变得轻松简单

Mac电脑用户们&#xff0c;你们是否曾经为了给设备充电而感到烦恼&#xff1f;是否希望能够方便地查看连接设备的电量情况&#xff1f;现在&#xff0c;有了Magic Battery for macOS&#xff0c;这些问题都将成为过去&#xff01; Magic Battery是一个实用的应用程序&#xff…...

nodejs+vue大学食堂订餐系统elementui

可以查看会员信息&#xff0c;录入新的会员信息&#xff0c;对会员的信息进行管理。 网站管理模块对整个网站中的信息进行管理&#xff0c;可以查看会员留在留言栏中的信息&#xff0c;设置网站中的参数等。用户管理模块主要实现用户添加、用户修改、用户删除等功能。 近年来&…...

nat综合实验

路漫漫其修远兮,吾将上下而求索。 实验目的如图 实验思路&#xff1a;配置内网&#xff0c;再配置外网&#xff0c;再做nat clien1配置 clien2配置 pc3配置 lsw1配置 sysname lsw1 # vlan batch 10 20 30 # interface MEth0/0/1 # interface Eth-Trunk1port link-type trunkp…...

【iOS逆向与安全】好用的一套 TCP 类

初始化 //页面 %hook xxxxxxxViewController//- (void)viewWillAppear:(BOOL)animated{ //NSLog("View Will Appear&#xff0c;再次进入刷新"); - (void)viewDidLoad{//启动tcp[[Xddtcp sharedTcpManager] connectServer] ;} 发送数据 //发送数据 [[Xddtcp shared…...

Ubuntu Kafka开机自启动服务

1、创建service文件 在/lib/systemd/system目录下创建kafka.service文件 [Unit] DescriptionApache Kafka Server Documentationhttp://kafka.apache.org/documentation.html Requireszookeeper.service[Service] Typesimple Environment"JAVA_HOME/usr/local/programs/j…...

c#实现单例模式的两种方法(饿汉式、懒汉式)

在C#中&#xff0c;可以使用以下几种方式来实现单例模式&#xff1a; 饿汉式单例模式&#xff08;Eager Singleton&#xff09;&#xff1a; 在类加载时就创建实例。私有化构造函数&#xff0c;防止外部实例化。提供一个静态的只读属性来获取实例。代码示例&#xff1a; // 在C…...

Git与Repo:开源开发的得力工具组合

Git与Repo&#xff1a;开源开发的得力工具组合 1. 引言 开源开发在当今的软件行业中扮演着至关重要的角色。它不仅推动了技术的创新和进步&#xff0c;也促进了开发者之间的合作与共享。随着越来越多的开源项目的涌现&#xff0c;有效的代码管理和版本控制成为了必不可少的工…...

centos7 添加网卡设置动态ip,修改网卡为任意名称

centos7 添加网卡并设置动态ip&#xff0c;重命名为任意名称 本文记录如何在centos环境上增加两个网卡&#xff0c;并设置为动态获取ip&#xff0c;以及修改网卡名称为任意名称 1、centos7添加两个网卡动态获取ip 1.1 vmvare上添加网络适配器 1、关闭虚拟机 2、 添加网络适…...

计算机竞赛 深度学习人脸表情识别算法 - opencv python 机器视觉

文章目录 0 前言1 技术介绍1.1 技术概括1.2 目前表情识别实现技术 2 实现效果3 深度学习表情识别实现过程3.1 网络架构3.2 数据3.3 实现流程3.4 部分实现代码 4 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习人脸表情识别系…...

nvm安装后node或npm不是内部或外部命令

nvm安装后出现node或npm不是内部或外部命令 进行以下步骤解决 找到nvm安装所在位置&#xff0c;新建一个空的nodejs文件夹 打开 windowr —> sysdm.cpl —> 高级 —>环境变量 将下图中两个位置的地址改成刚刚新建的nodejs空文件夹所在的位置 nvm安装后都是会自动添加…...

Kafka数据可靠性保证

1.生产者发送数据到Topic partition的可靠性保证 为保证producer发送的数据&#xff0c;能可靠的发送到指定的topic&#xff0c;topic的每个partition收到producer发送的数据后&#xff0c;都需要向producer发送ack&#xff08;acknowledgement确认收到&#xff09;&#xff0c…...

基于R的linkET包qcorrplot可视化Mantel test相关性网络热图分析correlation heatmap

写在前面 需求是对瘤胃宏基因组结果鉴定到的差异菌株与表观指标、瘤胃代谢组、血清代谢组、牛奶代谢组中有差异的部分进行关联分析&#xff0c;效果图如下&#xff1a; 数据准备 逗号分隔的csv格式文件&#xff0c;两个表格&#xff0c;一个是每个样本对应的表观指标数据&…...

IOTDB的TsFile底层设计

目录 概述 数据模型 数据结构 元数据注册 读取和写入 设计思想 主要过程...

MATLAB算法实战应用案例精讲-【人工智能】边缘计算(补充篇)

目录 前言 算法原理 传统边缘检测算子 构建通用的边缘检测算子 图...

Linux学习-HIS系统部署(1)

Git安装 #安装中文支持&#xff08;选做&#xff09; [rootProgramer ~]# echo $LANG #查看当前系统语言及编码 en_US.UTF-8 [rootProgramer ~]# yum -y install langpacks-zh_CN.noarch #安装中文支持 [rootProgramer ~]# vim /etc/locale.co…...

Cairo介绍及源码构建安装(3)

接前一篇文章&#xff1a;Cairo介绍及源码构建安装&#xff08;2&#xff09; 四、Cairo构建与安装 2. 配置 BLFS中给出的命令为&#xff1a; ./configure --prefix/usr \--disable-static \--enable-tee 这里将“--prefix”选项由“/usr”调整为“/usr/local”&#x…...

Mac电脑信息大纲记录软件 OmniOutliner 5 Pro for Mac中文

OmniOutliner 5 Pro是一款专业级的Mac大纲制作工具&#xff0c;它可以帮助用户更好地组织和管理信息&#xff0c;以及制作精美的大纲。以下是OmniOutliner 5 Pro的主要功能和特点&#xff1a; 强大的大纲组织和管理功能。OmniOutliner 5 Pro为用户提供了多层次的大纲结构&…...

linux设置应用开机自启(通用:mysql、jar、nginx、solr...)

1. 业务场景 用于单机生产环境&#xff0c;防止服务器断电或者强制重启导致的服务下线。 2. 实现方案 对于无状态服务&#xff0c;可容器部署设置 restart: always&#xff0c;systemctl eable docker对于有状态服务&#xff0c;可编写自启脚本&#xff0c;如下 ① 编写执行…...

Offset Explorer(Kafka消息可视化工具)报invalid hex digit ‘{‘错误解决方法

解决办法&#xff1a; 根据代码的实际情况&#xff0c;设置成对应的值。设置完成后点update、refresh更新。...

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中&#xff0c;Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染&#xff08;即CPU被阻塞&#xff09;&#xff0c;这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&…...

【位运算】消失的两个数字(hard)

消失的两个数字&#xff08;hard&#xff09; 题⽬描述&#xff1a;解法&#xff08;位运算&#xff09;&#xff1a;Java 算法代码&#xff1a;更简便代码 题⽬链接&#xff1a;⾯试题 17.19. 消失的两个数字 题⽬描述&#xff1a; 给定⼀个数组&#xff0c;包含从 1 到 N 所有…...

【JavaSE】绘图与事件入门学习笔记

-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角&#xff0c;以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向&#xff0c;距离坐标原点x个像素;第二个是y坐标&#xff0c;表示当前位置为垂直方向&#xff0c;距离坐标原点y个像素。 坐标体系-像素 …...

大数据学习(132)-HIve数据分析

​​​​&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4…...

Windows安装Miniconda

一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...

【网络安全】开源系统getshell漏洞挖掘

审计过程&#xff1a; 在入口文件admin/index.php中&#xff1a; 用户可以通过m,c,a等参数控制加载的文件和方法&#xff0c;在app/system/entrance.php中存在重点代码&#xff1a; 当M_TYPE system并且M_MODULE include时&#xff0c;会设置常量PATH_OWN_FILE为PATH_APP.M_T…...

Python实现简单音频数据压缩与解压算法

Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中&#xff0c;压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言&#xff0c;提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...

pgsql:还原数据库后出现重复序列导致“more than one owned sequence found“报错问题的解决

问题&#xff1a; pgsql数据库通过备份数据库文件进行还原时&#xff0c;如果表中有自增序列&#xff0c;还原后可能会出现重复的序列&#xff0c;此时若向表中插入新行时会出现“more than one owned sequence found”的报错提示。 点击菜单“其它”-》“序列”&#xff0c;…...

【QT控件】显示类控件

目录 一、Label 二、LCD Number 三、ProgressBar 四、Calendar Widget QT专栏&#xff1a;QT_uyeonashi的博客-CSDN博客 一、Label QLabel 可以用来显示文本和图片. 核心属性如下 代码示例: 显示不同格式的文本 1) 在界面上创建三个 QLabel 尺寸放大一些. objectName 分别…...