希尔排序是插入排序的一种,是直接插入排序的改进版本。

对于上节介绍的直接插入排序法,如果数据原来就已经按要求的顺序排列,则在排序过程中不需要进行数据移动操作,即可得到有序数列。但是,如果最初的数据是按倒序排列的,则在进行插入排序时每次的比较都需要向后移动数据,这样,将导致算法的效率很低。

希尔排序的思想是把数列划分为若干个较小的数列,对每组数列使用直接插入排序算法排序,随着增量逐渐减少,每组包含的数字越来越多,当增量减至1时,整个数列恰被分成一组,最后再使用一次直接插入排序对整个数列进行排序。

例如有4, 3, 6, 2, 7, 1, 5, 8八个数字,第一次分成四组,即8/2组。如下图,相同颜色的数字为一组,下标为x的数字和下标为x+4的数字为一组。

对这四个数组分别做直接插入排序,即两两比较,如果大的在前则交换位置,得到:

然后缩小组数,4/2=2,缩小为两组。如下图:

对这两个数组分别做直接插入排序,得到:

再次缩小组数,2/2=1,缩小为一组,那么所有数字都。如下图:

最后,对4, 1, 5, 2, 6, 3, 7, 8这个数列执行一次直接插入排序。

总结上面的规律,可以得出:

第一次分组数s = n / 2 == 0 ? n / 2 : n / 2 + 1

取数规则是[x]和[x+n/2]为一组

当然,这只是比较简单的分组方式,不一定是最优的。来看代码:

  1. public class ShellSort {
  2. private int[] numbers;
  3. public ShellSort(int[] numbers) {
  4. this.numbers = numbers;
  5. }
  6. /**
  7. * 对数组分组并对每个组做直接插入排序, 完成后缩小组的数量, 重复插入排序, 直到缩小到一个组
  8. * 第一次分组数: section = n/2 == 0 ? n/2 : n/2+1, 分组规则: 每隔n/2挑一个数, 即[x]和[x+n/2]为一组
  9. */
  10. public void sort() {
  11. int section = this.numbers.length / 2;
  12. int j;
  13. int temp;
  14. while(section >= 1) {
  15. for(int i = section; i < this.numbers.length; i++) {
  16. temp = this.numbers[i];
  17. j = i - section;
  18. while(j >= 0 && this.numbers[j] > temp) {
  19. this.numbers[j + section] = this.numbers[j];
  20. j = j - section;
  21. }
  22. this.numbers[j + section] = temp;
  23. }
  24. section /= 2;
  25. }
  26. System.out.print("排序后: ");
  27. for(int x = 0; x < numbers.length; x++) {
  28. System.out.print(numbers[x] + "  ");
  29. }
  30. }
  31. public static void main(String[] args) {
  32. int[] numbers = new int[] { 4, 3, 6, 2, 7, 1, 5, 8 };
  33. System.out.print("排序前: ");
  34. for(int x = 0; x < numbers.length; x++) {
  35. System.out.print(numbers[x] + "  ");
  36. }
  37. System.out.println();
  38. ShellSort ss = new ShellSort(numbers);
  39. ss.sort();
  40. }
  41. }

运行:

  1. 排序前: 4  3  6  2  7  1  5  8
  2. 排序后: 1  2  3  4  5  6  7  8

希尔排序的时间复杂度,最坏是O(n^2),平均O(n^3/2)。

