算法与数据结构 Shell排序算法

  1. Shell排序算法

1959年Shell发明,第一个突破O(n^2)的排序算法,是简单插入排序的改进版。它与插入排序的不同之处在于,它会优先比较距离较远的元素。希尔排序又叫缩小增量排序。
Shell排序算法的排序流程如下:
(1)将有n个元素的数组分成n/2个数字序列,第一个数据和第n/2+1个为一对,……
(2) 一次循环使每一个序列对排好顺序
(3)然后,再变成n/4个序列,再次排序
(4)不断重复以上步骤,随着序列减少为最后一个,完成排序。
下面举一个实例来执行插入排序算法:
在这里插入图片描述
5个整型数据118,101,105,127,112,这是一组无序数据。对其执行Shell排序过程,步骤如下:
(1)第1次排序,首先将数组分为6/2=3个数字序列,第1个数据127和第4个数据101为一对,第2个数据118和第5个数据112为一对,第3个数据105和第6个数据100为一对。每一对数据进行排序后的数据为101、112、 100、 127、118、105。

(2)第2次排序,将数组分为6/4=1个序列(这里执行取整操作),此时逐个对数据比较,按照插入排序算法对该序列进行排序。排序后的数据为100、101、 105、 112、118、127。

从上面的例子可以非常直观地了解到Shell排序算法的执行过程。插入排序时,如果原数据已经是基本有序的,则排序的效率就可大大提高。另外,对于数量较小的序列使用直接插入排序,因需要移动的数据量较少,其效率也较高。因此,Shell 排序算法具有比较高的执行效率。

  1. 实例代码运行:
 public static void main(String[] args) {
        int[] a = {2,3,9,7,6,5,1,8,4,0};
        shellsort(a);
        System.out.println("最终排序结果:" + Arrays.toString(a));
    }

    private static void shellsort(int[] a) {
        int n = 0;
        int j = 0;
        int e = 0;
        for (int gap = a.length / 2;gap > 0;gap /= 2) {//首先将其分组
            for(int i = gap; i < a.length;i++) {
                j = 0;
                e = a[i];
               for ( j = i;j - gap >= 0 && a[j - gap] > e;j = j - gap) {
                    a[j] = a[j - gap];
                   n++;
                   System.out.println("第"+n+"步排序结果:"+Arrays.toString(a));
                }
                a[j] = e;
            }
        }
    }

运行结果
第1步排序结果:[2, 3, 9, 7, 6, 5, 3, 8, 4, 0]2步排序结果:[2, 1, 9, 7, 6, 5, 3, 9, 4, 0]3步排序结果:[2, 1, 8, 7, 6, 5, 3, 9, 7, 0]4步排序结果:[2, 1, 8, 4, 6, 5, 3, 9, 7, 6]5步排序结果:[2, 1, 8, 4, 8, 5, 3, 9, 7, 6]6步排序结果:[2, 1, 2, 4, 8, 5, 3, 9, 7, 6]7步排序结果:[0, 1, 2, 4, 8, 5, 8, 9, 7, 6]8步排序结果:[0, 1, 2, 4, 3, 5, 8, 9, 8, 6]9步排序结果:[0, 1, 2, 4, 3, 5, 7, 9, 8, 9]10步排序结果:[0, 1, 2, 3, 4, 5, 7, 6, 8, 9]11步排序结果:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
最终排序结果:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值