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

news/2024/7/5 1:40:38

希尔排序

希尔排序法又称缩小增量法。希尔排序法的基本思想是:先选定一个整数,把待排序文件中所有记录分成个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;
		}
	}				
}


http://lihuaxi.xjx100.cn/news/1898657.html

相关文章

【注解和反射】--05 反射的性能对比、反射操作泛型和注解

反射 05 性能对比分析 下面对比了通过普通new方式、反射方式及关闭Java语言安全检测的反射方式三种情况下&#xff0c;程序的性能(所需时间)。 package com.duo.reflection;import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method;//性能测试…

【深度学习目标检测】八、基于yolov5的抽烟识别(python,深度学习)

YOLOv5是目标检测领域一种非常优秀的模型&#xff0c;其具有以下几个优势&#xff1a; 1. 高精度&#xff1a;YOLOv5相比于其前身YOLOv4&#xff0c;在目标检测精度上有了显著的提升。YOLOv5使用了一系列的改进&#xff0c;如更深的网络结构、更多的特征层和更高分辨率的输入图…

【Redis】AOF 基础

因为 Redis AOF 的实现有些绕, 就分成 2 篇进行分析, 本篇主要是介绍一下 AOF 的一些特性和依赖的其他函数的逻辑,为下一篇 (Redis AOF 源码) 源码分析做一些铺垫。 AOF 全称: Append Only File, 是 Redis 提供了一种数据保存模式, Redis 默认不开启。 AOF 采用日志的形式来记…

DevOps常用工具全家桶,实现高效运维和交付

专栏集锦&#xff0c;大佬们可以收藏以备不时之需&#xff1a; Spring Cloud 专栏&#xff1a;http://t.csdnimg.cn/WDmJ9 Python 专栏&#xff1a;http://t.csdnimg.cn/hMwPR Redis 专栏&#xff1a;http://t.csdnimg.cn/Qq0Xc TensorFlow 专栏&#xff1a;http://t.csdni…

【二分查找】自写二分函数的总结

作者推荐 【动态规划】【广度优先搜索】LeetCode:2617 网格图中最少访问的格子数 本文涉及的基础知识点 二分查找算法合集 自写二分函数 的封装 我暂时只发现两种&#xff1a; 一&#xff0c;在左闭右开的区间寻找最后一个符合条件的元素&#xff0c;我封装成FindEnd函数。…

设计模式—装饰模式

与其明天开始&#xff0c;不如现在行动&#xff01; 文章目录 装饰模式—穿衣服&#x1f48e;总结 装饰模式—穿衣服 装饰模式&#xff08;Decorator&#xff09;可以动态的给对象添加一些额外的职责。 Component是定义一个对象接口&#xff0c;可以给这些对象动态地添加职责。…

HPV治疗期间如何预防重复感染?谭巍主任讲述具体方法

众所周知&#xff0c;人乳头瘤病毒(HPV)是一种常见的性传播疾病&#xff0c;感染后可能会引起生殖器疣、宫颈癌等疾病。在治疗期间&#xff0c;预防重复感染非常重要。今日将介绍一些预防HPV重复感染的方法。 1. 杜绝不洁性行为 在治疗期间&#xff0c;患者应该避免与感染HPV…

FLStudio2024完整版水果音乐编曲制作软件

FL Studio2024是款专业的音频录制编辑软件&#xff0c;可以针对作曲者的要求编辑出不同音律的节奏&#xff0c;例如鼓、镲、锣、钢琴、笛、大提琴等等任何乐器的节奏律动。FL Studio目前在中国已经受到广大制作人喜爱&#xff0c;使用它制作的音乐作品也已经数不胜数&#xff0…