希尔排序

希尔排序是希尔(DonaldShell) 于1959年提出的一种排序算法。希尔排序也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序。

基本思想

希尔排序是把记录按下标的一定增量分组对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止

解释

我们看常见的希尔排序动态图解

太快额?

来个静态图示

已经非常接近有序的了,即使需要移动来插入,也就移动1到2步,我们就可以使用直接插入排序对这一个大组进行排序

当然,我们对有序序列进行插入时,怎么插入的?

分别有**交换法,移动法,**我们分别写出来测一下

请听题

科大10个人去面试CSDN社团,满分是10分,现在给出的分数是8,9,1,7,2,3,5,4,6,0,请用希尔排序将他们从小到大排列

交换法推导过程

package com.wang.sort;import java.util.Arrays;/*** @author 王庆华* @version 1.0* @date 2020/12/24 17:11* @Description TODO* @pojectname 希尔排序算法*/
public class ShellSort {public static void main(String[] args) {int[] arr = {8,9,1,7,2,3,5,4,6,0};ShellSort(arr);}//交换法逐步推导过程public static void ShellSort(int[] arr){int temp = 0;//希尔排序的第一轮排序//分组,我们例子是10个数据除以二就是5组for (int i = 5; i <arr.length ; i++) {//遍历各组中所有的元素,共有5组,每组2个元素//步长是5  5-5=0   6-5=1 7-5=2for (int j = i-5; j >=0 ; j-=5) {//如果当前元素大于加上步长后的元素,说明需要交换if (arr[j]>arr[j+5]){//0>6  1>7 2>8 3>9 4>10temp = arr[j];arr[j] = arr[j+5];arr[j+5] = temp;}}}System.out.println("希尔排序第一轮后"+ Arrays.toString(arr));//第二轮//在第一组的基础上,5组再除以2 分为2组,步长变为2for (int i = 2; i <arr.length ; i++) {//遍历各组中所有的元素,共有5组,每组2个元素for (int j = i-2; j >=0 ; j-=2) {//如果当前元素大于加上步长后的元素,说明需要交换if (arr[j]>arr[j+2]){//0>6  1>7 2>8 3>9 4>10temp = arr[j];arr[j] = arr[j+2];arr[j+2] = temp;}}}System.out.println("第二轮希尔排序后的结果"+Arrays.toString(arr));//第三轮//在第二组的基础上,2组再除以2 分为1组,步长变为1for (int i = 1; i <arr.length ; i++) {//遍历各组中所有的元素,共有5组,每组2个元素for (int j = i-1; j >=0 ; j-=1) {//如果当前元素大于加上步长后的元素,说明需要交换if (arr[j]>arr[j+1]){//0>6  1>7 2>8 3>9 4>10temp = arr[j];arr[j] = arr[j+1];arr[j+1] = temp;}}}System.out.println("第三轮希尔排序后的结果"+Arrays.toString(arr));}
}

希尔排序交换法

/*** @author 王庆华* @version 1.0* @date 2020/12/24 17:11* @Description TODO* @pojectname 希尔排序算法*/
public class ShellSort {public static void main(String[] args) {int[] arr = {8,9,1,7,2,3,5,4,6,0};ShellSort(arr);}//交换法逐步推导过程public static void ShellSort(int[] arr){int temp = 0;int count = 0;for (int gap = arr.length/2; gap >0 ; gap/=2) {for (int i = gap; i <arr.length ; i++) {for (int j = i-gap; j >=0 ; j-=gap) {if (arr[j]>arr[j+gap]){temp = arr[j];arr[j] = arr[j+gap];arr[j+gap] = temp;}}}System.out.println("希尔排序"+(count++)+"轮"+Arrays.toString(arr));}}
}

外层for循环控制的是分多少组,恰巧我们发现这个gap也是我们的步长,步长也是由它来控制,这就很巧了,比如我们第一次分了5个组,就是

