经典排序之希尔排序

文章介绍了直接插入排序的基本思想、算法描述和C语言实现,指出其在最好情况下的时间复杂度为O(n)。接着,文章详细解释了希尔排序如何通过预排序优化直接插入排序,通过设置间隔gap进行多步排序,最终达到O(n*log2n)的时间复杂度。希尔排序的C语言代码也一并给出。
摘要由CSDN通过智能技术生成

         希尔排序和直接插入排序都属于插入排序,希尔排序是对直接插入排序的优化,如果想要理解希尔排序首先要理解直接插入排序是如何进行排序的,下面我们先实现直接插入排序。

        直接插入排序思想

        直接插入排序思想是将待排序元素插入一段有序数列,在生活中这种思想比较常见,也许你没有注意,当你在玩扑克牌抓牌时,每有一张牌拿到手里都要插入到已经有序的牌里,这便是直接插入牌序的思想。从第一张扑克牌开始(一张牌时是有序的),逐个插入到手牌里

        算法描述

        1.取出第一个元素,只有一个元素当然被认为是有序的。

        2.取出下一个元素,插入到序列中,如果待插入元素小于序列中的被插入元素,该被插入元素移动至下一位置。直到该待插入元素大于被插入的元素或者前面已经没有元素时停止,该待插入元素插入到该位置后,此时完成一个元素的插入。

       3.重复步骤二,直至所有元素插入完成。

      C语言代码实现直接插入排序

void InsertSort(int* a, int size) {
	assert(a);
	int end;
	int x;
	for (int i = 0; i < size-1; i++) {
		end = i;
		x = a[end + 1];
		while (end >= 0) {
			if (a[end] > x) {
				a[end + 1] = a[end];
				end--;
			}
			else {
				break;
			}
		}
		a[end + 1] = x;
	}
}

       算法分析

       我们来分析一下该算法的时间复杂度,最坏情况下当然是每次插入时插入到该序列的第一个位置,一趟排序的时间复杂度为O(n),完成排序的时间复杂度为O(n^2);那么最好的情况下的时间复杂度是多少呢?当待排序序列有序时或接近有序时,我们只需要将待插入元素插入到该序列之后,而不必遍历前面的序列,此时排序的时间复杂度为O(n)。总结:直接插入排序的时间复杂度为O(n^2),但在排序有序或接近有序的序列时时间复杂度会更小。

     

        直接插入排序如何优化

        希尔排序是对直接插入排序的优化,那么希尔是怎样对直接插入排序进行优化的呢?前面我们已经总结了直接插入排序的算法分析,知道了直接插入排序在对有序或接近有序的序列进行排序时效率十分高。那么有没有方法现将序列进行处理使得其接近有序呢?这便是希尔排序中预排序的处理。

      希尔排序算法思想

        将序列以gap为间隔进行分组,所有间隔相同的为一组,分为N/gap组。然后分别对每组进行直接插入排序。

                  

        当gap等于3时 ,序列被分成9/3=3组,然后对每组元素进行插入排序,得到的序列为{2,1,3,5,4,6,8,9,7},这样就得到了一个相较原序列更有序的序列。我们会发现当gap==1时每组间隔为1,序列被分为了N组元素(N为待排序序列元素个数),此时就是直接插入排序。如果我们一开始选择gap=length/2,然后缩小gap=gap/2,我们对序列进行多次预排序,最后当gap==1时进行直接插入排序,完成最后的排序。

        C语言代码实现希尔排序 

void ShellSort(int* a, int size) {
    //设置排序间隔
	int grap = size ;
	while (grap > 1) {
        //每次预排序间隔,当garp==1时进行直接插入排序
		grap /= 2;
		for (int i = 0; i < size - grap; i++) {
			int end = i;
			int x = a[end + grap];
			while (end >= 0) {
				if (a[end] > x) {
					a[end + grap] = a[end];
					end -= grap;
				}
				else {
					break;
				}
			}
			a[end + grap] = x;
		}
	}
}

        算法分析

        我们可以看到希尔排序与直接插入排序的代码是十分相似的,希尔排序在直接插入排序的思想上增加了预排序,通过gap/=2控制每次循环的增量gap对序列进行预排(这是希尔的划分,业界一般通过gap=gap/3+1来划分),当gap==1时进行对接近有序序列进行排序。希尔排序时被分为log2n个增量gap,每个增量的排序的时间复杂度大致为O(n)。大致算出希尔排序的时间复杂度为T(n)=O(n*log2n)。

        

        

        

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值