直接插入排序_希尔排序

文章目录

  • 直接插入排序
    • 原理
    • 步骤
    • 视频演示
    • 代码实现
    • 特性
  • 希尔排序
    • 原理
    • 步骤
    • 图像演示
    • 代码实现
    • 希尔排序的分析
    • 特性
  • 直接插入排序和希尔排序的比较

直接插入排序

直接插入排序(Straight InsertionSort)是一种最简单的排序方法,其基本操作是将一条记录插入到已排好的有序表中,从而得到一个新的、记录数量增1的有序表。

原理

通过构建有序序列,对于未排序的数据,在已排序的序列中从后向前遍历,找到相应位置并插入。

在这里插入图片描述

步骤

1.将第一个元素设为已排序
2.对于每个未排序的元素x
a.提取x
b.将x到已排序的元素中从后向前遍历
c.如果当前元素y>x,y后移一位。反之找到x的正确位置,跳出循环
d.在此插入x的值

视频演示

录制_2023_12_16_19_21_08_556

代码实现

void insertsort(int* a, int n)
{
	for (int i = 0; i < n - 1; i++)
	{
		int x = i;
		int tmp = a[x + 1];
		while (x >= 0)//将要插入的元素到首元素进行遍历
		{
			if (tmp<a[x])//不要用a[x+1]和a[x]比较,因为x再变化,而要x在插入前不变,这个循环为了找到要找到x的位置
			{
				a[x + 1] = a[x];
				x--;
			}
			else
			{
				break;
			}
		}//while循环找到要插入的元素的正确的位置
		a[x + 1] = tmp;//插入x
	}
}
   

int main()
{
	int a[] = { 33,43,14,35,29,28,38,12,2,16,4,13 };
	int n = sizeof(a) / sizeof(a[0]);
	for (int i = 0; i < n; i++)
	{
		printf("%d ", a[i]);
	}
	printf("\n");
	insertsort(a, n);
	for (int i = 0; i < n; i++)
	{
		printf("%d ", a[i]);
	}
	return 0;
}

在这里插入图片描述

特性

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

  • 当用直接插入的升序排序去排一个降序的数组时,每个未排序的数x都要遍历完前面所有有序的数才能找到正确的位置,此时时间复杂度最大,为n^2。而一个直接插入的升序排序去排一个接近升序的数组时,遍历的效率大大提高,时间效率也就越高。

  • 排序算法的稳定性的定义:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,A1=A2,且A1在A2之前,而在排序后的序列中,A1仍在A2之前,则称这种排序算法是稳定的;否则称为不稳定的。
    比如将上面直接插入排序代码的tmp<a[x]改成tmp<=a[x]。则两个相等的记录会被交换,此时该排序算法就变得不稳定了。

希尔排序

希尔排序(Shell’s Sort)是插入排序的一种,又称“缩小增量排序”(Diminishing IncrementSort),是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。该方法因 D.L.Shell 于 1959 年提出而得名。
希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至 1时,整个文件恰被分成一组,算法便终止。

通过上面的直接插入排序我们了解到:当元素集合越接近有序,直接插入排序算法的时间效率越高。而希尔排序就是将一些无序的数据进行调整,变成接近有序的数据,最后通过直接插入排序来完成排序。

原理

希尔排序的过程可以分为预排序排序
进行预排序时,先将原序列分成n个子序列(n为增量,一般为序列长度的一半)然后进行直接插入排序,之后增量取原增量的一半,进行插入排序,直到增量为1时,序列接近有序,再进行一次直接插入排序。

  • 希尔排序的增量是希尔在排序算法中提出的一组增量序列,这个增量序列的递推公式是ht=N/2,h[k+1]=h[k]/2,也就是说增量序列是{N/2,(N/2)/2,…,1}。在希尔排序中,使用这个增量序列来分割待排序的数组,并对每个子序列进行插入排序。通过逐渐减小增量,最终使整个数组变得有序。

步骤

1.预排序
a.设置增量序列并进行直接插入排序
b.不断缩小增量重复a,使原序列接近有序
2.排序

图像演示

