算法之排序5——希尔排序

简介: 依次比较待插入元素 i 和分组内另一个元素,就需要用到for循环语句;当h = 5 时,a[5]恰好是数组内第6个元素,也就是第一个待插入的元素,所以初始条件是 i = h,待插入的最后一个元素就是数组内最后一个元素,即终止条件为 i < a.length

🟡前言


21天挑战赛的第五天,本文主要讲述希尔排序,也是插入排序的改良版


活动地址:CSDN21天学习挑战赛


🟡概述


1️⃣排序原理


1.选定一个增长量h,按照增长量h作为数据分组依据,对数组进行分组

2.对每个分好组的进行排序·

3.减少增长量,最小为1,重复第二步

此处组内排序是运用插入排序的方法,而不是单纯的两两交换


2️⃣原理图


e240c7a5064246bca04661717ea38a7d.gif


d037051c5f564bfbb4b4ced67c81f66b.png


第一次将数据分为五组:下标为{0,5},{1、6},{2、7},{3、8},{4、9},然后每组内元素对比,小的在前


第二次将数据分为两组:下标为0、2、4、6、8的一组,下标为1、3、5、7、9的一组然后每组内元素运用插入排序的方法进行排序


第三次就是相邻两两比较,然后排序,即整个数组运用插入排序的方法进行排序


由于此时数组并不是完全混乱的,所以移动的数据量会更少,提高效率


🟡调用API解决


1️⃣构造方法和成员方法

构造方法


Shell()


成员方法


  • public static void sort(Comparable[]a):对数组a中元素进行排序


  • public static boolean greater(Comparable x, Cpmparable y):判断x是否大于y;

一般使用时会这么写:x.compareTo(y) ,再判断值是否 >0 , >0则表示 x>y


  • public static void exch(Comparable[]a, int i, int j):交换数组a中下标为 i 和 j 的元素


2️⃣增长量


一般会取长度的一般,即 h = h / 2


严谨一点应该如下


int N = a.length;
        int h = 1;
        while (h < N/2){
            h = 2 * h + 1;
        }


3️⃣解题思路


1.想要对数组内元素进行排序,就要调用 public static void sort(Comparable[]a)


2.依次比较待插入元素 i 和分组内另一个元素,就需要用到for循环语句;当h = 5 时,a[5]恰好是数组内第6个元素,也就是第一个待插入的元素,所以初始条件是 i = h,待插入的最后一个元素就是数组内最后一个元素,即终止条件为 i < a.length


3.每组比较的元素有个共同特点是:组内后者元素下标 i — 组内前者元素下标 j = h,即 j = i - h,所以这里也要添加一个内循环来找出与待排序元素一组的元素


4.利用插入排序的方法比较组内元素 a[ j - h ] 和 a[ j ] 大小


5.转换成字符串类型后打印输出


4️⃣代码实现


public class ShellSort {
    public static void sort(Comparable[] a){
        int N = a.length;
        int h = 1;
        while (h < N/2){
            h = 2 * h + 1;
        }
        while (h >= 1){
            for(int i = h; i < a.length ; i++){
                for (int j = i; j >=h; j -= h){
                    if(greater(a[j-h],a[j])){
                        exch(a,j-h,j);
                    }
                    else {
                        break;
                    }
                }
            }
        }
    }
    private static boolean greater(Comparable x, Comparable y){
        return x.compareTo(y) > 0;
    }
    private static void exch(Comparable[] a, int i, int j){
        Comparable temp;
        temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }
}
public class ShellSortTest {
    public static void main(String[] args) {
    Integer[] arr = {9,1,2,5,7,4,8,6,3,5};
    ShellSort.sort(arr);
    System.out.println(Arrays.toString(arr));
    }
}

5ae737562fec49afa5876b3e38cd989c.png


🟡空间复杂度


希尔排序的时间复杂度取决于h的取值,不同取值的复杂度不同,所以不展开讲述,其时间复杂度的范围是O(N^(3/2))~n * log2n之间


🟡结语


希尔排序是高级排序的一种,虽然书写代码时是交换数据,但是不能将组内元素排序理解为两两交换,而是组内运用插入排序的算法进行排序

相关文章
|
2月前
|
算法 调度
【软件设计师备考 专题 】算法探索:排序、查找、数值计算和字符串处理(二)
【软件设计师备考 专题 】算法探索:排序、查找、数值计算和字符串处理
32 0
|
2月前
|
算法 搜索推荐 Java
数据结构与算法(Java篇)笔记--希尔排序
数据结构与算法(Java篇)笔记--希尔排序
|
4天前
|
算法 索引
数据结构与算法-排序进阶入门
数据结构与算法-排序进阶入门
7 0
|
19天前
|
人工智能 搜索推荐 Shell
【排序算法】插入排序与希尔排序,你不想知道为什么希尔比插入更快吗?
【排序算法】插入排序与希尔排序,你不想知道为什么希尔比插入更快吗?
|
21天前
|
搜索推荐 算法 Shell
【数据结构与算法】直接插入排序和希尔排序
【数据结构与算法】直接插入排序和希尔排序
|
2月前
|
存储 搜索推荐 算法
【数据结构】八大排序之计数排序算法
【数据结构】八大排序之计数排序算法
12 4
|
2月前
|
搜索推荐 算法
【数据结构】八大排序之归并排序算法
【数据结构】八大排序之归并排序算法
21 5
|
2月前
|
搜索推荐 算法 编译器
【数据结构】八大排序之快速排序算法
【数据结构】八大排序之快速排序算法
37 4
|
2月前
|
搜索推荐 算法
【数据结构】八大排序之简单选择排序算法
【数据结构】八大排序之简单选择排序算法
11 0
|
2月前
|
算法 搜索推荐
【数据结构】八大排序之冒泡排序算法
【数据结构】八大排序之冒泡排序算法
17 1