for(int gap = 5;gap>0;gap=2){for(int i=gap;i<arr.length;i++){for(int j = i - gap;j>=0;j-=gap){我们就拿第一个数据来举例;8  和   3;if(8>3){//a[0]>a[5]交换;然后j=j-gap=0-5跳出最内层循环让i++变成6再进入最内层循环也就是这次是a[j=1]和a[j+gap=6]比较 9>5交换我们的j=j-gap=-4 跳出i变成2再进来依次类推}}}
}

效率较低,我们有插入法的希尔排序,效率更高

移动法希尔排序

为什么交换法的希尔排序会很慢呢?

因为我们的交换temp = arr[j]; arr[j] = arr[j+gap];arr[j+gap] = temp;代价很大的,我们的直接插入排序就直接插入到了那个位置,不需要来回交换,因此交换法希尔排序比较慢

那么移动法希尔排序怎么做呢?

代码

/*** @author 王庆华* @version 1.0* @date 2020/12/24 17:11* @Description TODO* @pojectname 希尔排序算法*/
public class ShellSort {public static void main(String[] args) {int[] arr = {8,9,1,7,2,3,5,4,6,0};shellSort2(arr);System.out.println(Arrays.toString(arr));}public static void shellSort2(int[] arr){//增量gap,并逐步缩小增量for (int gap = arr.length/2; gap >0 ; gap/=2) {//从第gap个元素,逐个对其所在的组进行直接插入排序for (int i = gap; i <arr.length ; i++) {int j = i;//带插入的下标先保存起来int temp = arr[j];if (arr[j] < arr[j-gap]){while (j - gap>=0 && temp< arr[j-gap]){//继续找位置//移动arr[j] = arr[j-gap];j-=gap;//向前移动}//退出循环时,找到位置arr[j] = temp;}}}}
}

文字来解释一下

还是老办法拿数据来举例,我们的第一层循环还是用来分组和制定我们的步长的,第一次进去,5组,每组2个数据,步长是5,

第二层循环,我们先获得我们的起始位置,5,temp=arr[5]=3,也就是第六个数据,同样它是第一组的第二个数据哦!!那么进入if判断的时候,我们发现j-gap正好是对应了跟它同组的另一个数据也就是8,他们两个判断,剩下的就跟我们的直接插入排序很像了,不同之处在于我们移动的地方,以前是-1,现在变成了-gap步长,也就是同组见进行了数据交换。还有不懂的我们可以debug在函数的地方打断点,跟着程序走一遍

数据结构与算法-------希尔排序------交换法+移动法相关推荐

  1. 数据结构与算法 | 希尔排序

    啥叫希尔排序? 1 什么叫希尔排序? 2 代码实现 3 时间复杂度 4 稳定性 参考 1 什么叫希尔排序? 希尔排序(Shell Sort)是插入排序的一种.该方法因DL.Shell于1959年提出而 ...

  2. 数据结构与算法之排序算法

    数据结构与算法之排序算法 排序算法的介绍 ​ 排序也称排序算法(Sort Algorithm),排序是将一组数据,依指定的顺序进行排序的过程. 排序的分类 1)内部排序:指将需要处理的数据都加载到内部 ...

  3. 常见数据结构和算法实现(排序/查找/数组/链表/栈/队列/树/递归/海量数据处理/图/位图/Java版数据结构)

    常见数据结构和算法实现(排序/查找/数组/链表/栈/队列/树/递归/海量数据处理/图/位图/Java版数据结构) 数据结构和算法作为程序员的基本功,一定得稳扎稳打的学习,我们常见的框架底层就是各类数据 ...

  4. 数据结构排序算法实验报告_[数据结构与算法系列]排序算法(二)

    我的上一篇文章向大家介绍了排序算法中的冒泡排序.插入排序和选择排序.它们都是平均时间复杂度为 O(n^2) 的排序算法,同时还为大家讲解了什么是原地排序和什么是排序的稳定性.下图是这三种算法的比较,不 ...

  5. 数据结构与算法(三) 排序算法(代码示例)

    数据结构与算法三 排序算法 1. 选择排序 2. 插入排序 3. 冒泡排序 4. 归并排序 5. 快速排序 6. 希尔排序 7. 堆排序 总结 1. 选择排序 选择排序的基本原理: 对于未排序的一组记 ...

  6. 排序算法---希尔排序(java版)

    希尔排序 原理 先将待排序表分割成若干相隔某个"增量"的记录组成一个子表,对各个子表分别进行直接插入,当整个表中的元素已成基本有序是,再对全体记录进行一次直接插入排序.希尔排序主要 ...

  7. 在Object-C中学习数据结构与算法之排序算法

    笔者在学习数据结构与算法时,尝试着将排序算法以动画的形式呈现出来更加方便理解记忆,本文配合Demo 在Object-C中学习数据结构与算法之排序算法阅读更佳. 目录 选择排序 冒泡排序 插入排序 快速 ...

  8. 经典排序算法 - 希尔排序Shell sort

    经典排序算法 - 希尔排序Shell sort 希尔排序Shell Sort是基于插入排序的一种改进,同样分成两部分, 第一部分,希尔排序介绍 第二部分,如何选取关键字,选取关键字是希尔排序的关键 第 ...

  9. 十大经典排序算法-希尔排序算法详解

    十大经典排序算法 十大经典排序算法-冒泡排序算法详解 十大经典排序算法-选择排序算法详解 十大经典排序算法-插入排序算法详解 十大经典排序算法-希尔排序算法详解 十大经典排序算法-快速排序算法详解 十 ...

  10. python排序算法——希尔排序(附代码)

    python排序算法--希尔排序 文章目录 python排序算法--希尔排序 一.前言 二.算法描述 三.代码实现 总结 一.前言 相关知识来自<python算法设计与分析>.初级排序算法 ...

最新文章

  1. 极客新闻——04、WiFi万能钥匙万玉权:管理应该是“自下而上”
  2. KVM调整cpu和内存
  3. [gic]-ARM gicv3/gicv2的总结和介绍-PPT
  4. word项目符号或编号bullets and numbering
  5. 不同的写法 其中 1 2 (试了下 没有效果 ,先记载这里把)
  6. 【Flink】报错 KryoException ConcurrentModificationException StackOverflowError
  7. log4j 总结 精华
  8. suse linux rpm 安装
  9. 分享我的Linux开发环境
  10. Java 多线程执行
  11. 题目:输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。
  12. 讲解对于Java中如何计算日期之间的天数知识
  13. Android中TextView中文字体粗体的设置方法
  14. 面试中单例模式有几种写法?
  15. 工业用科技激光SLAM拣货潜伏式AGV多层料箱机器人|海格里斯HEGERLS助你实现生产全自动化
  16. 如何深入理解PhalApi框架三层结构Api+Domain+Model模式
  17. PS 不能使用移动工具 因为目标图层被隐藏怎么办
  18. 罗克韦尔自动化启用位于硅谷的新建电动汽车创新中心
  19. 自定义SSLSocketFactory
  20. 大数据时代如何使用数据分析来找女朋友?

热门文章

  1. Javascript:结合canvas、a标签根据url下载图片到本地
  2. reflection java_Java Reflection (JAVA反射)
  3. 高等数学复习笔记(二)- 一元函数微分学的概念、计算以及几何应用
  4. Web Service工作原理及实例
  5. Java学习个人备忘录之文档注释
  6. iOS 学习 - 18.TextField 自定义菜单事件,复制和微信分享
  7. Activity 生命周期及其栈管理方式
  8. debian添加快捷启动方式
  9. C++基本类型隐性转换。
  10. TED如何和压力做朋友(一)