插入排序----希尔排序

希尔排序

希尔排序法又称缩小增量法。希尔排序法的基本思想是:先选定一个整数,把待排序文件中所有记录分成个gap组,所有距离为的记录分在同一组内,并对每一组内的记录进行排序。然后,取,重复上述分组和排序的工作。当到达=1时,所有记录在统一组内排好序

实现

希尔排序是对直接插入排序的一个优化,希尔排序分为预排和正式排序两个阶段,预排是把n个数分成gap组,每个组执行一遍直接插入排序,但是每次end不再是end--或者end+1,而是end-=gap和a[end+gap]=tmp。

gap我们初始给它赋值为n,也就是分成n组,每组一个数,这样的话也就相当于直接插入排序,因为直接插入排序我们是每次挪一个位置和Tmp比较。

for (int i = 0; i < n - gap; i++)
{
	int end = i;
	int tmp = a[end + gap];
	while (end >= 0)
	{
		if (a[end] > tmp)
		{
			a[end + gap] = a[end];
			end -= gap;
		}
		else
		{
			break;
		}
	}
	a[end + gap] = tmp;
}

上述操作也就是把直接插入排序的1换成了gap而已,而这也就相当于gap等于1时候的预排,如果这样操作的话就和直接插入排序没有任何区别,所以我们把gap=n后,第一次预排之前要 gap=gap/3+1;这个操作就是把n个数据分成3组,+1是为了保证让gap不为0,如果gap=2,2/3=0,那分成0组是什么意思?,我把n个数据分成3组进行一次预排,第一次预排之后,每一组肯定都是有序的,这时,gap再进行一次 gap=gap/3+1;也就是再把他划分为更少的组,而我们使gap=gap/3+1,这个加1还有最重要的目的就是一定会使gap=1,所有我们当gap=1时不再往下划分Gap,这个时候就是正式排序

void ShellSort(int* a, int n)//希尔排序
{
	int gap = n;
	while (gap > 1)
	{
		.......
	}				
}

gap越小,分的组越少,预排的结果越接近有序的。当gap>1时,进行的是预排序,当gap==1,进行的是正式排序。这就是希尔排序。

测试

#include<stdio.h>
int main()
{
	
	int a[] = { 6,1,2,7,9,3,4,5,10,8 };
	int n = sizeof(a) / sizeof(a[0]);
	ShelltSort(a, n);
	for (int i = 0; i < n; i++)
	{
		printf("%d ", a[i]);
	}
	return 0;
}

时间复杂度

希尔排序的时间复杂度非常难计算,我们只需要记住它大概在O(N^1.3)左右就可以了。

性能测试

我们使用c语言随机生成的随机数,对这两个排序进行性能测试,我们测试的是1000000个随机数,(由于C语言生成的随机数只能有30000多个,所以我们在每个随机数后面再加上第几次循环的i可以大大减少重复的数据)

#include<stdio.h>
#include<time.h>
#include<stdlib.h>
srand(time(0));
const int N = 1000000;
int* a1 = (int*)malloc(sizeof(int)*N);
int* a2 = (int*)malloc(sizeof(int) * N);
for (int i = 0; i < N; i++)
{
	a1[i] = rand()+i;
	a2[i] = a1[i];
	
}
int begin1 = clock();
InsertSort(a1, N);
int end1 = clock();

int begin2 = clock();
ShellSort(a2, N);
int end2 = clock();

printf("InsertSort:%d\n", end1 - begin1);
printf("ShellSort:%d\n", end2 - begin2);

free(a1);
free(a2);

结果如上,由此可以看出,希尔排序无非就是比直接插入排序多了多次预排,直接的差异竟然如此之大。 

源代码

void ShellSort(int* a, int n)//希尔排序
{
	int gap = n;
	while (gap > 1)
	{
		gap = gap/3+1;//+1保证最后一次gap为1,也就是进行直接插入排序;gap越小,预排的结果越接近有序
		for (int i = 0; i < n - gap; i++)
		{
			int end = i;
			int tmp = a[end + gap];
			while (end >= 0)
			{
				if (a[end] > tmp)
				{
					a[end + gap] = a[end];
					end -= gap;
				}
				else
				{
					break;
				}
			}
			a[end + gap] = tmp;
		}
	}				
}

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

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