Java与算法之(10) - 希尔排序的更多相关文章

  1. python算法介绍:希尔排序

    python作为一种新的语言,在很多功能自然要比Java要好一些,也容易让人接受,而且不管您是成年人还是少儿都可以学习这个语言,今天就为大家来分享一个python算法教程之希尔排序,现在我们就来看看吧 ...

  2. python算法与数据结构-希尔排序算法(35)

    一.希尔排序的介绍 希尔排序(Shell Sort)是插入排序的一种.也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本.希尔排序是非稳定排序算法. 希尔排序是把记录按下标的一定增量分组,对每 ...

  3. 几种常见排序算法之Java实现(插入排序、希尔排序、冒泡排序、快速排序、选择排序、归并排序)

    排序(Sorting) 是计算机程序设计中的一种重要操作,它的功能是将一个数据元素(或记录)的任意序列,重新排列成一个关键字有序的序列. 稳定度(稳定性)一个排序算法是稳定的,就是当有两个相等记录的关 ...

  4. 9, java数据结构和算法: 直接插入排序, 希尔排序, 简单选择排序, 堆排序, 冒泡排序,快速排序, 归并排序, 基数排序的分析和代码实现

    内部排序: 就是使用内存空间来排序 外部排序: 就是数据量很大,需要借助外部存储(文件)来排序. 直接上代码: package com.lvcai; public class Sort { publi ...

  5. 排序算法入门之希尔排序(java实现)

    希尔排序是对插入排序的改进.插入排序是前面元素已经有序了,移动元素是一个一个一次往后移动,当插入的元素比前面排好序的所有元素都小时,则需要将前面所有元素都往后移动.希尔排序有了自己的增量,可以理解为插 ...

  6. Hark的数据结构与算法练习之希尔排序

    算法说明 希尔排序是插入排序的优化版. 插入排序的最坏时间复杂度是O(n2),但如果要排序的数组是一个几乎有序的数列,那么会降低有效的减低时间复杂度. 希尔排序的目的就是通过一个increment(增 ...

  7. 八大排序算法之二希尔排序(Shell Sort)

    希尔排序是1959 年由D.L.Shell 提出来的,相对直接排序有较大的改进.希尔排序又叫缩小增量排序 基本思想: 先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录 ...

  8. C#算法基础之希尔排序

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  9. Java与算法之(11) - 合并排序

    天下事,合久必分,分久必合.合并排序的基本思想正是先分再合. 例如对3, 1这个数列排序,首先是分,分为3和1两个数列,然后再合并并排序.合并需要额外的辅助空间,即建立一个两个数列长度之和的空数组用于 ...

随机推荐

  1. springboot+CXF开发webservice对外提供接口(转)

    文章来源:http://www.leftso.com/blog/144.html 1.项目要对外提供接口,用webservcie的方式实现 2.添加的jar包 maven: <dependenc ...

  2. 微信小程序——轮播图实现

    小程序的轮播图,也就是他其中的一个控件可以算是直接上代码: 这是WXML 页面 代码: <view class='carousel_div'> <swiper class=" ...

  3. AI 系列 总目录

    AI 系列 答应了园区大牛 张善友 要写AI 的系列博客,所以开始了AI 系列之旅. 一.四大平台系列(百度AI.阿里ET.腾讯.讯飞) 1.百度篇 (1) 百度OCR文字识别-身份证识别 (2) 基 ...

  4. 【java设计模式】【创建模式Creational Pattern】建造模式Builder Pattern

    package com.tn.pattern; public class Client { public static void main(String[] args) { Director dire ...

  5. Android活动生命周期

    任务(Task) Android 是使用任务(Task)来管理活动的,一个任务就是一组存放在栈里的活动的集合,这个栈也被称作返回栈(Back Stack).在默认情况下,每当我们启动了一个新的活动,它 ...

  6. sourceTree git 忽略指定文件

    按照如下步骤执行(终端命令) 1. git status modified: LovegoMall.xcworkspace/xcuserdata/Tiny.xcuserdatad/xcdebugger ...

  7. OC学习8——异常处理

    1.和Java一样,OC也有自己的一套异常处理机制,不同的是,OC中的异常处理机制并不是作为常规的编程实践,通常只是作为一种程序调试.排错机制. 2.与Java中类似,OC中也是采用@try...@c ...

  8. iOS pch文件创建使用,和info.plis文件路径改变,路径的设置

    一 路径报错: 二 pch创建设置: 一:如果要更改Info.plist与Prefix.pch文件实际路径,也就是实际文件的位置(不是在工程中的组织路径),需要到Build Settings中修改对应 ...

  9. GitLab配置ssh key

    一.背景 当前很多公司都选择git作为代码版本控制工具,然后自己公司搭建私有的gitlab来管理代码,我们在clone代码的时候可以选择http协议,当然我们亦可以选择ssh协议来拉取代码.但是网上很 ...

  10. bzoj 1996: [Hnoi2010]chorus 合唱队

    Description Input Output Sample Input 4 1701 1702 1703 1704 Sample Output 8 HINT Source 因为只会在区间的两端进行 ...