直接插入排序_希尔排序

news2024/12/28 3:00:37

文章目录

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

直接插入排序

直接插入排序(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;
}

在这里插入图片描述

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

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

相关文章

智能优化算法应用:基于动物迁徙算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于动物迁徙算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于动物迁徙算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.动物迁徙算法4.实验参数设定5.算法结果6.…

MinGW编译Python至pyd踩坑整理

title: MinGW编译Python至pyd踩坑整理 tags: [Python,CC] categories: [开发记录,Python] date: 2023-12-12 13:48:20 description: sidebar: [‘toc’, ‘related’,‘recent’] 注意需要魔法 用scoop自动安装配置MinGw 需要魔法&#xff0c;不需要手动配置mingw scoop in…

FreeRDP WebConnect Url 任意文件读取漏洞复现

0x01 产品简介 FreeRDP-WebConnect 是一个开源HTML5代理&#xff0c;它提供对使用RDP的任何Windows服务器和工作站的Web访问。 0x02 漏洞概述 FreeRDP WebConnect Url 接口处存在任意文件读取漏洞&#xff0c;攻击者可通过该漏洞读取系统重要文件&#xff08;如数据库配置文…

自动驾驶学习笔记(十九)——Planning模块

#Apollo开发者# 学习课程的传送门如下&#xff0c;当您也准备学习自动驾驶时&#xff0c;可以和我一同前往&#xff1a; 《自动驾驶新人之旅》免费课程—> 传送门 《Apollo 社区开发者圆桌会》免费报名—>传送门 文章目录 前言 Planning作用 Planning内容 Plannin…

【深度强化学习】DQN, Double DQN, Dueling DQN

