首页 > 其他分享 >如果你搞不懂排序,看这篇文章就对了,初学者也看得懂,其三:进阶插入排序——希尔排序

如果你搞不懂排序,看这篇文章就对了,初学者也看得懂,其三:进阶插入排序——希尔排序

时间:2024-11-10 19:16:49浏览次数:6  
标签:tmp end 进阶 int 插入排序 gap 排序

目录

一.希尔排序

1.1希尔排序的原理

1.2希尔排序的代码思路
1.3希尔排序的代码实现

1.1希尔排序的原理

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

希尔排序大体上可以分为两步:

1.预排序

2.插入排序

为什么要增加预排序这一步呢?

我们知道插入排序再排逆序的数组时时间复杂度为最坏的情况。所以我们才要进行预排序,预排序的目的是为了让数组接近有序。当数组接近有序时使用插入排序也就绰绰有余了。

让我们先来看第一步:

1.预排序

我们知道插入排序再排逆序的数组时时间复杂度为最坏的情况。所以我们才要进行预排序。

预排序的目的是为了让数组接近有序,简而言之预排序就是将大的数调到后面,小的数调到前面。

预排序中我们要引入分组的概念,要用到gap(间隔),让我们用画图理解:

当gap为3的时候,就是从数组的第1个数开始,找到第4个数,也就是和他间隔为3的数,再从第4个数找与它间隔为3的数,以此类推,直到数组的最后一个数,或者超出数组的范围。

2.插入排序

对插入排序有疑问的小伙伴可以看我的另一篇博客:直接插入排序

这里我就不再过多赘述了。

1.2希尔排序的代码思路

让我来看单趟预排序的代码实现以及思路:

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

这段代码就是对数组的第一个数,取间隔为gap所形成的预排序。

让我们将这段代码和插入排序的比较一下:

void InsertSort(int* a, int n)
{
	//  [0, n-1]
	for (int i = 0; i < n - 1; i++)
	{
		// [0, n-2]是最后一组
		// [0,end]有序 end+1位置的值插入[0,end],保持有序
		int end = i;
		int tmp = a[end + 1];
		while (end >= 0)
		{
			if (tmp < a[end])
			{
				a[end + 1] = a[end];
				--end;
			}
			else
			{
				break;
			}
		}
		a[end + 1] = tmp;
	}
}

​

我们会发现,这直接插入排序不就是单趟预排序的gap变成了1嘛。

换而言之,直接插入排序就是gap为一的预排序。

预排序的完整代码如下:


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

当j为0时,预排的是红色的一组。

当j为1时,预排的是绿色的一组。

当j为2时,预排的是紫色的一组。

1.3希尔排序的代码实现

思路讲完了,预排序也讲完了。希尔排序终于要来了。在现实情况下,我们能知道gap为多少吗?像前面我的只排6个数据,gap=3还是可以的,但是如果我们要排一百万,一千万,一亿甚至更多的数呢?gap又要怎么算呢?我们要知道。gap越小预排序越接近有序,但也排的越慢。gap越大,预排序越不接近有序,但排的越快。但是我们找不到gap应该取多少,所以我们可以让gap等于一个随机的数但要越来越小直到gap=1进行插入排序。

void ShellSort(int* a, int n)
{
	int gap = n;
	while (gap > 1)
	{
		// +1保证最后一个gap一定是1
		// gap > 1时是预排序
		// gap == 1时是插入排序
		gap = gap / 3 + 1;

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

标签:tmp,end,进阶,int,插入排序,gap,排序
From: https://blog.csdn.net/2302_80713191/article/details/143455065

相关文章

  • 冒泡排序(详细讲解)
    对于冒泡排序,字面理解就是对一段数据进行排序比如说你有10个数据intarr[10]={3,1,7,5,8,9,0,2,4,6};你想对这些数据进行从小到大的排序,一个个用if和else去进行比较太麻烦了,所以这时候冒泡排序就可以帮你提高效率首先,先文字讲解,这里总共有十个数据,而我们每次排序都会将......
  • ArkTS的进阶语法-1(泛型,工具类型,空安全)
     目录ArkTS的进阶语法1.泛型......
  • 排序算法原理、应用与对比
    一、排序算法综述排序算法在计算机科学中具有至关重要的地位。在众多应用场景中,如数据库管理、搜索引擎结果排序、数据分析等,高效的排序算法能够极大地提高系统的性能和用户体验。不同类型的排序算法具有各自独特的特点和分类。从算法的稳定性来看,有些算法是稳定的,如插入排序......
  • JVM 进阶:深入理解与高级调优
    在学习了JVM的基础知识后,接下来我们将深入了解JVM的内部工作原理、高级优化方法和性能调优技巧,这些内容将帮助你更好地管理Java应用的性能,尤其是在面对大规模应用和高并发场景时。一、深入了解JVM内存结构JVM内存结构的划分和管理直接关系到Java程序的运行效率,深......
  • DICOM图像知识:DICOM图像排序与坐标系解析
    目录引言1.概述2.DICOM图像排序规则2.1Patient的Study按StudyDate排序2.2Study的Series按SeriesNumber排序2.3Series的SOP按InstanceNumber或SliceLocation排序2.3.1InstanceNumber排序2.3.2SliceLocation排序2.3.3使用ImagePosition(Patient)和Image......
  • 桶排序 选择,插入排序
    (2)选择排序:基本思想:从数组的未排序区域选出一个最小的元素,把它与数组中的第一个元素交换位置;然后再从剩下的未排序区域中选出一个最小的元素,把它与数组中的第二个元素交换位置。重复上述过程,直到数组中的所有元素按升序排列完成。【案例】对一维数组中的十个数据进行从小到大排......
  • 桶排序2
    #include<iostream>#include<bits/stdc++.h>usingnamespacestd;/*桶排序思想:把每个数组开辟的空间看作一个桶,将与桶编号相同的数据存入桶中13579864210数据b[]开辟桶的个数大于数据最大值第一步:桶内初始化为0第二步:判断数据存入桶中a[11]a[0].........
  • 【模块一】kubernetes容器编排进阶实战之kubeadm部署kubernetes
    kubeadm部署kubernetes准备环境主机名IP地址k8s-master1        10.0.0.121k8s-node110.0.0.101k8s-node210.0.0.102k8s-node310.0.0.103注:提前安装好docker或者containerd环境安装kubeadm、kubectl、kubelet#分别在所有主机依次执行一下命令apt-getupdate&&......
  • 【VBA实战】用Excel制作排序算法动画续
    为什么会产生用excel来制作排序算法动画的念头,参见【VBA实战】用Excel制作排序算法动画一文。这篇文章贴出我所制作的所有排序算法动画效果和源码,供大家参考。冒泡排序:插入排序:选择排序:快速排序:归并排序:堆排序:希尔排序:完整源码如下。OptionExplicitPublichm......
  • 排序算法 - 冒泡
    文章目录1.冒泡排序1.1简介1.2基本步骤:1.3示例代码(C)1.4复杂度分析1.5动画展示1.冒泡排序1.1简介冒泡排序(BubbleSort)是一种简单的排序算法,其基本思想是通过相邻元素的比较和交换,把最大的元素逐步“冒泡”到列表的末尾。该算法的名称来源于较小的元素会逐......