摘要:概述希尔排序的诞生是由于插入排序在处理大规模数组的时候会遇到需要移动太多元素的问题,也称递减增量排序算法。希尔排序的思想是将一个大的数组分而治之,划分为若干个小的数组,然后分别对划分出来的数组进行插入排序。
概述
希尔排序的诞生是由于插入排序在处理大规模数组的时候会遇到需要移动太多元素的问题,也称递减增量排序算法。希尔排序的思想是将一个大的数组“分而治之”,划分为若干个小的数组,然后分别对划分出来的数组进行插入排序。
希尔排序是基于插入排序的以下两点性质而提出改进方法的:
插入排序在对几乎已经排好序的数据操作时, 效率高, 即可以达到线性排序的效率
但插入排序一般来说是低效的, 因为插入排序每次只能将数据移动一位
效果示意图:
至于如何提高效率的,我们还是看下面的实例吧。
步骤取增量,一般取数组长度/2
按增量取得一个子数列,对子数列按插入排序的方式处理
将增量递减,重复1,2步骤
直至增量为为0,数列已经排好序
实例原始数据:
3 5 2 6 2
取5/2=2作为增量,对[3 2 2]进行插入排序,得到
2 5 2 6 3
增量递减2/2=1,对[2 5 2 6 3]进行插入排序,得到
2 2 3 5 6
增量递减为0,排序结束。
代码实现(Java)package com.coder4j.main.arithmetic.sorting; public class Shell { /** * 希尔排序 * * @param array * @return */ public static int[] sort(int[] array) { int step = array.length / 2; while (step >= 1) { for (int i = step; i < array.length; i++) { int temp = array[i]; int j; for (j = i - step; j >= 0 && temp < array[j]; j-=step) { array[j + step] = array[j]; } array[j + step] = temp; } System.out.println("增量为:" + step + ",结果:"); for (int k : array) { System.out.print(k + " "); } System.out.println(); step /= 2; } return array; } public static void main(String[] args) { int[] array = { 3, 5, 2, 6, 2 }; int[] sorted = sort(array); System.out.println("最终结果"); for (int i : sorted) { System.out.print(i + " "); } } }
测试输出结果:
增量为:2,结果: 2 5 2 6 3 增量为:1,结果: 2 2 3 5 6 最终结果 2 2 3 5 6
经测试,与实例中结果一致。
希尔与插入对比希尔是插入的改进优化,到底能否提高效率呢,我们作一下小测试。
分别对[1 2 3 4] 和 [4 3 2 1] 进行两种算法的排序操作,看移动的次数。
比较代码:
package com.coder4j.main.arithmetic.sorting; public class ShellVSInsert { /** * 插入排序 * * @param array * @return */ public static int[] insert(int[] array) { // 记录移动次数 int count = 0; for (int i = 1; i < array.length; i++) { int temp = array[i]; int j; for (j = i - 1; j >= 0 && temp < array[j]; j--) { array[j + 1] = array[j]; count++; } array[j + 1] = temp; } System.out.println("插入排序移动次数:" + count); for (int k : array) { System.out.print(k + " "); } System.out.println(); return array; } /** * 希尔排序 * * @param array * @return */ public static int[] shell(int[] array) { // 记录移动次数 int count = 0; int step = array.length / 2; while (step >= 1) { for (int i = step; i < array.length; i++) { int temp = array[i]; int j; for (j = i - step; j >= 0 && temp < array[j]; j = j - step) { array[j + step] = array[j]; count++; } array[j + step] = temp; } step /= 2; } System.out.println("希尔排序移动次数:" + count); for (int k : array) { System.out.print(k + " "); } System.out.println(); return array; } public static void main(String[] args) { int[] array1 = { 1, 2, 3, 4 }; insert(array1); int[] array2 = { 1, 2, 3, 4 }; shell(array2); int [] array3 = { 4, 3, 2, 1 }; insert(array3); int [] array4 = { 4, 3, 2, 1 }; shell(array4); } }
对比了两种极端情况,结果如下:
插入排序移动次数:0 1 2 3 4 希尔排序移动次数:0 1 2 3 4 插入排序移动次数:6 1 2 3 4 希尔排序移动次数:4 1 2 3 4
可见希尔排序在有些时候可以减少移动次数。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/65416.html
希尔排序 在介绍希尔排序之前,先了解一下直接插入排序 文章目录 希尔排序一、直接插入排序1. 单趟排序2. 直接插入排序 二、希尔排序三、测试希尔排序和直接插入排序性能 一、直接插入排序 1. 单趟排序 x插入一个有序区间 这里end是指向数组最后一个元素 2. 直接插入排序 根据上面的单趟排序启发 end是数组的最后一个元素,end之后的元素都是待排序 一个关键的判断点,end和...
摘要:常见的内部排序算法有插入排序希尔排序选择排序冒泡排序归并排序快速排序堆排序基数排序等。这里主要介绍希尔排序。一图胜千言算法介绍算法描述希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。但希尔排序是非稳定排序算法。 常见的内部排序算法有:插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。这里主要介绍希尔排序。 一图胜千言: showImg(h...
摘要:动态定义间隔序列参考来源详细介绍了十种算法大家可以去学习下以后大概会尽量每天更新一个算法学习吧温故而知新 参考书:严蔚敏-数据结构 希尔排序(Shells Sort) 希尔排序又称缩小增量排序,归属于插入排序一类,简单来说,和我们的插入排序比,它更快. 奇妙的记忆点: 内排序(内存排序就够了) 不稳定(排序后原始顺序无法保证) 希尔排序重点在于分割. 基本思想: 将整个待排序记录序...
阅读 2670·2021-11-25 09:43
阅读 2579·2021-11-22 09:34
阅读 2822·2021-11-12 10:34
阅读 1430·2021-10-20 13:46
阅读 2300·2019-08-30 13:21
阅读 928·2019-08-30 11:21
阅读 482·2019-08-30 11:20
阅读 2185·2019-08-29 17:20