DQN 更新方程 Q θ ( s t , a t ) ← Q θ ( s t , a t ) α ( r t γ max ⁡ a ′ Q θ ( s t 1 , a ′ ) − Q θ ( s t , a t ) ) Q_\theta(s_t,a_t) \leftarrow Q_\theta(s_t,a_t) \alpha \left( r_t \gamma \red{\max_{a} Q_\theta(s_{t1},a)} - Q_{\theta}(s_t,a_t…

Cmake基础(4)

这篇文章在上一篇的基础之上应用多文件&#xff0c;即一个项目中添加多个文件 文章目录 GLOBsource_group排除文件 上一篇文章的cmake基本不变&#xff0c;这篇文章的重点在于add_executable(${EXECUTABLE_NAME} main.cpp) GLOB file(GLOB cpp_list ${CMAKE_CURRENT_SOURCE_…

继电器模块的使用(超详细)

继电器模块的工作原理 继电器&#xff08;Relay&#xff09;是一种电控开关&#xff0c;其工作原理基于电磁感应。继电器通常包括一个电磁线圈和一组触点。 以下是继电器模块的基本工作原理&#xff1a; 电磁线圈&#xff1a; 继电器内部包含一个电磁线圈&#xff0c;通常由绕制…

深度学习:混合精度训练

深度学习&#xff1a;混合精度训练 前言混合精度训练核心技术权重备份损失缩放梯度裁剪动态调整学习率 优势与弊端代码示例 参考文献 前言 浮点数据类型主要分为双精度Double&#xff08;FP64&#xff09;、单精度Float&#xff08;FP32&#xff09;和半精度Half&#xff08;F…

如何在页面中加入百度地图

官方文档&#xff1a;jspopularGL | 百度地图API SDK (baidu.com) 添加一下代码就可以实现 <!DOCTYPE html> <html> <head><meta name"viewport" content"initial-scale1.0, user-scalableno"/><meta http-equiv"Conten…

基于Springboot的高校教学评价系统的设计与实现(源码+调试)

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。今天给大家介绍一篇基于Springboot的高校教…

idea2023解决右键没有Servlet的问题

复制Servlet Class.java中的文件。 回到文件&#xff0c;然后点击小加号 然后输入刚刚复制的东西&#xff1a; 3. 此时右键有servlet。 4. 然后他让你输入下面两个框&#xff1a; JAVAEE TYPE中输入Servlet Class Name 表示你要创建的Servlet类的名称是什么。自己起名字。然后…

EIS(防抖):meshflow算法

视频防抖的应用 对视频防抖的需求在许多领域都有。 这在消费者和专业摄像中是极其重要的。因此&#xff0c;存在许多不同的机械、光学和算法解决方案。即使在静态图像拍摄中&#xff0c;防抖技术也可以帮助拍摄长时间曝光的手持照片。 在内窥镜和结肠镜等医疗诊断应用中&…

用代码写uml并在线生成uml图

可以用PlantUml写uml,并在线生成uml图。 startuml start:登录系统; if (用户名和密码正确?) then (yes):进入系统首页;:展示主菜单; else (no):显示登录错误;stop endif:选择模块; partition "课程信息" {:查看课程列表;:查看课程详情; } partition "课程签到…

uniapp的uni-im 即时通信使用教程【用户与商家对话、聊天 / 最新 / 最全 / 带源码 / 教程】

目录 使用场景用户图片商家图片 官方文档官方文档地址插件地址 项目创建uniCloud开发环境申请开发环境申请完后 概括开始使用步骤1App.vue 步骤2找到软件登录图片找到软件登录接口登录源码如下 步骤3找到软件注册图片注册源码如下 步骤4找到index.vue首页图片 index.vue源码如下…

[robot_state_publisher-3] Error: Error document empty.

出现这个问题&#xff0c;我这里遇到的是&#xff1a;指定的urdf文件路径无效&#xff0c;而产生这个的根本原因是没有在CMakelists.txt中添加如下代码&#xff1a; install( DIRECTORY urdf DESTINATION share/${PROJECT_NAME} )把urdf文件夹添加到指定的share/${PROJEC…

第15章 《乐趣》Page305~311, 代码精简以后,讨论一下引用含义的问题

将Page305~311的代码精简了一下&#xff0c;讨论一下引用含义的问题&#xff0c;精简之后的代码如下&#xff1a; #include <iostream> #include <SDL2/SDL.h>using namespace std;namespace sdl2 {char const* last_error() {return SDL_GetError(); }struct Ini…

贪心算法:买卖股票的最佳时机II 跳跃游戏 跳跃游戏II

122.买卖股票的最佳时机II 思路&#xff1a; 想要获得利润&#xff0c;至少要以两天为一个交易单元&#xff0c;因为两天才会有股价差。因此可以将最终利润进行分解&#xff0c;如prices[3] - prices[0] (prices[3] - prices[2]) (prices[2] - prices[1]) (prices[1] - pr…

07-抽象工厂

意图 提供一个创建一系列相关或相互依赖对象的接口&#xff0c;而无需指定它们具体的类。 适用性 在以下的情况可以选择使用抽象工厂模式&#xff1a; 一个系统要独立于它的产品的创建、组合和表示。一个系统要由多个产品系列中的一个来配置。要强调一系列相关的产品对象的…

Elasticsearch优化-04

Elasticsearch优化 1、优化-硬件选择 Elasticsearch 的基础是 Lucene&#xff0c;所有的索引和文档数据是存储在本地的磁盘中&#xff0c;具体的路径可在 ES 的配置文件…/config/elasticsearch.yml中配置&#xff0c;如下&#xff1a; # #Path to directory where to store …

Pytorch:Tensorboard简要学习

目录 一、TensorBoard简介二、TensorBoard的安装与启动Tensorboard的安装Tensorboard的启动 三、TensorBoard的简单使用3.1 SummaryWriter()3.2 add_scalar()和add_scalars()3.3 add_histogram()3.4 模型指标监控 四、总结参考博客 一、TensorBoard简介 TensorBoard 是Google开…