当前位置: 首页 > article >正文

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

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

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

📚 非线性时间比较类:

📕 插入类排序:[本篇]

📖 直接插入排序

📖 希尔排序

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

📖 冒泡排序

📖 冒泡排序-优化

📖 快速排序(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)

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

使用直接插入排序

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

使用希尔排序

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

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


http://www.kler.cn/a/540189.html

相关文章:

  • Centos Ollama + Deepseek-r1+Chatbox运行环境搭建
  • Django操作指令大集合说明
  • 信息科技伦理与道德3-2:智能决策
  • 网络防御高级02-综合实验
  • C++11新特性之unique_ptr智能指针
  • 大数据项目2a:基于spark的电影推荐和分析系统设计与实现
  • 【合集】Java进阶——Java深入学习的笔记汇总 amp; 再论面向对象、数据结构和算法、JVM底层、多线程
  • ZooKeeper选举机制详解
  • C++20新特性
  • Spring Boot中使用Thymeleaf的详细指南
  • 安卓开发,底部导航栏
  • 解决windows wsl2+Ubuntu中没有网络问题
  • HarmonyOS:时间日期国际化
  • 组件库选择:ElementUI 还是 Ant Design
  • STC51 P0 口 与P1 口输出
  • Linux TCP 编程详解与实例
  • json转typescript在线工具
  • webpack配置之---output.chunkFormat
  • [权限提升] Linux 提权 维持 — 系统错误配置提权 - 明文 ROOT 密码提权
  • Websocket从原理到实战
  • 大模型Prompt 提示词攻击,大语言模型安全的潜在威胁
  • 深入解析:Java中如何使用Redis存储购物车信息?
  • Deepseek使用途径以及Prompt 提示词编写原理
  • 【漫话机器学习系列】087.常见的神经网络最优化算法(Common Optimizers Of Neural Nets)
  • Kokoro 开源文本转语音引擎上线!多语言支持,无需联网,浏览器内极速运行
  • java项目之美妆产品进销存管理系统的设计与开发源码(ssm+mysql)