相关文章

千亿露酒市场的未来之“露”

执笔 | 尼 奥 编辑 | 扬 灵 12月15日&#xff0c;以“以美为酿&#xff0c;品致未来”为主题的中国露酒产业发展大会暨露酒价值论坛在“中国酒都”宜宾举办。 近年来&#xff0c;露酒产业发展异军突起&#xff0c;市场销售规模超越黄酒、葡萄酒品类&#xff0c;成为中国酒…

【Qt QML 入门】TextEdit

TextEdit可以显示多行可编辑的格式化文。默认是无边框的&#xff0c;可以和父控件完美融合。 import QtQuick import QtQuick.Window import QtQuick.ControlsWindow {id: winwidth: 800height: 600visible: trueTextEdit {id: textEditanchors.centerIn: parenttext: "He…

Sentinel使用详解

组件简介 Sentinel是阿里开源的一套用于服务容错的综合性解决方案。它以流量为切入点&#xff0c;从流量控制、熔断降级、系统负载保护等多个维度来保护服务的稳定性。Sentinel承接了阿里巴巴近10年的双十一大促流量的核心场景&#xff0c;例如秒杀、消息削峰填谷、集群流量控…

翻译: LLM工具使用和代理Tool use and agents

欢迎来到本周的最后一个视频。在这个视频中&#xff0c;我想与您分享LLM&#xff08;大型语言模型&#xff09;开始能够使用工具的情况&#xff0c;以及讨论一下前沿的“代理”主题&#xff0c;这是让LLM自己决定下一步采取什么行动的领域。让我们来看看。在早期的食物订单接收…

操作系统期末复习-内存管理

一、内存管理 分页存储管理&#xff0c;是将一个进程的逻辑地址空间分成若干个大小相等的片&#xff0c;称为页面或页&#xff0c;并为各页加以编号&#xff0c;从0开始&#xff0c;如第0页、第1页等。相应地&#xff0c;也把内存空间分成与页面相同大小的若干个存储块&#xf…

人工智能文本分类

在本文中&#xff0c;我们全面探讨了文本分类技术的发展历程、基本原理、关键技术、深度学习的应用&#xff0c;以及从RNN到Transformer的技术演进。文章详细介绍了各种模型的原理和实战应用&#xff0c;旨在提供对文本分类技术深入理解的全面视角。 一、引言 文本分类作为人工…

交叉熵在机器学习里做损失的意义

交叉熵是机器学习中常用的损失函数之一&#xff0c;特别适用于分类任务。其背后的核心思想是衡量两个概率分布之间的差异。在分类问题中&#xff0c;通常有一个真实分布&#xff08;ground truth distribution&#xff09;和一个模型预测的分布&#xff08;predicted distribut…

knime 安装Regex Extractor节点

1、在File中&#xff0c;找到install knime extensions 2、接着输入palladian&#xff0c;然后选择select all&#xff0c;最后点击next就可以了&#xff0c;等待安装就可以了 3、然后重启knime就可以看到了Regex Extractor节点

整理了上百个开源中文大语言模型,涵盖模型、应用、数据集、微调、部署、评测

自ChatGPT为代表的大语言模型&#xff08;Large Language Model, LLM&#xff09;出现以后&#xff0c;由于其惊人的类通用人工智能&#xff08;AGI&#xff09;的能力&#xff0c;掀起了新一轮自然语言处理领域的研究和应用的浪潮。 尤其是以ChatGLM、LLaMA等平民玩家都能跑起…

PADS9.5 : 原理图电源网络 和 地网 络添加

原理图电源网络 和 地网 络添加 添加电源网络 1、点击连线 2、2、连线 3、3、连线时&#xff0c;右键 4、4、点击电源&#xff0c;因为该网络已经有3.3v&#xff0c;它会弹出网络确认&#xff0c;确定即可&#xff0c;如果 需要其他电源网络&#xff0c;双击即可修改 5、双击…

