【数据结构】常见排序算法——常见排序介绍、插入排序、直接插入排序、希尔排序

这篇具有很好参考价值的文章主要介绍了【数据结构】常见排序算法——常见排序介绍、插入排序、直接插入排序、希尔排序。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.排序的概念和应用

1.1排序的概念

  在计算机科学中,排序是将一组数据按照指定的顺序排列的过程。排序算法由于执行效率的不同可以分为多种不同的算法。

  通常情况下,排序算法可以分为两类,即内部排序和外部排序。内部排序是指数据全部加载到内存中进行排序,适用于数据量较小的情况,而外部排序则是指针对数据量较大的情况,需要利用外部存储设备(如磁盘)进行排序。在不同场景下,我们需要选择不同的排序算法来达到最佳的排序效果。

(1)排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。

(2)稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的;否则称为不稳定的。

(3)内部排序:数据元素全部放在内存中的排序。

(4)外部排序:数据元素太多不能同时放在内存中,根据排序过程的要求不能在内外存之间移动数据的排序。

1.2排序的运用

  排序算法被广泛应用于计算机程序中,用于对数据进行排序,以便更快、更方便地处理和查询数据。这些应用包括数据库、搜索引擎、数据分析、加密、财务管理、视频处理和游戏开发等领域。
【数据结构】常见排序算法——常见排序介绍、插入排序、直接插入排序、希尔排序

  生活中很多地方都会有排序。
  
【数据结构】常见排序算法——常见排序介绍、插入排序、直接插入排序、希尔排序

1.3常见的排序算法

【数据结构】常见排序算法——常见排序介绍、插入排序、直接插入排序、希尔排序

2.常见的排序算法

2.1插入排序

  直接插入排序是一种简单的插入排序法,其基本思想是:

  插入排序特点:把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列。

我们在玩扑克时,就运用到了插入排序:

【数据结构】常见排序算法——常见排序介绍、插入排序、直接插入排序、希尔排序

2.1.1直接插入排序

  直接插入排序(Insertion Sort)是一种简单但有效的排序算法,其基本思想是将一个新元素插入到已排序好的元素序列中去。具体实现中,我们从第二个元素开始,将当前元素与前面已排序的元素进行比较,如果当前元素比前一个元素小,则将它插入前一个元素的前面,否则不做处理。如此以往,直到最后一个元素都被放入正确的位置为止。

  插入排序属于原地排序,只需要常数级别的额外空间。在处理小规模数据集时比较高效,但在处理大型数据集时会有些效率问题。它的时间复杂度为O(n2)但由于其常数项比冒泡排序和选择排序小,因此实际运行时比这些算法更快。插入排序是一种稳定排序算法,因为在排序过程中不涉及跳跃式的交换,所以相等元素的相对位置不会改变。

直接插入排序实现思想:

  当插入第i(i>=1)个元素时,前面的array[0],array[1],…,array[i-1]已经排好序,此时用array[i]的排序码与array[i-1],array[i-2],…的排序码顺序进行比较,找到插入位置即将array[i]插入,原来位置上的元素顺序后移。

【数据结构】常见排序算法——常见排序介绍、插入排序、直接插入排序、希尔排序


直接插入排序的实现:

  具体来说,这个函数的作用是对传入的数组a进行排序,数组中有n个元素。首先在外层循环中,从数组的第二个元素(索引为1)开始遍历,将其作为当前待排序的元素tmp,同时记录一个end指针指向当前已排序的最后一个元素所在的位置。

  在内层循环中,我们将tmp与end所指向的元素比较,如果tmp小于end所指向的元素,则将end所指向的元素后移一位,并向前移动end指针,继续在区间[0, end]中进行比较,直到找到tmp应该插入的位置。

  最后,将tmp插入到正确的位置,该插入位置为end + 1。

  这样,经过n-1次外层循环的排序操作后,数组a中的元素就按升序排列了。

void InsertSort(int* a, int n)
{
	for (int i = 1; i < n; i++)
	{
		int end=i-1;
		int tmp=a[i];
		//将tmp插入到[0,end]区间中,保持有序
		while (end >= 0)
		{
			if (tmp < a[end])
			{
				a[end + 1] = a[end];
				end--;
			}
			else
			{
				break;
			}
		}
		a[end + 1] = tmp;
	}
}

直接插入排序的特性总结:

(1)元素集合越接近有序,直接插入排序算法的时间效率越高;

(2)时间复杂度:O(N^2);

(3)空间复杂度:O(1),它是一种稳定的排序算法;

(4)稳定性:稳定。

