2、希尔排序

 希尔排序又称缩小增量法,是对直接插入排序的优化。

思路

思想:先去一合适任意值gap(至少大于1小于数组大小),先取下标为0的数,然后跳过gap个数,取其位置的数,再跳过gap个数...直到gap跳出整个数组后,这几个数为一组,之后取下标为1的数,跳过gap个数,取其位置的数...直到首取为止的下标为gap止,分为多个组合,对这几个 组合分为进行插入排序,这个过程称为预排序,达到接近有序的顺序,之后缩减gap数值重复操作,直到gap==1时,完成排序。

 第一次排完后:

 之后缩减gap的值再次分组(gap=2)

 第二次排完后:

 第三次gap=1,最后一次排序,整个数组为一组

 排完后为

简单来说:1、取gap分组

                  2、分组

                  3、分别对每个组中的数进行排序

                  4、缩小gap的值重新分组排序直到gap==1

代码

 首先写出两个“相邻”数的比较以及插入

                //和直接插入法类似
                int end = i;
				int tmp = a[end + gap];
				while (end >= 0)					
				{
					if (a[end] > tmp)
					{
						a[end + gap] = a[end];    //分组后每组相邻的数在整个数组下标差为gap
						end -= gap;
					}
					else
						break;
				}
				a[end + gap] = tmp;

之后在外围添加循环来实现每一gap组中所有数的比较插入

            for (int i = j; i < n - gap; i += gap)   //每组的排序
			{
				int end = i;
				int tmp = a[end + gap];
				while (end >= 0)			
				{
					if (a[end] > tmp)
					{
						a[end + gap] = a[end];      //分组后每组相邻的数在整个数组下标差为gap
						end -= gap;
					}
					else
						break;
				}
				a[end + gap] = tmp;
            }

实现每组插入后,再通过循序实现所有组合的插入排序

        for (int j = 0; j < gap; j++)				 //有gap组
		{
			for (int i = j; i < n - gap; i += gap)   //每组的排序
			{
				int end = i;
				int tmp = a[end + gap];
				while (end >= 0)							
				{
					if (a[end] > tmp)
					{
						a[end + gap] = a[end];       //分组后每组相邻的数在整个数组下标差为gap
						end -= gap;
					}
					else
						break;
				}
				a[end + gap] = tmp;
			}
		}

 实现了一次gap的组合,最后再通过循环实现所有gap缩小的排序

void ShellSort(int* a, int n)
{
	int gap = n;
	while (gap > 1) 
    {                                //缩小gap重新分组排序直到gap==1
		gap = gap / 3 + 1;
	    
		for (int j = 0; j < gap; j++)				//有gap组
		{
			for (int i = j; i < n - gap; i += gap)	//每组的排序
			{
				int end = i;
				int tmp = a[end + gap];
				while (end >= 0)								
				{
					if (a[end] > tmp)
					{
						a[end + gap] = a[end];      //分组后每组相邻的数在整个数组下标差为gap
						end -= gap;
					}
					else
						break;
				}
				a[end + gap] = tmp;
			}
		}
	}
}

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

空间复杂度:O(1) 

稳定性:不稳定

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值