什么是希尔排序呢?
Posted 宁果果卡卡
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了什么是希尔排序呢?相关的知识,希望对你有一定的参考价值。
在了解希尔排序之前我们先来回忆一下,其实希尔排序也是一种插入排序,只不过对插入排序做了进一步的优化。
它是如何优化的呢?
在插入排序时我们是直接把无序数组的元素与有序数组中的元素挨个比较,再直接插入到适当位置,而我们的希尔排序是先按元素下标的增量(两个元素之间的跨度,初始增量为length/2)分成若干个小组,再对每个小组使用插入排序算法排序,排完序后放回原数组,然后增量在上一步的基础上减半,再按元素下标的增量进行分组,重复上述动作,当增量减至为1时,整个数列恰好被分成一个小组,再进行插入排序,算法结束。
说到这里我想一定有小伙伴感觉一头雾水,怎么感觉比插入排序更麻烦了呢?卡卡当初在学习时也是有这种疑问,其实并不是这样的,我们的希尔排序的整体思想是通过先分组再排序使整个数列趋向于一个有序数列,这使得后续的插入排序工作量减少,尤其是数列中元素个数较多的情况下,工作量会大大降低,速度也会有很大的提升。
莫慌!下面我们通过实例帮助小伙伴们更好的理解:
由上图我们可以得知数组的length=8,所以初始增量=length/2=4;
我们按增量对元素分成了4个小组,对每个小组用直接插入法进行排序再放回原数组为下一次分组做准备,以此类推,直到我们的数组变成了一个有序数列。
那它代码该如何实现呢?上代码!!!
import java.util.Arrays;
public class Xier {
public static void main(String[] args) {
int[] a = { 5, 4, 6, 7, 1, 8, 2, 3 };
array(a);
}
public static void array(int[] a) {
// 每一次分组的增量进行折半
for (int k = a.length / 2; k > 0; k = k / 2) {
// 从下标为k的元素开始然后与下标-k的元素进行比较
// 可以变相的认为分成k组,每组是length/k个元素
// 然后对每一组进行插入排序
for (int i = k; i < a.length; i++) {
// 定义临时变量
int insertvalue = a[i];
int index = i - k;
// 判断是否成立若不成立,进行下一次循环
while (index >= 0 && insertvalue < a[index]) {
a[index + k] = a[index]; // 后移
index = index - k;// 继续寻找以相同增量的前一个元素
}
// 退出循环时表明找到了要插入的位置
a[index + k] = insertvalue;
}
System.out.println(Arrays.toString(a));
}
}
}
运行结果为:
由代码我们可以发现希尔排序代码几乎是在插入排序的基础上做了一些小小的改动罢了。
下面我们把快速排序与希尔排序来对比一下:
从平均时间复杂度上来看我们的希尔排序可能要快一些,下面我们通过真实的测试来对比一下(还是一万个数字,这里只做对比,测试时间与电脑性能也有一定的关系):
通过对比发现,我们的插入排序用了3s左右,而我们的希尔排序却1s不到,已经是非常的快了。现在终于知道希尔排序的厉害了吧,但是,我们的希尔排序也有缺点那就是稳定性差。
好了关于希尔排序,卡卡今天就分享这么多了,感谢大家的阅读!!
点个在看或转发就是对卡卡最大的爱,嘻嘻!!
以上是关于什么是希尔排序呢?的主要内容,如果未能解决你的问题,请参考以下文章