在这里插入图片描述

代码实现

void shellsort(int* a, int n)
{
	int gap = n;
	while (gap>1)
	{
	gap = gap /2;

		for (int i = 0; i < n - gap; i++)//这里每循环一次,代表已完成对一个子序列的排序
		{
			int x = i;
			int tmp = a[x + gap];//当gap为1时就是直接插入排序
			while (x >= 0)
			{
				if (tmp > a[x])
				{
					a[x + gap] = a[x];
					x -= gap;
				}
				else
				{
					break;
				}
			}
			a[x + gap] = tmp;
		}
	}
}


int main()
{
	int a[] = { 33,43,14,35,29,28,38,12,2,16,4,13 };
	int n = sizeof(a) / sizeof(a[0]);
	for (int i = 0; i < n; i++)
	{
		printf("%d ", a[i]);
	}
	printf("\n");
	/*insertsort(a, n);
	for (int i = 0; i < n; i++)
	{
		printf("%d ", a[i]);
	}*/
	shellsort(a, n);
	for (int i = 0; i < n; i++)
	{
		printf("%d ", a[i]);
	}
	return 0;
}

在这里插入图片描述

希尔排序的分析

《数据结构(C语言版)》-严蔚敏

希尔排序的分析是一个复杂的问题,因为它的时间是所取“增量”序列的函数,这涉及一些数学上尚未解决的难题。因此,到目前为止尚未有人求得一种最好的增量序列,但大量的研究已得出一些局部的结论。如有人指出,当增量序列为dlta[k]=
-1时,希尔排序的时间复杂度为O( n(3/2) ),其中t为排序趟数,1≤k≤t≤ log2(n+1)。还有人在大量的实验基础上推出:当n在某个特定范围内,希尔排序所需的比较和移动次数约为
n1.3,当n→∞时,可减少到n( log2n)2[2]

增量序列可以有各种取法,但需注意:应使增量序列中的值没有除1之外的公因子,并且最后一个增量值必须等于1。

《数据结构-用面相对象方法与C++描述》— 殷人昆
gap 的取法有多种。最初 Shell 提出取 gap =[n/2],gap=[gap/2]直到 gap =1,后来 Knuth 提出取 gop =[gap/3] +1。还有人提出都为好,也有人提出 gap 互质为 好。无论哪一种主张都没有得到证明。
对希尔排序的时间复杂度的分析很困难,在特定情况下可以准确地估算关键码的比较次数和对象移动次数,但想要弄清关键码比较次数和对象移动次数与增量选择之间的依赖关系,并给出完整的数学分析,还没有人能够做到。在Knuth所著的《计算机序设计技巧》第3卷中,利用大量的实验统计资料得出,当n很大时,关键码平均比较次数和对象平均称动次数大约在n1.251.6n1.25范围内,这是在利用直接插入排序作为子序列排序方法的情况下得到的。

特性

1. 希尔排序是对直接插入排序的优化。
2. 当gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,数组已经接近有序的了,这样就会很快。这样整体而言,可以达到优化的效果。我们实现后可以进行性能测试的对比。
3. 时间复杂度:因为咋们的gap是按照Knuth提出的方式取值的,而且Knuth进行了大量的试验统计,我们暂时就按照n1.25到1.6n1.25来算。
4. 稳定性:不稳定

直接插入排序和希尔排序的比较

我们使用clock函数对两种排序的运行时间进行测量并比较,测量排序100000个数据的时间。

int main()
{

	srand(time(0));
	const int N = 100000;
	int* a1 = (int*)malloc(sizeof(int) * N);

	for (int i = 0; i < N; ++i)
	{
		a1[i] = rand();
	}
	int begin1 = clock();
	insertsort(a1, N);
	int end1 = clock();

	int begin2 = clock();
	shellsort(a1, N);
	int end2 = clock();

	printf("insertsort: %d\n", end1 - begin1);
	printf("shellsort: %d\n", end2 - begin2);
	free(a1);
	return 0;
}

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

腾讯云:AI云探索之路