Impala4.x源码阅读笔记(一)——HdfsTextScanner解析

前言 本文为笔者个人阅读Apache Impala源码时的笔记&#xff0c;仅代表我个人对代码的理解&#xff0c;个人水平有限&#xff0c;文章可能存在理解错误、遗漏或者过时之处。如果有任何错误或者有更好的见解&#xff0c;欢迎指正。 在文章Impala3.4源码阅读笔记&#xff08;七…

环形链表Ⅱ 双指针 Java版本

文章目录 题目解题思路代码 题目 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环…

期货股市联动(期股联动助推资本市场上扬)

期股联动——期货股市助推资本市场上扬 随着我国资本市场的不断发展&#xff0c;期货和股票这两个市场也在逐渐紧密地联系起来。期货和股票的相互作用是一种“期股联动”&#xff0c;它能够促进资本市场的上扬。 期货与股票市场 期货市场是一种标准化的场外交易市场&#xf…

【JavaEE】多线程(4) -- 单例模式

目录 什么是设计模式? 1.饿汉模式 2.懒汉模式 线程安全问题 什么是设计模式? 设计模式好⽐象棋中的 "棋谱". 红⽅当头炮, ⿊⽅⻢来跳. 针对红⽅的⼀些⾛法, ⿊⽅应招的时候有⼀ 些固定的套路. 按照套路来⾛局势就不会吃亏. 软件开发中也有很多常⻅的 "问题…

如何使用Lychee结合内网穿透搭建本地私人图床网站并实现远程访问

文章目录 1.前言2. Lychee网站搭建2.1. Lychee下载和安装2.2 Lychee网页测试2.3 cpolar的安装和注册 3.本地网页发布3.1 Cpolar云端设置3.2 Cpolar本地设置 4.公网访问测试5.结语 1.前言 图床作为图片集中存放的服务网站&#xff0c;可以看做是云存储的一部分&#xff0c;既可…

架构设计系列之基础设施能力建设

周末聊两句&#xff1a; 今天将的基础设施能力建设部分&#xff0c;一般的架构书籍中都不存在的部分&#xff0c;这是我在实践过程中的经验和能力总结部分&#xff0c;希望和大家有一个很好的交流自从在 WeChat 中开了订阅号的两周半的时间&#xff0c;非常感谢大家的支持&…

大数据HCIE成神之路之数据预处理(2)——异常值处理

异常值处理 1 异常值处理1.1 散点图1.1.1 实验任务1.1.1.1 实验背景1.1.1.2 实验目标1.1.1.3 实验数据解析 1.1.2 实验思路1.1.3 实验操作步骤1.1.4 结果验证 1.2 基于分类模型的异常检测1.2.1 实验任务1.2.1.1 实验背景1.2.1.2 实验目标1.2.1.3 实验数据解析 1.2.2 实验思路1.…

手麻、腿麻、麻痛…背后竟隐藏7大疾病!多一个人知道,少一个悲剧!

手脚麻木背后的7大病症&#xff1a;骨病、脑梗、肿瘤…… 1、神经问题 上图四只手上橙色的区域代表了麻木感&#xff0c;如果您的手麻集中在无名指和小指的区域&#xff0c;您可以拿一张纸&#xff0c;用五个手指分别试着夹住&#xff0c;检验您的五个手指力量&#xff1b;您还…

Android动画(三)——属性动画

目录 介绍 属性动画的实现类 对象动画&#xff08;ObjectAnimator&#xff09; 方法1&#xff1a;Java代码实现对象动画 其它使用方法 方法2&#xff1a;XML实现对象动画 效果 ​编辑 值动画&#xff08;ValueAnimator&#xff09; PropertyValueHolder 效果图 动画组合…

Android动画(四)——属性动画ValueAnimator的妙用

目录 介绍 效果图 代码实现 xml文件 介绍 ValueAnimator是ObjectAnimator的父类&#xff0c;它继承自Animator。ValueAnimaotor同样提供了ofInt、ofFloat、ofObject等静态方法&#xff0c;传入的参数是动画过程的开始值、中间值、结束值来构造动画对象。可以将ValueAnimator看…