数据结构与算法-------希尔排序------交换法+移动法
希尔排序
希尔排序是希尔(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 什么叫希尔排序? 2 代码实现 3 时间复杂度 4 稳定性 参考 1 什么叫希尔排序? 希尔排序(Shell Sort)是插入排序的一种.该方法因DL.Shell于1959年提出而 ...
- 数据结构与算法之排序算法
数据结构与算法之排序算法 排序算法的介绍 排序也称排序算法(Sort Algorithm),排序是将一组数据,依指定的顺序进行排序的过程. 排序的分类 1)内部排序:指将需要处理的数据都加载到内部 ...
- 常见数据结构和算法实现(排序/查找/数组/链表/栈/队列/树/递归/海量数据处理/图/位图/Java版数据结构)
常见数据结构和算法实现(排序/查找/数组/链表/栈/队列/树/递归/海量数据处理/图/位图/Java版数据结构) 数据结构和算法作为程序员的基本功,一定得稳扎稳打的学习,我们常见的框架底层就是各类数据 ...
- 数据结构排序算法实验报告_[数据结构与算法系列]排序算法(二)
我的上一篇文章向大家介绍了排序算法中的冒泡排序.插入排序和选择排序.它们都是平均时间复杂度为 O(n^2) 的排序算法,同时还为大家讲解了什么是原地排序和什么是排序的稳定性.下图是这三种算法的比较,不 ...
- 数据结构与算法(三) 排序算法(代码示例)
数据结构与算法三 排序算法 1. 选择排序 2. 插入排序 3. 冒泡排序 4. 归并排序 5. 快速排序 6. 希尔排序 7. 堆排序 总结 1. 选择排序 选择排序的基本原理: 对于未排序的一组记 ...
- 排序算法---希尔排序(java版)
希尔排序 原理 先将待排序表分割成若干相隔某个"增量"的记录组成一个子表,对各个子表分别进行直接插入,当整个表中的元素已成基本有序是,再对全体记录进行一次直接插入排序.希尔排序主要 ...
- 在Object-C中学习数据结构与算法之排序算法
笔者在学习数据结构与算法时,尝试着将排序算法以动画的形式呈现出来更加方便理解记忆,本文配合Demo 在Object-C中学习数据结构与算法之排序算法阅读更佳. 目录 选择排序 冒泡排序 插入排序 快速 ...
- 经典排序算法 - 希尔排序Shell sort
经典排序算法 - 希尔排序Shell sort 希尔排序Shell Sort是基于插入排序的一种改进,同样分成两部分, 第一部分,希尔排序介绍 第二部分,如何选取关键字,选取关键字是希尔排序的关键 第 ...
- 十大经典排序算法-希尔排序算法详解
十大经典排序算法 十大经典排序算法-冒泡排序算法详解 十大经典排序算法-选择排序算法详解 十大经典排序算法-插入排序算法详解 十大经典排序算法-希尔排序算法详解 十大经典排序算法-快速排序算法详解 十 ...
- python排序算法——希尔排序(附代码)
python排序算法--希尔排序 文章目录 python排序算法--希尔排序 一.前言 二.算法描述 三.代码实现 总结 一.前言 相关知识来自<python算法设计与分析>.初级排序算法 ...
最新文章
- 极客新闻——04、WiFi万能钥匙万玉权:管理应该是“自下而上”
- KVM调整cpu和内存
- [gic]-ARM gicv3/gicv2的总结和介绍-PPT
- word项目符号或编号bullets and numbering
- 不同的写法 其中 1 2 (试了下 没有效果 ,先记载这里把)
- 【Flink】报错 KryoException ConcurrentModificationException StackOverflowError
- log4j 总结 精华
- suse linux rpm 安装
- 分享我的Linux开发环境
- Java 多线程执行
- 题目:输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。
- 讲解对于Java中如何计算日期之间的天数知识
- Android中TextView中文字体粗体的设置方法
- 面试中单例模式有几种写法?
- 工业用科技激光SLAM拣货潜伏式AGV多层料箱机器人|海格里斯HEGERLS助你实现生产全自动化
- 如何深入理解PhalApi框架三层结构Api+Domain+Model模式
- PS 不能使用移动工具 因为目标图层被隐藏怎么办
- 罗克韦尔自动化启用位于硅谷的新建电动汽车创新中心
- 自定义SSLSocketFactory
- 大数据时代如何使用数据分析来找女朋友?