首页
学习
活动
专区
圈层
工具
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Java常见排序算法详解——希尔排序

概念: 希尔排序通过将比较的全部元素分为几个区域来提升插入排序的性能。这样可以让一个元素可以一次性地朝最终位置前进一大步。...然后算法再取越来越小的步长进行排序,算法的最后一步就是普通的插入排序,但是到了这步,需排序的数据几乎是已排好的了(此时插入排序较快)。...希尔排序是基于插入排序的以下两点性质而提出改进方法的: 插入排序在对几乎已经排好序的数据操作时, 效率高, 即可以达到线性排序的效率 但插入排序一般来说是低效的, 因为插入排序每次只能将数据移动一位 原理...: 先取一个正整数 d1(d1 的倍数的记录看成一组,然后在各组内进行插入排序 然后取 d2(d2 < d1) 重复上述分组和排序操作;直到取...选择排序 直接插入排序 二分插入排序 希尔排序 堆排序 完整代码: Java和Kotlin代码我均放在了GitHub上,欢迎Star!

47600

插入排序和希尔排序(Java)

nums[j] = target; } } 希尔排序:观察插入排序发现如果数组已经有一定的排列了,那么插入排序性能会很高,例:0 2 3 4 1 排序,前面都是一次判断,不需要交换操作...希尔排序加入了步长,而不是一开始就从头进行插入排序,目的是将数组进行一定的排序,最后再用插入排序进行排序,性能比直接使用插入排序快 shellSort.png 实现代码: /** *...} } } 为了对比直接插入排序和希尔排序的区别,我加入了一个变量来计数挪位操作的次数 /** * 希尔排序 * * @param nums...System.out.print(i + " "); } System.out.println(); System.out.println("以步长4先进行希尔排序后排序的交换次数...:" + count[0]); 结果: 0 1 1 3 4 5 6 7 8 9 插入排序交换次数:21 0 1 1 3 4 5 6 7 8 9 以步长4先进行希尔排序后排序的交换次数:15

36120
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    排序算法之希尔排序-Java版

    希尔排序 1.1 希尔排序的基本介绍 1.2 希尔排序思想 1.3 希尔排序的时间复杂度和空间复杂度等 2. 代码演示 1....希尔排序 1.1 希尔排序的基本介绍 希尔排序是加强版的插入排序,相对与普通的插入排序做了优化,比普通的插入排序多了一个步长的概念 1.2 希尔排序思想 就是把数据下标按照一定的步长进行分组,然后每组分别用普通插入排序进行排序...1.3 希尔排序的时间复杂度和空间复杂度等 算法名称 平均时间复杂度 最好情况 最坏情况 空间复杂度 稳定性 希尔排序 O(nlogn) O(nlogn) O(nlogn) O(1) 不稳定 2....%d arr:%s", j, insertIndex, Arrays.toString(arr)); System.out.println(); } } } } 代码基本与普通插入排序一致

    69610

    希尔排序

    希尔排序(ShellSort)是以它的发明者Donald Shell名字命名的,希尔排序是插入排序的改进版,实现简单,对于中等规模数据的性能表现还不错 排序思想 前情回顾:直接插入排序(对插入排序不熟悉的强烈建议先阅读此文...其实希尔排序就可以实现这个效果 希尔排序是怎么做的呢? ? ? 一尘 ? 慧能 ?...下面有颜色的是逻辑上的分组,并没有实际地进行分组操作,在数组中的位置还是原来的样子,只是将他们看成这么几个分组(逻辑上分组) 可以看出,他是按下标相隔距离为4分的组,也就是说把下标相差4的分到一组,比如这个例子中...同理,对这仅有的一组数据进行排序,排序完成 希尔排序真厉害啊,同时构造出两个特殊条件以达到高效插入 ? ? 一尘 ? 慧能 ? 恩恩,这就是希尔排序的精华所在 排序代码 ? 慧能 ?...最后说一下稳定性吧 不是稳定的,虽然插入排序是稳定的,但是希尔排序在插入的时候是跳跃性插入的,有可能破坏稳定性 ? ? 一尘 ?

    40460

    排序——希尔排序

    希尔排序(基于逐趟缩小增量) 基本思想 先将整个待排记录序列分割成若干子序列,分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行一次直接插入排序。...(k = 0; k < t; k++) ShellInsert(L, dlta[k]); // 增量为dlta[k]的一趟插入排序 } void ShellInsert(SqList &L,...int dk){ // 对顺序表L进行一趟增量为dk的Shell排序,dk为步长因子 for(i = dk + 1; i <= L.length; i++){ // 开始将r[i] 插入有序增量子表...暂存在r[0] for(j = i - dk; j > 0 && (r[0].key < r[j].key); j = j - dk) r[j + dk] = r[j]; // 关键字较大的记录在子表中后移...,目前尚未解决 最后一个增量值必须为1,无除1以外的公因子 不宜在链式存储结构上实现

    762105

    排序----希尔排序

    上一篇:插入排序 希尔排序的思想是:使数组中任意间隔为h的元素都是有序的。这样的数组成为h有序数组。换句话说,一个h数组就是h个互相独立的有序数组 编织在一起组成的数组。...实现希尔排序的一种方法是对于每个h,使用插入排序将h个子数组独立地排序。然后按某种次序递减h,可以实现数组整体排序。这里出现两个问题:为什么使用插入排序而不是选择排序?按哪种次序递减h?...希尔排序是对直接插入排序的改进,它权衡了子数组的规模和有序性。它避免了直接插入排序主键最小的元素正好在数组的尽头,要将它挪动到正确的位置需要移动次数很多的问题。...希尔排序的算法性能不仅取决于h,还取决于h之间的数学性质,比如它们的公因子等。 希尔排序的用时是次平方级别的,目前发现希尔排序最坏情况也达不到平方级别,是N^1.5次方。...” } 从希尔排序可以发现,我们对插入排序稍微改动,就在效率上取得了极大的提升,算法的魅力正在于此。

    86600

    排序算法 --- 希尔排序

    一、排序思想 之前说到插入排序,希尔排序就对其进行了一个优化,优化的思路是: 对待排序列进行分组,组数为gap = arr.length / 2; 对每一组进行插入排序,然后再进行分组,gap = gap...二、代码实现 关于希尔的代码实现,网上很多花里胡哨的答案,什么交换法位移法之类的,其实不要想得那么复杂。...刚才说了,希尔排序的主要思想就是分组,对每一组分别进行插入排序,那代码就简单了,就是这分组里面将之前插入排序的代码拷过来稍微改改就行了。...,以前插入排序的代码是这样的: for(int i=1; i排序 int insertVal = arr...聪明的你肯定发现了,以前只有一组,每次比较的时候,步长是1,现在步长是gap,所以,只要将以前插入排序循环中的1都改成gap就行了,完整代码如下: public static void mySort(int

    49831

    【排序算法】希尔排序

    希尔排序( 缩小增量排序 ) 希尔排序是一种经典的排序算法,它通过多次插入排序的方式,以及逐步缩小增量的策略,实现对数据的高效排序,希尔排序法又称缩小增量法。...分组思想 希尔排序的核心思想在于将待排序的数据分成若干组,对每一组数据进行插入排序。这样做的好处是,一方面可以减少数据的比较次数和移动次数,另一方面可以利用已经部分有序的性质,加速排序的过程。...: 希尔排序是对直接插入排序的优化。...排序稳定性分析:不稳定,即在排序过程中相等元素的相对位置可能发生变化。...当到达=1时,所有记录在统一组内排好序 时间复杂度 O(N^1.3) 空间复杂度的空间复杂度为 O(1) 排序稳定性:不稳定,即在排序过程中相等元素的相对位置可能发生变化。

    10110

    排序四 希尔排序

    我们可以清楚的看到,在排序过程中,两个元素位置交换了。 所以,希尔排序是不稳定的算法。...[图片] 已知的最好步长序列是由Sedgewick提出的(1, 5, 19, 41, 109,...),该序列的项来自 这两个算式。 这项研究也表明“比较在希尔排序中是最主要的操作,而不是交换。”...算法稳定性 由上文的希尔排序算法演示图即可知,希尔排序中相等数据可能会交换位置,所以希尔排序是不稳定的算法。 直接插入排序和希尔排序的比较 直接插入排序是稳定的;而希尔排序是不稳定的。...直接插入排序更适合于原始记录基本有序的集合。 希尔排序的比较次数和移动次数都要比直接插入排序少,当N越大时,效果越明显。 在希尔排序中,增量序列gap的取法必须满足:最后一个步长必须是 1 。...直接插入排序也适用于链式存储结构;希尔排序不适用于链式结构。 完整参考代码 JAVA版本 代码实现 范例代码中的初始序列和本文图示中的序列完全一致。

    90090

    希尔排序解读(基于java实现)

    概述希尔排序(Shell Sort)是一种基于插入排序的排序算法,通过将待排序的元素分组进行插入排序,逐步减小分组的间隔,最终使整个序列有序。...时间空间复杂度分析时间复杂度: 希尔排序的时间复杂度是比较复杂的,由于增量序列的选择不同,最坏情况下的时间复杂度可以达到O(n^2),但在一般情况下,希尔排序的平均时间复杂度为O(n log n)。...究其原因,希尔排序通过将待排序序列划分为若干个子序列进行插入排序,每次排序时的间隔逐渐缩小。...内层循环从gap开始,依次遍历数组中的元素。对于每个元素,我们将其保存在临时变量temp中,并使用j记录其位置。内层循环的内部,我们使用另一个循环实现插入排序。...将保存在临时变量temp中的值放置在正确的位置上,完成一次插入排序。外层循环会重复进行,直到gap的值为1,此时进行最后一次插入排序,将整个数组排序完成。

    26010

    希尔排序

    希尔排序(ShellSort)是以它的发明者Donald Shell名字命名的,希尔排序是插入排序的改进版,实现简单,对于中等规模数据的性能表现还不错 排序思想 前情回顾:直接插入排序(对插入排序不熟悉的强烈建议先阅读此文...其实希尔排序就可以实现这个效果 希尔排序是怎么做的呢? ? ? 一尘 ? 慧能 ?...下面有颜色的是逻辑上的分组,并没有实际地进行分组操作,在数组中的位置还是原来的样子,只是将他们看成这么几个分组(逻辑上分组) 可以看出,他是按下标相隔距离为4分的组,也就是说把下标相差4的分到一组,比如这个例子中...同理,对这仅有的一组数据进行排序,排序完成 希尔排序真厉害啊,同时构造出两个特殊条件以达到高效插入 ? ? 一尘 ? 慧能 ? 恩恩,这就是希尔排序的精华所在 排序代码 ? 慧能 ?...既然知道了思想,那你写一写代码吧 对于已经熟悉插入排序的一尘来说这并不是什么难事,很快,一尘写出了希尔排序的代码 ?

    44110

    希尔排序

    1、希尔排序介绍 希尔排序是对直接插入排序算法的一种改进,当记录较少或者记录本身基本有序的时候直接插入排序的优势非常明显,所以希尔排序就是通过人为的创造这两个条件,然后进行插入排序,基本思想是设置一个增量...引用一个别人的博文的例子“经典排序算法 - 希尔排序Shell sort ”  准备待排数组[6 2 4 1 5 9] 首先需要选取关键字,例如关键是3和1(第一步分成三组,第二步分成一组),那么待排数组分成了以下三个虚拟组...,就是4后边,6前边 后边的也不用改,所以排序完毕 顺序输出结果:[1 2 4 5 6 9] 2、希尔排序的关键是如何取关键字,因为其它内容与插入排序一样 好的增量序列的共同特征: ① 最后一个增量必须为...1 ② 应该尽量避免序列中的值(尤其是相邻的值)互为倍数的情况 参见 http://baike.baidu.com/view/2217047.htm 大量的研究表明,当增量序列为dlta[k]=2^(t-k...+1)-1      (t、k有一定的范围)的时候可以获得不错的效果公式参见大话数据结构p395 下面为C++的shell排序实现: // 希尔排序.cpp : 定义控制台应用程序的入口点。

    55780

    希尔排序

    希尔排序(Shell's Sort)是插入排序的一种又称“缩小增量排序”(Diminishing Increment Sort),是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。...希尔排序是基于插入排序的以下两点性质而提出改进方法的: 1.插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率。...但是在希尔排序中,一个元素可能会被移动的很远,所以相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱,所以shell排序是不稳定的。...希尔排序的时间复杂度与增量序列的选取有关,Hibbard增量的希尔排序的时间复杂度为O(n3/2),希尔排序时间复杂度的下界是n*log2n。...增量序列的选择 Shell排序的执行时间依赖于增量序列。 好的增量序列的共同特征: 1.最后一个增量必须为1; 2.应该尽量避免序列中的值(尤其是相邻的值)互为倍数的情况。

    56840

    希尔排序

    希尔排序 思想 希尔排序是插入排序的一种,也称之为缩小增量排序。希尔排序算法是直接插入排序算法的一种改进,减少了其复制的次数,速度要快很多。...希尔排序是非稳定排序算法,实现过程: 将记录按照下标的一定增量进行分组,对每个组进行插入排序 增量逐渐减少:当减少至1时,算法终止 栗子 假设步长为step,对[1, 8, 2, 9, 3, 7, 4,...6, 5]进行排序,步长一般是按照折半进行选取 步长取4:对[1, 3, 5],[8, 7],[2, 4],[9, 6]三个序列,分别进行插入排序 步长取2:对上述排序的序列,步长取一半,再按照类似的方法进行排序...(alist): # 希尔排序:核心是插入排序 n = len(alist) # 折半:取整数解,防止小数:n=9,step=4 step = n // 2 i...], numberArray[i-step] = numberArray[i-step], numberArray[i] i -= step // 每交换一次,下标左移step;直接插入排序中是左移一个位置

    32520
    领券