八大排序算法——希尔(shell)排序(动图演示 思路分析 实例代码java 复杂度分析)
一、动图演示

二、思路分析
希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。
简单插入排序很循规蹈矩,不管数组分布是怎么样的,依然一步一步的对元素进行比较,移动,插入,比如[5,4,3,2,1,0]这种倒序序列,数组末端的0要回到首位置很是费劲,比较和移动元素均需n-1次。
而希尔排序在数组中采用跳跃式分组的策略,通过某个增量将数组元素划分为若干组,然后分组进行插入排序,随后逐步缩小增量,继续按组进行插入排序操作,直至增量为1。希尔排序通过这种策略使得整个数组在初始阶段达到从宏观上看基本有序,小的基本在前,大的基本在后。然后缩小增量,到增量为1时,其实多数情况下只需微调即可,不会涉及过多的数据移动。
来看下希尔排序的基本步骤,在此选择增量gap=length/2,缩小增量继续以gap = gap/2的方式,这种增量选择可以用一个序列来表示,{n/2,(n/2)/2...1},称为增量序列。希尔排序的增量序列的选择与证明是个数学难题,选择的这个增量序列是比较常用的,也是希尔建议的增量,称为希尔增量,但其实这个增量序列不是最优的。此处做示例使用希尔增量。

