希尔排序

            int[] sort = new int[13] { 1, 4, 89, 34, 56, 40, 59, 60, 39, 1, 40, 90, 48 };  // 输入一个数组
            int h = 1;
            int length = sort.Length;
            while (h > length / 3)
            {
                h = 3 * h + 1;      // 1,4,13,40,121,364,1093,...
            }   // h的初始值根据数组元素多少而定
            while (h >= 1)  // 当h=1 时排序完成
            {
                for (int i = h; i < length; i++)  // 将间隔为h的元素排序
                {
                    for (int j = i; j >= h && sort[j] < sort[j - h]; j -= h) // 当满足这两个条件时交换 数值
                    {
                        int temp = sort[j];
                        sort[j] = sort[j - h];
                        sort[j - h] = temp;
                    }
                }
                h = h / 3;
            }
            for (int i = 0; i < sort.Length; i++)  // 输出
               {
                    Console.Write(sort[i] + " ");
               }

上面的代码采用的h序列为1/2(3^k-1)。
希尔排序的思想是使数组中任意间隔为h的元素都是有序的。这样的数组被称为h有序数组。如果h很大,我们就能将元素移动到很远的地方,为实现更小的h有序数组创造方便。
实现希尔排序的一种方法是对于每个h,用插入排序将h个子数组独立的排序。但因为子数组是独立的,更简单的方法是在h子数组中将每个元素交换到比他大的元素之前去,只需将插入排序的移动元素的距离由1改为h即可。

  备注:文字和代码有参考到书籍:算法 第四版(人民邮电出版社)
希尔排序 (162-163)

相对于最简单的选择排序,插入排序在解决具有某些规律的乱序数组排序时会更有优势,但由于插入排序只会交换相邻的元素,因此元素只能一点一点的从一端移到另一端。
Shell排序简单的改进了插入排序,交换不相邻的元素以对数组的局部进行排序,并最终用插入排序对局部有序的数组排序。

发表评论

电子邮件地址不会被公开。 必填项已用*标注