zoukankan      html  css  js  c++  java
  • 经典排序算法 希尔排序Shell sort

    经典排序算法 - 希尔排序Shell sort

    希尔排序Shell Sort是基于插入排序的一种改进,同样分成两部分,

    第一部分,希尔排序介绍

    第二部分,如何选取关键字,选取关键字是希尔排序的关键

    第一块希尔排序介绍

    准备待排数组[6 2 4 1 5 9]

    首先需要选取关键字,例如关键是3和1(第一步分成三组,第二步分成一组),那么待排数组分成了以下三个虚拟组:

    [6 1]一组

    [2 5]二组

    [4 9]三组

    看仔细啊,不是临近的两个数字分组,而是3(分成了三组)的倍数的数字分成了一组,

    就是每隔3个数取一个,每隔三个再取一个,这样取出来的数字放到一组,

    把它们当成一组,但不实际分组,只是当成一组来看,所以上边的"组"实际上并不存在,只是为了说明分组关系

    对以上三组分别进行插入排序变成下边这样

    [1 6] [2 5] [4 9]

    具体过程:

    [6 1]6和1交换变成[1 6]

    [2 5]2与5不动还是[2 5]

    [4 9]4与9不动还是[4 9]

    第一趟排序状态演示:

    待排数组:[6 2 4 1 5 9]

    排后数组:[1 2 4 6 5 9]

    第二趟关键字取的是1,即每隔一个取一个组成新数组,实际上就是只有一组啦,隔一取一就全部取出来了嘛

    此时待排数组为:[1 2 4 6 5 9]

    直接对它进行插入排序

    还记得插入排序怎么排不?复习一下

    [1 2 4]都不用动,过程省略,到5的时候,将5取出,在前边的有序数组里找到适合它的位置插入,就是4后边,6前边

    后边的也不用改,所以排序完毕

    顺序输出结果:[1 2 4 5 6 9]

    第二块希尔排序的关键是如何取关键字,因为其它内容与插入排序一样

    那么如何选取关键字呢?就是分成三组,一组,这个分组的依据是什么呢?为什么不是二组,六组或者其它组嘞?

    好的增量序列的共同特征:

    ① 最后一个增量必须为1

    ② 应该尽量避免序列中的值(尤其是相邻的值)互为倍数的情况

    参见 http://baike.baidu.com/view/2217047.htm

    这么关键的问题竟然没有一个公式,只给出了两个判定标准

    好吧,一般10个待排数字的话,关键依次选取5 3 1即可,其它的情况只能自己判断了,然后看是否符合上述两条"好"的标准

    就是说,这个关键的选择是没有规定的,怎么选都可以,仅一条,关键字要越来越小,直到1为止

    后补:

    增量的取值规则为第一次取总长度的一半,第二次取一半的一半,依次累推直到1为止,刚从下文中看到的这一段描述,感谢!

    算法系列15天速成——第三天 七大经典排序【下】

    以下C#代码实现仅供参考

            static void shell_sort(int[] unsorted, int len)
            {
                int group, i, j, temp;
                for (group = len / 2; group > 0; group /= 2)
                {
                    for (i = group; i < len; i++)
                    {
                        for (j = i - group; j >= 0; j -= group)
                        {
                            if (unsorted[j] > unsorted[j + group])
                            {
                                temp = unsorted[j];
                                unsorted[j] = unsorted[j + group];
                                unsorted[j + group] = temp;
                            }
                        }
                    }
                }
            }
    
    
            static void Main(string[] args)
            {
                int[] x = { 6, 2, 4, 1, 5, 9 };
                shell_sort(x, x.Length);
                foreach (var item in x)
                {
                    Console.WriteLine(item);
                }
                Console.ReadLine();
            }

    返回主目录 [经典排序算法][集锦]



    ------------------------------------------
    除非特别声明,文章均为原创,版权与博客园共有,转载请保留出处
    BUY ME COFFEE
  • 相关阅读:
    C++中使用多线程
    hdu 4223 dp 求连续子序列的和的绝对值最小值
    hdu 1372 bfs 计算起点到终点的距离
    hdu 4217 线段树 依次取第几个最小值,求其sum
    心得
    hdu 1175 bfs 按要求进行搜索,是否能到达,抵消两个(相同)棋子
    hdu 4221 greed 注意范围 工作延期,使整个工作时间罚时最少的单个罚时最长的值
    hdu 2844 多重背包 多种硬币,每一种硬币有一点数量,看他能组成多少种钱
    uva LCDDisplay
    hdu 4218 模拟 根据一个圆点和半径画一个圆 注意半径要求
  • 原文地址:https://www.cnblogs.com/kkun/p/shell_sort.html
Copyright © 2011-2022 走看看