三、复杂度分析
1. 时间复杂度:最坏情况下,每两个数都要比较并交换一次,则最坏情况下的时间复杂度为O(n2), 最好情况下,数组是有序的,不需要交换,只需要比较,则最好情况下的时间复杂度为O(n)。
经大量人研究,希尔排序的平均时间复杂度为O(n1.3)(这个我也不知道咋来的,书上和博客上都这样说,也没找到个具体的依据,,,)。
2. 空间复杂度:希尔排序,只需要一个变量用于两数交换,与n的大小无关,所以空间复杂度为:O(1)。
四、Java 代码如下
import java.util.Arrays;
public class shell {
public static void main(String[] args) {
int[] arr = new int[]{10,6,3,8,33,27,66,9,7,88};
shellSort(arr);
System.out.println(Arrays.toString(arr));
}
private static void shellSort(int[] arr) {
int temp;
//控制增量序列,增量序列为1的时候为最后一趟
for (int i = arr.length/2; i >0; i/=2) {
//根据增量序列,找到每组比较序列的最后一个数的位置
for (int j = i; j < arr.length; j++) {
//根据该比较序列的最后一个数的位置,依次向前执行插入排序
for (int k = j-i; k >=0; k-=i) {
if(arr[k]>arr[k+i]){
temp = arr[k];
arr[k] = arr[k+i];
arr[k+i] = temp;
}
}
}
}
}
}
八大排序算法——希尔(shell)排序(动图演示 思路分析 实例代码java 复杂度分析)的更多相关文章
- 八大排序算法详解(动图演示 思路分析 实例代码java 复杂度分析 适用场景)
一.分类 1.内部排序和外部排序 内部排序:待排序记录存放在计算机随机存储器中(说简单点,就是内存)进行的排序过程. 外部排序:待排序记录的数量很大,以致于内存不能一次容纳全部记录,所以在排序过程中需 ...
- 八大排序算法——插入排序(动图演示 思路分析 实例代码java 复杂度分析)
一.动图演示 二.思路分析 例如从小到大排序: 1. 从第二位开始遍历, 2. 当前数(第一趟是第二位数)与前面的数依次比较,如果前面的数大于当前数,则将这个数放在当前数的位置上,当前数的下标-1 ...
- 八大排序算法——堆排序(动图演示 思路分析 实例代码java 复杂度分析)
一.动图演示 二.思路分析 先来了解下堆的相关概念:堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆:或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆.如 ...
- 八大排序算法——归并排序(动图演示 思路分析 实例代码java 复杂度分析)
一.动图演示 二.思路分析 归并排序就是递归得将原始数组递归对半分隔,直到不能再分(只剩下一个元素)后,开始从最小的数组向上归并排序 1. 向上归并排序的时候,需要一个暂存数组用来排序, 2. 将 ...
- 八大排序算法——快速排序(动图演示 思路分析 实例代码Java 复杂度分析)
一.动图演示 二.思路分析 快速排序的思想就是,选一个数作为基数(这里我选的是第一个数),大于这个基数的放到右边,小于这个基数的放到左边,等于这个基数的数可以放到左边或右边,看自己习惯,这里我是放到了 ...
- 八大排序算法——冒泡排序(动图演示 思路分析 实例代码java 复杂度分析)
一.动图演示 二.思路分析 1. 相邻两个数两两相比,n[i]跟n[j+1]比,如果n[i]>n[j+1],则将连个数进行交换, 2. j++, 重复以上步骤,第一趟结束后,最大数就会被确定 ...
- 八大排序算法——选择排序(动图演示 思路分析 实例代码Java 复杂度分析)
一.动图演示 二.思路分析 1. 第一个跟后面的所有数相比,如果小于(或小于)第一个数的时候,暂存较小数的下标,第一趟结束后,将第一个数,与暂存的那个最小数进行交换,第一个数就是最小(或最大的数) ...
- 八大排序算法——基数排序(动图演示 思路分析 实例代码java 复杂度分析)
一.动图演 二.思路分析 基数排序第i趟将待排数组里的每个数的i位数放到tempj(j=1-10)队列中,然后再从这十个队列中取出数据,重新放到原数组里,直到i大于待排数的最大位数. 1.数组里的数最 ...
- Java常见排序算法之Shell排序
在学习算法的过程中,我们难免会接触很多和排序相关的算法.总而言之,对于任何编程人员来说,基本的排序算法是必须要掌握的. 从今天开始,我们将要进行基本的排序算法的讲解.Are you ready?Let ...
随机推荐
- HTTP劫持和DNS劫持
HTTP劫持和DNS劫持 首先对运营商的劫持行为做一些分析,他们的目的无非就是赚钱,而赚钱的方式有两种: 1.对正常网站加入额外的广告,这包括网页内浮层或弹出广告窗口: 2.针对一些广告联盟或带推广链 ...
- python numpy 科学计算通用函数汇总
import numpy as np #一元函数 #绝对值计算 a = -1b = abs(a)print(b)输出: 1 #开平方计算 a = 4b = np.sqrt(a)print(b)输出: ...
- C++ 中的sort()排序函数用法
sort(first_pointer,first_pointer+n,cmp) 该函数可以给数组,或者链表list.向量排序. 实现原理:sort并不是简单的快速排序,它对普通的快速排序进行了优化,此 ...
- C# RSA加解密与验签,AES加解密,以及与JAVA平台的密文加解密
前言: RSA算法是利用公钥与密钥对数据进行加密验证的一种算法.一般是拿私钥对数据进行签名,公钥发给友商,将数据及签名一同发给友商,友商利用公钥对签名进行验证.也可以使用公钥对数据加密,然后用私钥对数 ...
- python操作字符串类型json的注意点
python操作json的方法有json.dumps——将json对象(字典)转换为字符串对象json.loads——将字符串对象转换为json对象(字典)如果定义json对象jsonstring1= ...
- MAVEN项目中include引入静态文件时报错找不到文件
1. 出现的问题 Fragment "/common/jsp/resource.jsp" was not found at expected path /src/main/weba ...
- sed命令替换文件的内容【学习笔记】
sed -i "s/line/Line/g" `grep "line" -rl /home//zhuangzebin/`
- MySQL之 视图,触发器,存储过程,函数,事物,数据库锁,数据库备份
1.视图 视图: 是一个虚拟表,其内容由查询定义: 视图有如下特点; 1. 视图的列可以来自不同的表,是表的抽象和逻辑意义上建立的新关系. 2. 视图是由基本表(实表)产生的表(虚表). 3. ...
- 比原链(Bytom)先知节点 Windows接入文档
系统要求 我们建议选择知名的VPS服务商,运行比原链节点对算力没有要求,但是请配置尽可能大的磁盘空间. 节点服务器最小配置: 操作系统: Windows/Linux/Docker CPU: 2核 内存 ...
- C# Selenium 破解腾讯滑动验证
什么是Selenium? WebDriver是主流Web应用自动化测试框架,具有清晰面向对象 API,能以最佳的方式与浏览器进行交互. 支持的浏览器: Mozilla Firefox Google C ...