10.2.3 希尔排序

相关概念

  • 希尔排序,又叫做 缩小增量排序

  • 希尔排序的基本思想
    每一趟将 整个待排序记录 分成 若干子序列 ,在 每个子序列 内进行 直接插入排序 ,使 每个子序列内有序 。若干趟后,对 整个记录序列 进行 直接插入排序
    对待排记录先做 宏观调整 ,再做 微观调整
    比较过程使用的 间隔dk ,由大变小,即是 宏观到微观的过程

  • 宏观调整
    指的是>跳跃式</font的插入排序。
    具体做法 :将 整个记录序列 分成若干 子序列 ,分别对 每个子序列 进行 插入排序

  • 希尔排序的优越性
    省的让 关键字特别小的记录 只能一个单位一个单位的前移(希尔排序中可以一步跨若干个单位)。
    增量逐渐减小(从宏观到微观),直到1。
    如 选择 增量为5,3,1 ... 比较完成。每一趟里面仍然是 插入排序 ,只是 比较间隔 为 dk。
    d=1 时进行比较移动,此时的 记录序列 已经很接近于 非递增序了,要移动的次数 很少。
    为什么希尔排序完虐直接插入排序

  • 增量序列可以有多种取法,但一定要确保 增量序列中的值 没有除 1 以外的 公因子 ,并且 序列的最后一个值 为 1。

算法

// 一趟希尔排序算法,dk是本轮希尔排序所选用的增量
// 也可以看作直接插入排序的查找算法,只是间隔为 dk。
void ShellInsert(SqList &L, int dk)
{
	for(i=dk+1; i<=L.length; i++)
	{
		if(L.r[i].key < L.r[i-dk].key)
		{
			L.r[0] = L.r[i]; // 暂存
			for(j = i-dk;
				j>0 && L.r[0].key<L.r[j].key;
				j -= dk)
			{
				// 记录跳跃式移动
				L.r[j+dk] = L.r[j];
			}
			L.r[j+dk] = L.r[0];
		}
	}
}
// 希尔排序
void ShellSort(SqList &L, int dlta[], int t)
{
	// 按增量序列 dlta[0 .. t-1]做希尔排序
	for(k=0; k<t; k++)
	{
		ShellInsert(L, dlta[k]);
	}
}

性能分析(,希尔排序)

  • 直接插入排序,折半插入排序,表插入排序的 时间复杂度 是 O(n2)。
    折半插入排序法中的 比较操作的时间复杂度 是O(nlogn)

  • 希尔排序的时间复杂度 比 n2 要小。
    但想要具体分析出希尔排序的时间复杂度十分困难,因为其是 所取增量序列 的函数。
    在大量的实验基础上可以得到:当 n 在某个特定范围内,希尔排序所需的比较和移动的次数约为 n1.3 ,当 n -> ∞ 时,可以减少到 n(log2n)2

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值