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

【数据结构与算法】Java描述:第六节:排序算法(直接插入排序,希尔排序)

排序算法简单来说就是把一串数据,以想要的顺序排列起来,例如从大到小,从小到大,这篇文章来介绍一下 常见排序算法中的 插入排序算法。

一、关于排序算法

1.1  排序算法的稳定性

排序算法有稳定性这么一个评判标准 ,意思就是说 相同元素 的排序处理上是否保持原始顺序不变。

二、 插入排序

2.1 直接插入排序的思想

直接插入排序的思想 很简单 以从小到大为例:第一个元素 与第二个元素对比,比它大 就交换它们的位置 ,例如我们整理手牌。

2.2 代码解释:

外层循环:遍历数组

  • 循环变量 i:从 1 开始,直到数组末尾 (i < array.length)。

  • 作用:逐个处理未排序的元素。i 表示当前需要插入的元素位置。


内层循环:寻找插入位置

  1. 初始化 jj = i - 1,表示从当前元素的前一个位置开始比较。

  2. 保存当前值tmp = array[i],临时存储待插入的值。

  3. 内层循环条件j >= 0,向前遍历已排序部分。

    • 比较元素:若 array[j] > tmp(当前元素比待插入值大),则将 array[j] 后移到 j+1 的位置,并继续向前比较 (j--)。

    • 找到插入位置:若 array[j] <= tmp,说明 tmp 应插入到 j+1 的位置。此时将 tmp 放入 array[j+1] 并跳出内层循环 (break)。


1. 问题解决:

处理边界情况

  • 所有元素都比 tmp 大:若内层循环未触发 break(所有已排序元素均大于 tmp),则 j 最终变为 -1。此时需要将 tmp 插入到数组开头(array[0])。


变量 j 的变化示例

假设数组为 [5, 3, 1],分析第一次外层循环 (i=1):

  1. 初始状态i=1j=0tmp=3

  2. 内层循环

    • j=0array[0]=5 > 3 → 后移 5 到 j+1,数组变为 [5, 5, 1]j-- → j=-1

  3. 退出内层循环j=-1,执行 array[j+1] = tmp → array[0] = 3,数组变为 [3, 5, 1]


2. 关键点总结

  1. j 的作用:定位 tmp 应插入的位置。内层循环通过递减 j 遍历已排序部分。

  2. array[j+1] = tmp 的冗余性:无论是否触发 break,外层循环都会执行此操作。虽然重复赋值,但结果正确。

  3. 时间空间复杂度

    时间复杂度:O(N^2) 最坏情况下:逆序的 5 4 3 2 1*

    最好情况下:本身就是有序的 1 2 3 4 5 O(n)

    * 如果数据越有序,直接插入排序越快

    * 空间复杂度:O(1)

    * 稳定性:稳定的排序

    public void insertsort(int[] array){
            //i 代表 要交换的数据的下标,i在数组内一直向前遍历数组
            for (int i = 1; i < array.length ; i++) {
    
                int j = i-1;//把 j 放到 i 的左侧
                int tmp = array[i];//存储 要交换的值
    
                for (; j>=0; j--) {
                    //内层循环,可能循环多次,目的是把交换后的数据向前比对。1
                    //如果这个tmp的数据是整个数据最小的,等到 j=-1 ,跳出循环,
                    //使用array[j+1] = tmp; 也就是array[0] = tmp;
                    if(array[j] > tmp){
                        //交换前后数据
                        array[j+1] = array[j];
                    }else {
                        //等到前面的数据不比tmp大了,tmp就固定了
                        array[j+1] = tmp;
                        break;
                    }
                }
              array[j+1] = tmp;    //处理边界问题,如果所有的都比tmp大了,就把当前tmp 放到array[0] 
             }
       }

三、希尔排序

3.1 希尔排序的思路:

希尔排序是对直接插入排序的优化,它的做法是这样的

对一串数据进行分组,像这样分5组的叫 gap = 5,每次对分组内的元素排序,逐渐减小gap,最后gap = 1; 

因为我们 知道 直接插入排序 的 特点 是越有序的数组,排列越快,所以产生了希尔排序。

gap = 2 :

代码演示:

/**
     * 不稳定的
     * 时间复杂度:n^1.3  - n^1.5
     * 空间复杂度:O(1)
     * @param array
     */
    public static void shellSort(int[] array) {
        int gap = array.length;
        while (gap > 1) {
            gap = gap/3+1;//保证了最后一次 gap = 1
            shell(array,gap);
        }
    }

    private static void shell(int[] array, int gap) {
        for (int i = gap; i <array.length ; i++) {
            //i不再从数组第二个开始,而是中间
            int tmp = array[i];
            int j = i - gap;//每隔gap个数据分在一个组内
            for (; j >= 0 ; j-=gap) {//不用细想这句,因为一旦为负,循环进不去,回去
                if(array[j] > array[j+gap]){
                    array[j+gap] = array[j];
                }else {
                    array[j+gap] = tmp;//这句的作用是如果前面比后面的大,
                    // 就保持原来位置,原来数据,不交换
                    break;
                }
            }
            array[j+gap] = tmp;
            //这句的作用是把已经挪动到后面的数据替换成后面那个较小的数据 
            //因为正好跳出j的循环时,j-=gap,所以它一定就是刚刚那个j的位置
            //想不明白就去调试
        }
    }

时间复杂度分析:

     * 不稳定的
     * 时间复杂度:n^1.3  - n^1.5
     * 空间复杂度:O(1)

 

http://www.dtcms.com/a/98355.html

相关文章:

  • 3.29-4nmon
  • Python包管理完全指南:pip常用命令与最佳实践
  • Java项目实现幂等性方案总结
  • CSS3学习教程,从入门到精通, CSS3 盒子模型的详细语法知识点及案例代码(23)
  • Spring AI MCP 架构详解
  • [笔记.AI]向量化
  • Linux系统修改网卡名为eth0、eth1
  • 【CSS】相对位置小练习
  • SQL Server 备份相关信息查看
  • http与tcp的关系
  • 自动化发布工具CI/CD实践Jenkins常用工具和插件的使用
  • 二分查找【看了包会】
  • 线程概念与控制(中)
  • 深度剖析 ansible:从部署基础到模块运用及剧本编写
  • 【算法day25】 最长有效括号——给你一个只包含 ‘(‘ 和 ‘)‘ 的字符串,找出最长有效(格式正确且连续)括号子串的长度。
  • [Raspberry Pi]如何將看門狗(WatchDog)服務建置在樹莓派的Ubuntu作業系統中?
  • 查看openjdk源码
  • TDengine 中的异常恢复
  • 北斗导航 | 基于因子图优化的GNSS/INS组合导航完好性监测算法研究,附matlab代码
  • pyinstaller 对 pyexecjs模块打包老会有终端框闪烁
  • 【学Rust写CAD】18 定点数2D仿射变换矩阵结构体(MatrixFixedPoint结构别名)
  • 基于深度学习的手势识别系统设计
  • 3. 第三放平台部署deepseek
  • 部署堆叠+链路聚合架构,解锁网络高可用新体验
  • AGV-----RCS基础任务发布
  • 22_js运动函数
  • 历史数据分析——宝钢
  • AI赋能单片机开发的环节与方法
  • 观察者模式:解耦对象间的依赖关系
  • 【嵌入式学习3】多任务编程