希尔排序python 简书_排序算法 --- 希尔排序

一、排序思想

之前说到插入排序,希尔排序就对其进行了一个优化,优化的思路是:

对待排序列进行分组,组数为gap = arr.length / 2;

对每一组进行插入排序,然后再进行分组,gap = gap / 2;

再对每一组进行插入排序,直到最后组数为1,再进行最后一次插入排序即可;

欢迎大家关注我的公众号 javawebkf,目前正在慢慢地将简书文章搬到公众号,以后简书和公众号文章将同步更新,且简书上的付费文章在公众号上将免费。

案例:

假如有待排序列如下:

8 9 1 7 2 3 5 4 6 0

总共10个数,gap = 10 / 2 = 5,分成5组,并且不是两两相邻的为一组,arr[0]和arr[0 + gap]为一组,arr[1]和arr[1 + gap]为一组……第一次分组后的结果如下(数字后面带的符号相同的为同一组):

8* 9$ 1@ 7^ 2& 3* 5$ 4@ 6^ 0&

对这五组都进行插入排序,结果就是:

3* 5$ 1@ 6^ 0& 8* 9$ 4@ 7^ 2&

对上面的序列再进行分组,gap = gap / 2 = 5 / 2 = 2,再分成两组,arr[0]和arr[0+2]、arr[0+2+2]……为一组,分组结果就是:

3* 5$ 1* 6$ 0* 8$ 9* 4$ 7* 2$

对这两组分别进行插入排序,结果就是:

0* 2$ 1* 4$ 3* 5$ 7* 6$ 8* 9$

此时,gap = gap / 2 = 2 / 2 = 1,组数为1,所以不用分了,对这一组再进行插入排序,那么整个排序过程就完了。

二、代码实现

关于希尔的代码实现,网上很多花里胡哨的答案,什么交换法位移法之类的,其实不要想得那么复杂。刚才说了,希尔排序的主要思想就是分组,对每一组分别进行插入排序,那代码就简单了,就是这分组里面将之前插入排序的代码拷过来稍微改改就行了。分组的代码就是:

for(int gap = arr.length / 2; gap > 0; gap /= 2) {

……

}

这个for循环里面就直接把之前插入排序的代码粘过来,稍微改改就行,以前插入排序的代码是这样的:

for(int i=1; i

int insertVal = arr[i]; // 待排元素

int insertIndex = i - 1; // 从有序表最后一个元素开始比较

while (insertIndex >= 0 && insertVal < arr[insertIndex]) { // 如果还没有将有序表比较完 && 待排元素还没找到位置

arr[insertIndex + 1] = arr[insertIndex]; // 比待排元素大的元素后移一位

insertIndex --; // 继续往前比较

}

// 找到位置后,其他元素都后移了,自己占坑

if (insertIndex + 1 != i) {

arr[insertIndex + 1] = insertVal;

}

}

怎么改呢?聪明的你肯定发现了,以前只有一组,每次比较的时候,步长是1,现在步长是gap,所以,只要将以前插入排序循环中的1都改成gap就行了,完整代码如下:

public static void mySort(int[] arr) {

if (arr == null || arr.length == 1) {

return;

}

for(int gap = arr.length / 2; gap > 0; gap /= 2) {

for(int i=gap; i

int insertVal = arr[i];

int insertIndex = i-gap;

while (insertIndex >=0 && insertVal < arr[insertIndex]) {

arr[insertIndex + gap] = arr[insertIndex];

insertIndex -= gap;

}

if ((insertIndex + gap) != i) {

arr[insertIndex + gap] = insertVal;

}

}

}

}

怎么样,这样理解起来是不是简单多了?学废了吗

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值