java 排序算法之希尔算法

Java排序算法之希尔算法

希尔算法是插入排序的一种优化算法,也叫缩小增量排序。希尔排序的基本思路是将待排序数组元素按下标的一定增量分组,然后将每组分别进行直接插入排序。随着增量逐渐减少,每组包含的元素越来越多,当增量减至1时,整个数组恰被分成一组,此时算法终止。

做法

在希尔排序中,先将待排数组按照一定的增量分割成若干个子序列(下标间隔为增量)分别进行插入排序,然后逐渐减小增量,重复上述过程,直至增量为1(即最后一次按下标相邻的单个元素作为子序列进行插入排序),整个数组排序完成。

下面代码展示了希尔排序的实现:

public static void shellSort(int[] array) {
    int len = array.length;
    int temp, gap = len / 2;
    while (gap > 0) {
        for (int i = gap; i < len; i++) {
            temp = array[i];
            int preIndex = i - gap;
            while (preIndex >= 0 && array[preIndex] > temp) {
                array[preIndex + gap] = array[preIndex];
                preIndex -= gap;
            }
            array[preIndex + gap] = temp;
        }
        gap /= 2;
    }
}

其中len表示待排序数组长度,gap表示增量,每次将gap值减小一半,并进行插入排序。

示例

下面通过两个示例来说明希尔排序的过程:

示例一

假设待排序数组为{2, 5, 1, 9, 4, 6, 7, 3, 8},按照希尔排序的步骤排列如下:

第一次增量为4,将数组分为四组,分别排序:

2 5 1 9 4 6 7 3 8
      ↓
    4 6   8
      ↓
    2 5   1
      ↓
    7 3   9

排列后的数组为{2, 3, 1, 9, 4, 5, 7, 6, 8},此时gap变为2

第二次增量为2,将数组分为两组,分别排序:

2 3 1 9 4 5 7 6 8
    ↓
  1 3   5 6   8 9
    ↓
  2 4   7

排列后的数组为{1, 3, 2, 9, 4, 5, 7, 6, 8},此时gap变为1

第三次增量为1,按插入排序的方法排序,

1 3 2 9 4 5 7 6 8  // 将 1 插入到已排序序列中
1 2 3 9 4 5 7 6 8  // 将 2 插入到已排序序列中
1 2 3 4 9 5 7 6 8  // 将 4 插入到已排序序列中
1 2 3 4 5 9 7 6 8  // 将 5 插入到已排序序列中
1 2 3 4 5 7 9 6 8  // 将 7 插入到已排序序列中
1 2 3 4 5 7 6 9 8  // 将 6 插入到已排序序列中
1 2 3 4 5 7 6 8 9  // 将 8 插入到已排序序列中

排列后的数组为{1, 2, 3, 4, 5, 6, 7, 8, 9},排序完成。

示例二

假设待排序数组为{3, 2, 6, 5, 4, 1, 9, 8, 7},按照希尔排序的步骤排列如下:

第一次增量为4,将数组分为四组,分别排序:

3 2 6 5 4 1 9 8 7
        ↓
      4   7
        ↓
      3   1
        ↓
      9   6
        ↓
      2   5

排列后的数组为{3, 2, 6, 5, 4, 1, 7, 1, 9, 6, 2, 5, 4, 8, 3},此时gap变为2

第二次增量为2,将数组分为两组,分别排序:

3 2 6 5 4 1 7 1 9 6 2 5 4 8 3
    ↓
  6 1   9 5   8 3
    ↓
  3 2   4 1   7 6

排列后的数组为{3, 2, 1, 5, 4, 1, 8, 6, 7, 5, 9, 2, 4, 6, 3},此时gap变为1

第三次增量为1,按插入排序的方法排序,

3 2 1 5 4 1 8 6 7 5 9 2 4 6 3  // 将 2 插入到已排序序列中
2 3 1 5 4 1 8 6 7 5 9 2 4 6 3  // 将 3 插入到已排序序列中
1 2 3 5 4 1 8 6 7 5 9 2 4 6 3  // 将 4 插入到已排序序列中
1 2 3 4 5 1 8 6 7 5 9 2 6 4 3  // 将 1 插入到已排序序列中
1 2 3 4 5 1 8 6 7 5 9 2 6 4 3  // 将 5 插入到已排序序列中
1 2 3 4 1 5 8 6 7 5 9 2 6 4 3  // 将 1 插入到已排序序列中
1 2 3 4 1 5 8 6 7 5 9 2 6 4 3  // 将 8 插入到已排序序列中
1 2 3 4 1 5 6 6 7 5 9 2 8 4 3  // 将 8 插入到已排序序列中
1 2 3 4 1 5 6 6 7 5 9 2 8 4 3  // 将 7 插入到已排序序列中
1 2 3 4 1 5 6 6 5 7 9 2 8 4 3  // 将 5 插入到已排序序列中
1 2 3 4 1 5 6 6 5 7 9 2 8 4 3  // 将 9 插入到已排序序列中
1 2 3 4 1 5 6 6 5 7 2 8 4 3 9  // 将 2 插入到已排序序列中
1 2 3 4 1 5 6 6 5 7 2 8 4 3 9  // 将 6 插入到已排序序列中
1 2 3 4 1 5 2 6 5 7 6 8 4 3 9  // 将 4 插入到已排序序列中
1 2 3 4 1 5 2 6 5 7 6 8 4 3 9  // 将 3 插入到已排序序列中