2.1.2希尔排序

  希尔排序(Shell Sort)是插入排序的一种变体,是一种针对插入排序进行优化的算法,也被称为“缩小增量排序”。希尔排序的基本思想是对待排序的序列进行分组,对于每个子序列应用直接插入排序算法进行排序,逐渐扩大分组的范围,同时逐步缩小增量,直到分组大小为1,完成排序。

  希尔排序通过先排序间隔较长的子序列,使得整个序列中的数据基本有序,这样在排序较短的子序列时就可以节省大量时间,从而提高整个排序的效率。希尔排序有许多种不同的递增序列选择方法,不同的算法实现之间可利用不同的增量序列。

  希尔排序的时间复杂度与其所选用的增量序列有关,最差情况下为O(n2)平均情况下为O(n1.3)左右。希尔排序属于不稳定排序,因为在大间隔排序时元素的相对位置可能会发生变化。

希尔排序法实现思想:

  先选定一个整数,把待排序文件中所有记录分成个组,所有距离为的记录分在同一组内,并对每一组内的记录进行排序。然后,取,重复上述分组和排序的工作。当到达=1时,所有记录在统一组内排好序。

【数据结构】常见排序算法——常见排序介绍、插入排序、直接插入排序、希尔排序

希尔排序的实现:

  希尔排序的思想是先取一个间隔gap,将数组a分为若干个长度为gap的子序列,分别对这些子序列进行直接插入排序。然后逐渐缩小gap的值,重复以上操作,直至gap=1时,整个数组排序完成。

  代码中使用的增量序列是gap = gap / 3 + 1,也可选择其他增量序列,每次都将gap值缩小,直至其为1时排序结束。对于每个子序列,通过直接插入排序进行排序,不同之处是直接插入排序是对相邻的元素进行插入操作,而希尔排序的插入操作是对相距gap的元素进行插入。

  具体来看,对于每个间隔为gap的子序列,我们初始化end为i,记录待插入的元素tmp=a[i+gap],然后将tmp进行插入操作,找到合适的位置,使得end所在位置及之后的元素都向后移动gap个位置。插入排序的结束位置为0,整个操作过程和直接插入排序是类似的。

综上,希尔排序是通过先分组排序后逐步缩小元素间距,以达到提高排序效率的一种排序算法。

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

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

  我们可以简化上面的代码,使其减少一个循环,但复杂度不变:

  这段代码是标准的希尔排序的实现。它接受两个参数:一个整型数组a和数组的长度n。其中,数组a是待排序的对象,n表示数组a的元素个数。

  标准的希尔排序是将待排序的序列分成若干个子序列,对每个子序列进行插入排序,随后逐渐缩小子序列的长度,直到整个序列排序完成。关键点在于使用不同的增量gap来划分子序列,不同的增量选择方式会影响算法的时间复杂度。

  在该代码中,希尔排序的增量序列选择的策略是gap = n/2, n/4, n/8, … 直到gap=1。每次缩小增量gap之后,对每个子序列都进行一次插入排序。这样可以使得每个元素都能够尽可能快地移动到自己的正确位置上,以达到加速排序的目的。

  具体来看,每次对一个增量gap的子序列进行直接插入排序,我们选取增量gap之后,通过循环将整个数组分成了gap组。对于每个子序列,通过直接插入排序算法进行排序,在一次希尔排序中,相同的元素可能在多个子序列进行比较和赋值操作。

  通过多次迭代,不断缩小增量gap,在进行若干次间隔大的直接插入排序之后,我们最后得到的是一次增量为1的直接插入排序,此时整个序列的排序完成。

综上,标准的希尔排序算法是一种高效的排序算法,其时间复杂度和其所采用的增量序列有关,最优的情况下是O(n*log(n)),最差情况下是O(n^2)。

