您现在的位置是:首页 >其他 >数据结构与算法之排序算法-插入排序网站首页其他

数据结构与算法之排序算法-插入排序

爱是小小的癌 2025-04-18 12:01:02
简介数据结构与算法之排序算法-插入排序

排序算法是数据结构与算法中最基本的算法之一,其作用就是将一些可以比较大小的数据进行有规律的排序,而想要实现这种排序就拥有很多种方法~

那么我将通过几篇文章,将排序算法中各种算法细化的,详尽的为大家呈现出来:

📚 非线性时间比较类:

📕 插入类排序:[本篇]

📖 直接插入排序

📖 希尔排序

📕 交换类排序:(博主正在连夜码字中...)

📖 冒泡排序

📖 冒泡排序-优化

📖 快速排序(Hoare,挖坑法,前后指针法)

📖 快速排序-优化

📕 选择类排序:(博主正在连夜码字中...)

📖 简单选择排序

📖 堆排序

📕 归并类排序:(博主正在连夜码字中...)

📖 归并排序

📚 线性时间非比较

📕 非比较类排序:(博主正在连夜码字中...)

📖 计数排序

📖 桶排序

📖 基数排序

一、排序算法

① 排序算法的概念

顾名思义,就是对某一部分可以比较大小的元素进行排序,这就意味着排序不仅仅可以是对数字进行排序,我们也可以对一些自己定义的类进行排序,前提是你已经为它们想好了定义优先级的规则,并且重写了它们的比较方法。

② 排序的额外空间复杂度

额外空间复杂度:是指一个算法在运行的过程中,需要额外存储空间所消耗的内存。

额外空间复杂度为O(1):
想象你在厨房里做菜,只需要一个固定的碗来搅拌食材。无论你做的菜量有多大,你始终只需要这一个碗。这个碗就代表了 O(1) 的额外空间,因为它的大小是固定的,不随菜量的增加而改变。

额外空间复杂度为O(n):
假设你在整理书架,每本书都需要一个书签来标记位置。如果你有 n 本书,你就需要 n 个书签。书签的数量与书的数量成正比,这就是 O(n) 的额外空间复杂度。书越多,需要的书签也越多。

③ 排序的稳定性

排序的稳定性:是指在排序算法的排序过程中,当遇到两个相同值的时候,两者的相对位置是否保持不变。如果两者的相对位置保持不变,那么称这个排序算法是稳定的;反之则不是稳定的。

二、插入排序

① 基本思想

在所有的排序算法中,直接插入排序大概算是最简单易懂的一种排序。

插入排序将传入数据中第一个元素看作有序序列,将剩余的元素看作未排序序列。从未排序序列中的第一个元素开始,依次向后进行查找,并且将该元素插入到一个合适的位置,以升序序列为例,那么这个位置就是(扫描到的元素 <= 该元素)。

就像是打扑克的时候,将一张张没进行排序的牌,依次的插入到合适的位置。

② 直接插入排序

稳定性:稳定

时间复杂度:O(n^2)

额外空间复杂度:O(1)

📚 思路

与上述的插入排序基本思想基本一致。

图示

📖 代码示例

    public static void insertSort(int[] array){
         for(int i = 1;i < array.length;i++){
             for(int j = i;j > 0;j--){
                if(array[j - 1] > array[j]){
                    swap(array,j,j - 1);
                }else {
                    break;
                }
            }
         }
    }
    public static void swap(int[] array,int i,int j){
        int tmp = array[i];
        array[i] = array[j];
        array[j] = tmp;
    }

③ 希尔排序(递减增量排序)

稳定性:不稳定

时间复杂度:O(nlog^2 n) [最坏为O(n^2)]

额外空间复杂度:O(1)

📚 思路

希尔排序,也叫做递减增量排序,它是直接插入排序的一种优化版本,它的效率更高,但是缺点是希尔排序不再拥有稳定性。

希尔排序对插入排序的优化是因为:插入排序由于每次只能移动一位数据,所以效率并不高。

希尔排序的基本思想先选定一个整数,将待排序的数据按照一个距离 k 将数组分为若干个子序列,并且按照 k 为每次的移动量进行直接插入排序,当这次通过 k 选取出的若干序列都已有序时,再缩小 k 重新进行上述排序。

注:一般来说,k 取数组长度 / 2,之后的缩小也是不断 / 2。 

图示

📖 代码示例

    public static void shellSort(int[] array) {
        int k = array.length / 2;
        int len = array.length;
        while(k > 0) {
            for (int i = 0; i < len; i++) {
                for(int j = i + k;j >= k && j < len; j -= k){
                    if(array[j - k] > array[j]){
                        swap(array,j,j - k);
                    }else {
                        break;
                    }
                }
            }
            k /= 2;
        }
    }
    private static void swap(int[] array, int i, int j) {
        int tmp = array[i];
        array[i] = array[j];
        array[j] = tmp;
    }

使用希尔排序就能够对排序效率大大的优化,这是因为每完成一趟排序,就能够使整个数组变得更趋近于一个有序的数组,而插入排序处理越趋近于有序的数组,效率也就越高~

912. 排序数组 - 力扣(LeetCode)

我们可以通过这个题来对实现的排序算法来检验正确性,并且还能够查看出算法的效率如何:

使用直接插入排序

这边就可以看到,超时了。

使用希尔排序

使用希尔排序优化一下插入排序,就成功通过啦~

那么这篇文章到这里就结束啦,作者能力有限,如果有哪里说的不够清楚或者不够准确,还请各位在评论区多多指出,我也会虚心学习的,我们下次再见啦

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。