一、动图演示

二、思路分析

希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至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 复杂度分析)的更多相关文章

  1. 八大排序算法详解(动图演示 思路分析 实例代码java 复杂度分析 适用场景)

    一.分类 1.内部排序和外部排序 内部排序:待排序记录存放在计算机随机存储器中(说简单点,就是内存)进行的排序过程. 外部排序:待排序记录的数量很大,以致于内存不能一次容纳全部记录,所以在排序过程中需 ...

  2. 八大排序算法——插入排序(动图演示 思路分析 实例代码java 复杂度分析)

    一.动图演示 二.思路分析 例如从小到大排序: 1.  从第二位开始遍历, 2.  当前数(第一趟是第二位数)与前面的数依次比较,如果前面的数大于当前数,则将这个数放在当前数的位置上,当前数的下标-1 ...

  3. 八大排序算法——堆排序(动图演示 思路分析 实例代码java 复杂度分析)

    一.动图演示 二.思路分析 先来了解下堆的相关概念:堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆:或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆.如 ...

  4. 八大排序算法——归并排序(动图演示 思路分析 实例代码java 复杂度分析)

    一.动图演示 二.思路分析 归并排序就是递归得将原始数组递归对半分隔,直到不能再分(只剩下一个元素)后,开始从最小的数组向上归并排序 1.  向上归并排序的时候,需要一个暂存数组用来排序, 2.  将 ...

  5. 八大排序算法——快速排序(动图演示 思路分析 实例代码Java 复杂度分析)

    一.动图演示 二.思路分析 快速排序的思想就是,选一个数作为基数(这里我选的是第一个数),大于这个基数的放到右边,小于这个基数的放到左边,等于这个基数的数可以放到左边或右边,看自己习惯,这里我是放到了 ...

  6. 八大排序算法——冒泡排序(动图演示 思路分析 实例代码java 复杂度分析)

    一.动图演示 二.思路分析 1.  相邻两个数两两相比,n[i]跟n[j+1]比,如果n[i]>n[j+1],则将连个数进行交换, 2.  j++, 重复以上步骤,第一趟结束后,最大数就会被确定 ...

  7. 八大排序算法——选择排序(动图演示 思路分析 实例代码Java 复杂度分析)

    一.动图演示 二.思路分析 1.  第一个跟后面的所有数相比,如果小于(或小于)第一个数的时候,暂存较小数的下标,第一趟结束后,将第一个数,与暂存的那个最小数进行交换,第一个数就是最小(或最大的数) ...

  8. 八大排序算法——基数排序(动图演示 思路分析 实例代码java 复杂度分析)

    一.动图演 二.思路分析 基数排序第i趟将待排数组里的每个数的i位数放到tempj(j=1-10)队列中,然后再从这十个队列中取出数据,重新放到原数组里,直到i大于待排数的最大位数. 1.数组里的数最 ...

  9. Java常见排序算法之Shell排序

    在学习算法的过程中,我们难免会接触很多和排序相关的算法.总而言之,对于任何编程人员来说,基本的排序算法是必须要掌握的. 从今天开始,我们将要进行基本的排序算法的讲解.Are you ready?Let ...

随机推荐

  1. 模板std::mutex用法:

    std::mutex mymutex; std::lock_guard<std::mutex> lock(mymutex);

  2. java线程学习之notify方法和notifyAll方法

    notify(通知)方法,会将等待队列中的一个线程取出.比如obj.notify();那么obj的等待队列中就会有一个线程选中并且唤醒,然后被唤醒的队列就会退出等待队列.活跃线程调用等待队列中的线程时 ...

  3. 关于BDD100k数据输入处理mask变为56*56

    Mask_rcnn数据训练 Mask rcnn往里面送的是数据原图,可能没有把mask送里面,而且mask的数据 56*56,仿照coco——inspect_data重点考虑 Bounding box ...

  4. 码云和git

    第一步: 码云上注册: 第二部: 创建项目;根据需求,哒哒哒全部填完 第三部: 设置公钥(重点来了,头晕) 1. 打开git终端 git Bash 2.进入.ssh目录 输入命令 cd ~/.ssh ...

  5. ApiDoc官方文档

    链接地址:https://blog.csdn.net/whatday/article/details/84590795

  6. 隐藏软键盘(解决自定义Dialog中无法隐藏的问题)

    /** * Dialog中隐藏软键盘不管用 * @param activity */ public static void HideSoftKeyBoard(Activity activity){ t ...

  7. 编程类-----matlab基础语法复习(1)

    2019年美赛随笔记录: 具体功能:基础语法+基本运算+画图+矩阵+excel读取....... 所遇问题及其解决方案:         1.   que:matlab中plot画图无法复制下来图片? ...

  8. linux下 如何切换到root用户

    默认安装完成之后并不知道root用户的密码,那么如何应用root权限呢? (1)sudo 命令 xzm@ubuntu:~$  sudo 这样输入当前管理员用户密码就可以得到超级用户的权限.但默认的情况 ...

  9. MongoDB 索引 explain 分析查询速度

    一.索引基础索引是对数据库表中一列或多列的值进行排序的一种结构,可以让我们查询数据库变得更快.MongoDB 的索引几乎与传统的关系型数据库一模一样,这其中也包括一些基本的查询优化技巧.下面是创建索引 ...

  10. JS高程13.3事件对象的学习笔记

    1.事件流 事件流描述的是页面中元素接收事件的顺序.比如你单击了某个按钮,他们都认为单击事件不仅仅发生在按钮上,换句话说,在单击按钮的同时,你也单击了按钮的容器元素,甚至还单击了整个页面.那么你到底是 ...