数据结构第四天(希尔排序)

目录

前言

概述

源码:

主函数: 

运行结果:


前言

今天是插入排序的最后一个了,希尔排序。

哈哈,这可不意味着数据结构结束了,明天将开启新的篇章:交换排序。

学习算法的过程,并不总是坦坦大路,只要友友们喜欢,喵喵我呀,一定会分享每天所得,每天的点点滴滴,以及喵喵与代码的情仇恩怨。

概述

利用(http://数据结构第一天(生成1000以内的随机数自动填充数组)中的代码自动生成五个随机整数,并自动储存在数组中:

其实,直接插入排序的效率在某些时候是很高的,比如, 我们的记录本身就是基本有序的,我仍只需要少量的插入操作,就可以完成整个记录 集的排序工作,此时直接插入很高效。还有就是记录数比较少时,直接插入的优势也 比较明显。可问题在于,两个条件本身就过于苛刻,现实中记录少或者基本有序都属 于特殊情况 。

有条件当然是好,条件不存在,我们创造条件也是可以去做的。

我们可以想到,将原本有大量记录数的记录 进行分组。分割成若干个子序列,此时每个子序列待排序的记录个数就比较少了,然 后在这些子序列内分别进行直接插入排序,当整个序列都基本有序时,注意只是基本 有序时,再对全体记录进行一次直接插入排序。

因此,我们可以采取跳跃分割的策略 :将相距某个‘增量'的记录组成 个子 序列,这样就能保证在子序列内分别进行直接插入排序后得到的结果是基本有序的。

需要补充说明的是:这个增量必须是互质的,比如增量选择为7,5,3,1这样的一系列分组,同时,最后一个增量必须为1;这一系列增量我们可以通过2^{k}-1来获取。

下面就以增量为3,1举例:

增量为3时,1和4为一组,2 和5为一组, 排序结果:

经过上一轮分组排序之后,基本变成有序的了 ,最后增量为1分组,数组中所有元素都会参加排序:

最终排序结果如下: 

源码:

void sort(int* dest, const unsigned int dataCnt, int interval)
{
	int minNum = *dest;
	int circleTime = 0;
	(dataCnt%interval > 0) ? circleTime = dataCnt / interval + 1 : circleTime = dataCnt / interval;
	
	for (int k = 0; k <= interval; ++k)
	{
		for (int i = 0; i < circleTime; ++i)
		{

			for (int j = 0; j <circleTime; ++j)
			{

				if (*(dest + k + (j + 1)*interval)<*(dest + k + j*interval) && (j + 1)*interval + k+1<= dataCnt)
				{
					swap(*(dest + k + (j + 1)*interval), *(dest + k + j*interval));
				}
			}

		}

	}
}
void sortByShellInsert(int* dest, const unsigned int dataCnt, const unsigned int circleTime )
{
	
	for (int i = circleTime; i > 0; --i)
	{
		int interval = pow(2, i) - 1;
		sort(dest, dataCnt, interval);
	}
	
}

主函数: 

int main()
{

    int array[16] = { 0 };
    numberProducer.getFilledArray(array,16);
    cout << "  原 始 数 据   :";
    numberProducer.showArray(array,16);

    sortByShellInsert(array, 16, 5);
    cout << "希尔插入排序后  :";
    numberProducer.showArray(array, 16);

    sortByBinarySearchInsert(array, 16);
    cout << "折半插入排序后  :";
    numberProducer.showArray(array, 16);

    sortByDirectInsert(array, 16);
    cout << "直接插入排序后  :";
    numberProducer.showArray(array, 16);
    system("pause");
    return 0;
}

运行结果:

  • 22
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值