排列后的数组为{1, 2, 3, 4, 1, 5, 2, 6, 5, 7, 6, 8, 4, 3, 9},排序完成。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java 排序算法之希尔算法 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • Java花式解决’分割回文串 ii’问题详解

    对于Java花式解决’分割回文串 ii’问题详解,我将从以下几个方面进行讲解: 问题描述 解题思路 实现代码 示例说明 1. 问题描述 给定一个字符串s,将s分割成若干个非空回文子串,使得每个子串都是回文串。求最少需要分割几次。 2. 解题思路 本题可以使用动态规划来求解。定义dp[i]表示前缀s[0…i]最少需要切几次,才能满足每个子串都是回文串。那么…

    Java 2023年5月27日
    00
  • Spring集成Mybatis过程详细讲解

    下面就为您详细讲解“Spring集成Mybatis过程详细讲解”的完整攻略。 1. 前置条件 在开始Spring集成Mybatis之前,您需要先安装好以下开发环境: JDK(Java Development Kit):1.8及以上版本 Maven:3.0及以上版本 Spring:5.0及以上版本 Mybatis:3.4及以上版本 2. 创建Maven工程 首…

    Java 2023年5月20日
    00
  • Java 队列实现原理及简单实现代码

    下面就详细讲解“Java队列实现原理及简单实现代码”的完整攻略。 队列基本概念 在讲解队列的实现原理和代码之前,先了解一下队列的基本概念: 队列(Queue)是一种先进先出(FIFO,First In First Out)的数据结构。它可以用链表或数组来实现。队列在计算机中广泛应用,例如在操作系统、网络通信、数据库系统等方面经常被使用。 在队列中,新的元素插…

    Java 2023年5月18日
    00
  • java操作json对象出现StackOverflow错误的问题及解决

    如果你在 Java 中操作 JSON 对象时遇到 StackOverflow 错误,可能是因为实体类中的字段中包含了一个指向同一类型的对象,而这个对象又有一个指向同一类型的对象……以此类推,最终导致了无限循环。这将导致无限递归,直到抛出 StackOverflow 错误。 解决这种情况的最简单方式是使用“@JsonManagedReference”和…

    Java 2023年5月26日
    00
  • Java数组传递及可变参数操作实例详解

    Java数组传递及可变参数操作实例详解 在Java中,数组有时需要被作为参数传递给一个方法或者函数,然后再在该方法或函数中进行使用。另外,有时候我们也需要在参数列表中使用可变参数。本文将详细讲解Java数组传递及可变参数的操作实例。 Java数组传递 Java中的数组是一种引用类型,而非基本数据类型。这意味着,传递数组时,我们实际上传递的是数组引用的副本,而…

    Java 2023年5月26日
    00
  • Spring Boot 使用Druid详解

    Spring Boot使用Druid的详细攻略如下: 添加Druid依赖 在Spring Boot中使用Druid,需要在pom.xml文件中添加Druid的依赖: <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot…

    Java 2023年5月15日
    00
  • JSP针对XML文件操作技巧实例分析

    JSP针对XML文件操作技巧实例分析 简介 JSP是一种动态网页开发技术,它允许将Java代码和特定的标记插入到HTML、XML或其他类型的文档中,从而实现动态内容的生成。XML是一种标记语言,被广泛用于数据存储和传输。JSP可以灵活地处理XML文件,充分发挥它的特点。本文将详细讨论JSP针对XML文件的操作技巧。 XML文件的读取和解析 XML文件由标记和…

    Java 2023年6月15日
    00
  • 详解Java Ajax jsonp 跨域请求

    详解Java Ajax jsonp 跨域请求 什么是跨域请求 在浏览器请求数据时,如果请求的数据地址与原始页面的协议、域名或端口不同,就会发生跨域请求。由于浏览器有同源限制的限制,不同域名之间的请求会受到阻止。 解决方案 为了解决跨域请求的限制,可以使用 jsonp 方式进行异步请求。jsonp通过script标签来获取数据,script标签不受同源限制,因…

    Java 2023年5月26日
    00
合作推广
合作推广
分享本页
返回顶部