void ShellSort(int* a, int n)
{
	// gap > 1 预排序
	// gap == 1 直接插入排序
	int gap = n;
	while (gap > 1)
	{
		//gap /= 2;
		gap = gap / 3 + 1;

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

希尔排序的特性总结:

(1)希尔排序是对直接插入排序的优化。

(2)当gap > 1时都是预排序,目的是让数组更接近于有序。 当gap == 1时,数组已经接近有序的了,这样就会很快。这样整体而言,可以达到优化的效果。我们实现后可以进行性能测试的对比。

(3)希尔排序的时间复杂度不好计算, 因为gap的取值方法很多,导致很难去计算,因此在好些树中给出的希尔排序的时间复杂度都不固定。

(4)稳定性:不稳定。

 《数据结构(C语言版)》— 严蔚敏
【数据结构】常见排序算法——常见排序介绍、插入排序、直接插入排序、希尔排序

这些就是数据结构中有关直接插入排序和希尔排序的简单介绍了😉
如有错误❌望指正,最后祝大家学习进步✊天天开心✨🎉文章来源地址https://www.toymoban.com/news/detail-475971.html

到了这里,关于【数据结构】常见排序算法——常见排序介绍、插入排序、直接插入排序、希尔排序的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 算法 数据结构 递归插入排序 java插入排序 递归求解插入排序算法 如何用递归写插入排序 插入排序动图 插入排序优化 数据结构(十)

    1. 插入排序(insertion-sort):                                           是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入     算法稳定性:                  

    2024年02月09日
    浏览(56)
  • 数据结构——C语言实现常见排序(插入排序、希尔排序、选择排序、堆排序、冒泡排序)

    现在是北京时间2023年6月23日13点19分,度过了一个非常愉快的端午节。由于刚从学校回家,一下子伙食强度直升了个两三个档次。这也导致我的肠胃不堪重负,我也准备等会去健身房消耗一下盈余的热量。回到家陪伴爷爷走人生最后的阶段才是我这个暑假最重要的事情。自从

    2024年02月10日
    浏览(52)
  • 数据结构算法-插入排序

    一、概念及其介绍 插入排序(InsertionSort),一般也被称为直接插入排序。 对于少量元素的排序,它是一个有效的算法。插入排序是一种最简单的排序方法,它的基本思想是将一个记录插入到已经排好序的有序表中,从而一个新的、记录数增 1 的有序表 。在其实现过程使用双层

    2024年02月21日
    浏览(46)
  • 【数据结构与算法】十大经典排序算法-插入排序

    🌟 个人博客: www.hellocode.top 🏰 Java知识导航: Java-Navigate 🔥 CSDN: HelloCode. 🌞 知乎 :HelloCode 🌴 掘金 :HelloCode ⚡如有问题,欢迎指正,一起学习~~ 插入排序(Insertion Sort)是一种简单直观的排序算法,其基本思想是将一个记录插入到已排好序的有序序列中,直到所有记录

    2024年02月13日
    浏览(82)
  • 数据结构算法练习 插入排序 冒泡排序

    插入排序 代码如下  package main import \\\"fmt\\\" func main() {     a := []int{4, 5, 6, 1, 3, 2}         b := insert(a)     for i := 0; i len(b); i++ {         fmt.Println(b[i])     } } func insert(a []int) []int {     if len(a) = 1 {                   如果数组长度小于等于1 不用排序直接返回          retur

    2024年02月08日
    浏览(57)
  • 数据结构与算法:插入排序&希尔排序

    假设现在你有一个有序的数组,你要把一个数据插入到数组中,保证插入后依然有序,要怎么做? 对于人来说,这个问题就像是在整理扑克牌,瞄一眼就知道应该插入什么位置。但是对于程序来说,就需要一一对比,直到找到一个位置 左边比它大,右边比它小 ,就算找到了

    2024年01月17日
    浏览(57)
  • 数据结构与算法—插入排序&选择排序

    目录 一、排序的概念 二、插入排序   1、直接插入排序  特性总结: 2、希尔排序 特性总结:  三、选择排序 1、直接选择排序  特性总结: 2、堆排序—排升序(建大堆) 向下调整函数 堆排序函数 特性总结: 代码完整版:   头文件  函数文件  测试文件 排序 :所谓排序,

    2024年01月20日
    浏览(62)
  • 数据结构算法--2 冒泡排序,选择排序,插入排序

    思想就是将相邻元素两两比较,当一个元素大于右侧相邻元素时,交换他们的位置,小于右侧元素时,位置不变,最终序列中的最大元素,像气泡一样,到了最右侧。 这时冒泡排序第一轮结束,数列最右侧元素9的位置可认为是一个有序区,有序区目前有一个元素. 第二轮排序

    2024年02月13日
    浏览(64)
  • 【数据结构与算法】排序算法(选择排序,冒泡排序,插入排序,希尔排序)

    基本概念这了就不浪费时间解释了,这四种都是很简单的排序方式,本专栏后续文章会出归并排序,计数排序,快速排序,堆排序,桶排序等排序算法,今天这篇文章中给出选择排序,冒泡排序,插入排序和希尔排序的实现; 如果发现文章中有错误,还请大家指出来,我会非

    2024年02月15日
    浏览(84)
  • 【数据结构与算法】:插入排序与希尔排序

    🔥 个人主页 : Quitecoder 🔥 专栏 : 数据结构与算法 欢迎大家来到初阶数据结构的最后一小节:排序 排序是一种将一组对象按照某种特定顺序重新排列的过程。在计算机科学中,排序是数据处理中非常基本且重要的操作,它可以帮助人们更有效地理解和分析数据。排序的顺序

    2024年03月18日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包