随着科技的飞速发展&#xff0c;人工智能(AI)云计算领域日益显现出其巨大的潜力和价值。在这个充满挑战和机遇的领域&#xff0c;腾讯云凭借其卓越的技术和创新能力&#xff0c;取得了令人瞩目的成果。本文将深入探讨腾讯云在AI云计算领域的优势&#xff0c;以及其为人工智能发…

Multi-sensor KIT-V3.0 多传感器开发板

Multi-sensor KIT-V3.0 多传感器开发板 1.前言1.1 特点 2. Multi-sensor KIT QMA8658A-EVB QMC5883评估板的扩展2.1 特点 3. Multi-sensor KIT &#xff08;QMA8658A-EVB QMC5883&#xff09; Ultrasonic-CH-X01-EVB评估板的扩展3.1 特点 4.资料资源Multi-sensor KIT-V3.0 …

基于Hadoop的农产品价格信息检测分析系统

基于Hadoop的农产品价格信息检测分析系统 前言数据处理模块1. 数据爬取2. 数据清洗与处理3. 数据存储 数据分析与检测模块1. 农产品价格趋势分析2. 农产品价格检索3. 不同市场价格对比 创新点 前言 为了更好地了解农产品市场价格趋势和不同市场之间的价格差异&#xff0c;我设…

swing快速入门(十五)

注释很详细&#xff0c;直接上代码 上一篇 新增内容 1.文件对话框&#xff08;保存文件&#xff09; 2.文件对话框&#xff08;打开文件&#xff09; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener;public class swing_tes…

飞天使-docker知识点4-harbor

文章目录 Harbor安装完成harbor 官方建议方式之后查看 images配置docker 使用harbor 仓库上传下载镜像docker 镜像结合harbor 运行 Harbor Harbor 是一个用于存储和分发 Docker 镜像的企业级 Registry 服务器&#xff0c;由 vmware 开源&#xff0c;其通过添加一些企业必需的功…

前后端开发鄙视链的真相,希望对从事前后端开发的小伙伴有些帮助

一、常规的工资对比 前后端的工资情况怎么样?过来人可以负责任的告诉大家:据我所知,至少在杭的网易、阿里,前端跟后端是一个批发价。

【PostgreSQL】从零开始:(二)PostgreSQL下载与安装

【PostgreSQL】从零开始:&#xff08;二&#xff09;PostgreSQL下载与安装 Winodws环境下载与安装PostgreSQL下载PostgreSQL安装PostgreSQL1.登录数据库2.查看下我们已有的数据库 Liunx环境下载与安装PostgreSQL使用YUM下载安装PostgreSQL1.下载PostgreSQL安装包2.安装PostgreS…

DCN神州数码WAF-P-2021命令行恢复出厂

注意&#xff1a;执行该命令将会清除设备的所有配置信息&#xff0c;包括网络配置、安全策略等&#xff0c;并将设备恢复到出厂设置时的默认配置。在执行该操作之前&#xff0c;请务必备份重要的设备配置信息。 Console接入波特率9600&#xff0c;输入帐号密码admin/yunke1234…

Mac安装软件显示文件已损坏处理方法

今天安装软件&#xff0c;突然遇到了文件已损坏&#xff0c;扔到废纸篓的情况&#xff0c;于是搜索了下解决办法&#xff0c;跟大家分享下&#xff0c;希望对你有所帮助 一、检查安全性设置 打开【设置】-【隐私与安全】&#xff0c;下拉找到安全性&#xff0c;将安全性更改为…

【动态规划】06路径问题_不同路径II_C++(medium)

题目链接&#xff1a;leetcode不同路径II 目录 题目解析&#xff1a; 算法原理 1.状态表示 2.状态转移方程 3.初始化 4.填表顺序 5.返回值 编写代码 题目解析&#xff1a; 题目让我们求在考虑网格中有障碍物的情况下&#xff0c;从左上角到右下角将会有多少条不同的路径…

JVM虚拟机系统性学习-垃圾回收器CMS、G1和ZGC

