希尔排序

【0】README

0.1) 本文总结于 数据结构与算法分析,但源代码均为原创;旨在理清希尔排序的具体步骤;


【1】希尔排序相关

1.1)希尔排序(shellsort)的由来: 它的名称源于它的发明者 Donald Shell, 该算法是冲破二次时间屏障的第一批算法之一;
1.2)工作原理:它通过比较相距一定间隔的元素来工作, 各趟比较所用的距离随着算法的进行而减小,直到只比较相邻元素的最后一趟排序为止, 由于这个原因, 希尔排序有时也叫做 缩小增量排序;
1.3)增量序列:希尔排序使用一个序列 h1、h2、……、ht, 叫做增量序列; 只要h1=1 , 任何增量都是可行的;重点是, 有些增量序列比另外一些增量序列更好;
1.4)在使用增量hk 的一趟排序后,对于每一个 i , 我们有A[i] <= A[i+hk]; 所以相隔 增量hk 的元素都被排序, 此时称文件是 hk-排序的;
1.5)hk-排序的一般做法是(用到了插入排序): 对于 hk, hk+1, hk+2,……,N-1中的每一个位置i, 把其上的元素放到 i,i-hk, i-2hk…..中间的正确位置上;虽然这不是最终结果,但是结果考察,我们发现,一趟hk-排序的作用就是对 hk个独立的 子数组执行一次插入排序


【2】增量序列的选择建议:

2.0)希尔增量的问题在于: 这些增量对 未必互为素数, 因此较小的增量可能影响很小;
2.1)推荐(本源代码也使用的这种增量序列): Hibbard 提出一个稍微不同的增量序列, 它在实践中给出更好的结果, 增量形如1, 3, 7, ……, 2^k - 1(如, N=15, 则 int k=log15 = 3, 2, 1 也即增量序列 7, 3, 1);
2.2)希尔增量序列的选择: 其余的增量序列还有Hibbard:{1, 3, …, 2^k-1},Sedgewick(推荐):{1, 5, 19, 41, 109…}该序列中的项或者是9*4^i - 9*2^i + 1或者是 4^i - 3*2^i + 1。使用不同的增量对希尔排序的时间复杂度的改进将不一样,甚至一点小的改变都将引起算法性能剧烈的改 变。(在实践中: 堆排序慢于 使用 Sedgewick 增量序列的希尔排序;)
2.3)增量序列的一种流行(但是不好)的选择是使用 shell 建议的序列:这里写图片描述
定理: 使用 Hibbard 增量的希尔排序的最坏情况运行时间为 这里写图片描述
2.4)希尔排序的具体步骤(步骤):
这里写图片描述


【3】源代码+打印结果

3.1)download source code :
https://github.com/pacosonTang/dataStructure-algorithmAnalysis/blob/master/chapter7/p168_shellSort.c
3.2)source code at a glance :

#include <stdio.h>
#include <math.h>


// 计算 log 以2为底的对数
double log2(double input)
{   
    return log(input) / log(2); 
}

// we adopt ascending order to execute shellSorting operation
void shellSort(int data[], int size)
{
    int temp;
    int round;
    int index;
    int i;
    int offset;

    round = (int)log2(size);    

    for(; round > 0;) 
    {
        offset = (int)pow(2, round) - 1; // assignment of offset, like 7, 3, 1      
        for(i = offset; i < size; i++) // i like 7, 8, 9, ...., size-1 
        {                   
            temp = data[i];// the idea refers to the insertion sort             
            for(index = i; index >= offset; index -= offset)                    
                if(temp < data[index - offset])             
                    data[index] = data[index - offset];
                else
                    break;          
            data[index] = temp;
        }
        round --;
    }
}

void printArray(int data[], int size)
{
    int i;

    for(i = 0; i < size; i++)
        printf("%5d", data[i]);

    printf("\n");
}

int main()
{ 
    int size;
    int data[] = {100, 1000, 100, 10, 6, 2, 19, 25, 15, 55, 35, 5, 110, 120, 119};

    size = 15;

    printf("\n=== before executing shellSort ===\n");
    printArray(data, size);
    shellSort(data, size);
    printf("\n=== after executing shellSort ===\n");
    printArray(data, size); 




    return 0;
}

3.3)打印结果:
这里写图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值