算法之排序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之间


🟡结语


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

相关文章
|
5月前
|
算法
【算法】二分查找——在排序数组中查找元素的第一个和最后一个位置
【算法】二分查找——在排序数组中查找元素的第一个和最后一个位置
|
2月前
|
搜索推荐 算法 C语言
【排序算法】八大排序(下)(c语言实现)(附源码)
本文继续学习并实现了八大排序算法中的后四种:堆排序、快速排序、归并排序和计数排序。详细介绍了每种排序算法的原理、步骤和代码实现,并通过测试数据展示了它们的性能表现。堆排序利用堆的特性进行排序,快速排序通过递归和多种划分方法实现高效排序,归并排序通过分治法将问题分解后再合并,计数排序则通过统计每个元素的出现次数实现非比较排序。最后,文章还对比了这些排序算法在处理一百万个整形数据时的运行时间,帮助读者了解不同算法的优劣。
142 7
|
2月前
|
搜索推荐 算法 C语言
【排序算法】八大排序(上)(c语言实现)(附源码)
本文介绍了四种常见的排序算法:冒泡排序、选择排序、插入排序和希尔排序。通过具体的代码实现和测试数据,详细解释了每种算法的工作原理和性能特点。冒泡排序通过不断交换相邻元素来排序,选择排序通过选择最小元素进行交换,插入排序通过逐步插入元素到已排序部分,而希尔排序则是插入排序的改进版,通过预排序使数据更接近有序,从而提高效率。文章最后总结了这四种算法的空间和时间复杂度,以及它们的稳定性。
121 8
|
3月前
|
搜索推荐 Shell
解析排序算法:十大排序方法的工作原理与性能比较
解析排序算法:十大排序方法的工作原理与性能比较
89 9
|
3月前
|
算法 搜索推荐 Shell
数据结构与算法学习十二:希尔排序、快速排序(递归、好理解)、归并排序(递归、难理解)
这篇文章介绍了希尔排序、快速排序和归并排序三种排序算法的基本概念、实现思路、代码实现及其测试结果。
44 1
|
3月前
|
算法 搜索推荐 Java
数据结构与算法学习十三:基数排序,以空间换时间的稳定式排序,速度很快。
基数排序是一种稳定的排序算法,通过将数字按位数切割并分配到不同的桶中,以空间换时间的方式实现快速排序,但占用内存较大,不适合含有负数的数组。
42 0
数据结构与算法学习十三:基数排序,以空间换时间的稳定式排序,速度很快。
|
3月前
|
算法
❤️算法笔记❤️-(每日一刷-83、删除排序链表中的重复项)
❤️算法笔记❤️-(每日一刷-83、删除排序链表中的重复项)
36 0
|
3月前
|
存储 算法 搜索推荐
算法进阶之路:Python 归并排序深度剖析,让数据排序变得艺术起来!
算法进阶之路:Python 归并排序深度剖析,让数据排序变得艺术起来!
84 0
|
5月前
|
搜索推荐 算法 Java
现有一个接口DataOperation定义了排序方法sort(int[])和查找方法search(int[],int),已知类QuickSort的quickSort(int[])方法实现了快速排序算法
该博客文章通过UML类图和Java源码示例,展示了如何使用适配器模式将QuickSort类和BinarySearch类的排序和查找功能适配到DataOperation接口中,实现算法的解耦和复用。
57 1
现有一个接口DataOperation定义了排序方法sort(int[])和查找方法search(int[],int),已知类QuickSort的quickSort(int[])方法实现了快速排序算法
|
5月前
|
算法 搜索推荐 Java
算法实战:手写归并排序,让复杂排序变简单!
归并排序是一种基于“分治法”的经典算法,通过递归分割和合并数组,实现O(n log n)的高效排序。本文将通过Java手写代码,详细讲解归并排序的原理及实现,帮助你快速掌握这一实用算法。
51 0

热门文章

最新文章