CMS&#xff1a;低延迟 在 JDK1.5 时&#xff0c;HotSpot 推出了 CMS 收集器&#xff0c;CMS 收集器是 HotSpot 虚拟机中第一款真正意义上的并发收集器&#xff0c;它第一次实现了让垃圾收集线程和用户线程同时工作CMS 收集器关注尽可能地降低用户线程的停顿时间&#xff0c;停…

linux常见错误

1.E45: ‘readonly‘ option is set (add ! to override) 首先使用以下命令从Vim编辑器中出来&#xff1a;:qa!(强制退出) 接下来&#xff0c;使用sudo vim filename和更高版本&#xff1a;:wq 2.Bash script – "/bin/bash^M: bad interpreter: No such file or direc…

如何退回chrome旧版ui界面?关闭Chrome浏览器新 UI 界面

之前启用新UI的方式 Chrome 已经很久没有进行过大的样式修改&#xff0c;但近期在稳定分支中添加了新的 flags 实验性标志&#xff0c;带来了全新的设计与外观&#xff0c;启用方式如下&#xff1a; 在 Chrome 浏览器的搜索栏中输入并访问 chrome://flags 搜索“refresh 2023…

高效营销系统集成:百度营销的API无代码解决方案,提升电商与广告效率

百度营销API连接&#xff1a;构建无代码开发的高效集成体系 在数字营销的高速发展时代&#xff0c;企业追求的是快速响应市场的能力以及提高用户运营的效率。百度营销API连接正是为此而生&#xff0c;它通过无代码开发的方式&#xff0c;实现了电商平台、营销系统和CRM的一站式…

第十一章 SpringCloud Alibaba 实现Rocketmq–消息驱动

MQ简介 什么是MQ MQ&#xff08;Message Queue&#xff09;是一种跨进程的通信机制&#xff0c;用于传递消息。通俗点说&#xff0c;就是一个先进先出的数 据结构。 MQ的应用场景 异步解耦 最常见的一个场景是用户注册后&#xff0c;需要发送注册邮件和短信通知&#xff…

Qt中槽函数在那个线程执行的探索和思考

信号和槽是Qt的核心机制之一&#xff0c;通过该机制大大简化了开发者的开发难度。信号和槽属于观察者模式&#xff08;本质上是回调函数的应用&#xff09;。是函数就需要考虑其是在那个线程中执行&#xff0c;本文讨论的就是槽函数在那个线程中执行的问题。 目录 1. connect…

[BUG]TDA4 main域 CAN 无法进中断

目录 关键词平台说明一、背景二、根本原因2.1 Com模块 三、措施 关键词 嵌入式、C语言、autosar、TDA4 平台说明 项目ValueOSautosar OSautosar厂商vector芯片厂商TI编程语言C&#xff0c;C编译器HighTec (GCC) 一、背景 在将mcu域的部分can 移植到main域的时候发现无法进…

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《考虑灵活性资源传输精细化建模的配电网优化运行》

这个标题表达的是关于配电网优化运行的一个概念&#xff0c;其中考虑了灵活性资源传输的精细化建模。让我们逐个解读关键词&#xff1a; 考虑灵活性资源传输&#xff1a;这指的是在配电网优化运行中考虑到不同类型的灵活性资源的传输。灵活性资源包括可再生能源、储能系统、柔性…

HarmonyOS首次尝试-HelloWorld

我的旧手机是个HUAWEI PCT-AL10 HarmonyOS 3.0.0(Android 10) 插上后&#xff0c;studio能显示连接上了手机设备&#xff0c;创建的demo使用的是API9&#xff0c;也就是当前的最新版本。 点击运行报错&#xff1a; 点击去往帮助页&#xff0c;做的也挺好&#xff0c;有直达的…

抠图软件哪个好用?什么软件可以抠图换背景?

抠图软件哪个好用&#xff1f;在图片处理中&#xff0c;抠图换背景是一项常见的操作。很多新手可能会对此感到困惑&#xff0c;不知道应该使用什么软件来进行抠图换景。实际上&#xff0c;现在市面上有很多图片处理软件都具备抠图换背景的功能&#xff0c;每款软件都有其优缺点…