数据结构 | 排序算法总结——(一)直接插入排序(附Java实现代码)

简介: 数据结构 | 排序算法总结——(一)直接插入排序(附Java实现代码)

1.1排序基本概念

排序:重新排列表中的元素,使表中的元素满足按关键字递增或递减的过程。

算法的稳定性:如果待排序表中有两个元素Ri、Rj,其对应的关键字keyi=keyj,且在排序前Ri在Rj前面,如果使用某一排序算法排序后,Ri仍在Rj的前面,则称这个排序算法是稳定的。

分类:在排序过程中,根据数据元素是否完全在内存中,可将排序算法分为两类。

       内部排序:在排序期间元素全部存放在内存中的排序。

外部排序:在排序期间元素无法全部同时存放在内存中,必须在排序过程中根据要求不断地在内外存之间移动的排序。

1.2插入排序

基本思想:每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子序列中,直到全部记录完成。

1.2.1直接插入排序

原理:把n个待排序的元素看成一个有序表和一个无需表,开始的时候有序表只有1个元素,无序表中有n-1个元素每次从无序表中取出第一个元素,将它插入到有序表中,使之成为新的有序表,重复n-1次完成整个排序过程。

具体流程如下:

  1. 首先比较数组的前两个数据,并排序;
  2. 比较第三个元素与前两个排好序的数据,并将第三个元素放入适当的位置;
  3. 比较第四个元素与前三个排好序的数据,并将第四个元素放入适当的位置;
  4. 直至把最后一个元素放入适当的位置
  5. 实例:


0.初始状态 3,1,5,7,2,4,9,6(共8个数)

有序表:3;无序表:1,5,7,2,4,9,6

1.第一次循环,从无序表中取出第一个数 1,把它插入到有序表中,使新的数列依旧有序

有序表:1,3;无序表:5,7,2,4,9,6

2.第二次循环,从无序表中取出第一个数 5,把它插入到有序表中,使新的数列依旧有序

有序表:1,3,5;无序表:7,2,4,9,6

3.第三次循环,从无序表中取出第一个数 7,把它插入到有序表中,使新的数列依旧有序

有序表:1,3,5,7;无序表:2,4,9,6

4.第四次循环,从无序表中取出第一个数 2,把它插入到有序表中,使新的数列依旧有序

有序表:1,2,3,5,7;无序表:4,9,6

5.第五次循环,从无序表中取出第一个数 4,把它插入到有序表中,使新的数列依旧有序

有序表:1,2,3,4,5,7;无序表:9,6

6.第六次循环,从无序表中取出第一个数 9,把它插入到有序表中,使新的数列依旧有序

有序表:1,2,3,4,5,7,9;无序表:6

7.第七次循环,从无序表中取出第一个数 6,把它插入到有序表中,使新的数列依旧有序

有序表:1,2,3,4,5,6,7,9;无序表:(空)

性能分析:

空间效率:仅使用常数个辅助单元,空间复杂度O(1)

时间效率:时间复杂度O(n2)

    最差情况:反序,需要移动n*(n-1)/2个元素,时间复杂度O(n2)

               最好情况:正序,不需要移动元素,时间复杂度O(n)

稳定性:稳定的

适用性:适用于顺序存储和链式存储的线性表

import java.util.Scanner;
import java.util.Arrays;
public class InsertSort {
    public static void insertSort(int[] arr){
        int i=0,j=0,temp=0;//定义变量i,j,temp并初始化
        for (i=1;i<arr.length;i++){//从第二个开始比较
            temp = arr[i];
            for (j=i-1;j>=0;j--){
                if (arr[j]>temp){//如果前面的数大于当前数,将它后移
                    arr[j+1] = arr[j];
                }else {
                    break;
                }
            }
            arr[j+1] = temp;//一轮比较结束,将此轮确定元素放到正确位置
        }
        System.out.println("直接插入排序:"+Arrays.toString(arr));
    }
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);//Scanner工具类键盘输入数据
        while (scanner.hasNext()) {
            int n = scanner.nextInt();
            if (n > 0) {
                int arr[] = new int[n];
                for (int i = 0; i < n; i++) {
                    arr[i] = scanner.nextInt();
                }
                insertSort(arr);//调用直接插入排序insertSort方法
            }
        }
    }
}
相关文章
|
2月前
|
负载均衡 算法 关系型数据库
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
本文聚焦 MySQL 集群架构中的负载均衡算法,阐述其重要性。详细介绍轮询、加权轮询、最少连接、加权最少连接、随机、源地址哈希等常用算法,分析各自优缺点及适用场景。并提供 Java 语言代码实现示例,助力直观理解。文章结构清晰,语言通俗易懂,对理解和应用负载均衡算法具有实用价值和参考价值。
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
|
3月前
|
前端开发 Java
java实现队列数据结构代码详解
本文详细解析了Java中队列数据结构的实现,包括队列的基本概念、应用场景及代码实现。队列是一种遵循“先进先出”原则的线性结构,支持在队尾插入和队头删除操作。文章介绍了顺序队列与链式队列,并重点分析了循环队列的实现方式以解决溢出问题。通过具体代码示例(如`enqueue`入队和`dequeue`出队),展示了队列的操作逻辑,帮助读者深入理解其工作机制。
110 1
|
1月前
|
人工智能 前端开发 Java
Java 面试资料中相关代码使用方法与组件封装方法解析
这是一份详尽的Java面试资料代码指南,涵盖使用方法与组件封装技巧。内容包括环境准备(JDK 8+、Maven/Gradle)、核心类示例(问题管理、学习进度跟踪)、Web应用部署(Spring Boot、前端框架)、单元测试及API封装。通过问题库管理、数据访问组件、学习进度服务和REST接口等模块化设计,帮助开发者高效组织与复用功能,同时支持扩展如用户认证、AI推荐等功能。适用于Java核心技术学习与面试备考,提升编程与设计能力。资源链接:[点此下载](https://pan.quark.cn/s/14fcf913bae6)。
69 6
Java 面试资料中相关代码使用方法与组件封装方法解析
|
26天前
|
Java 调度 流计算
基于Java 17 + Spring Boot 3.2 + Flink 1.18的智慧实验室管理系统核心代码
这是一套基于Java 17、Spring Boot 3.2和Flink 1.18开发的智慧实验室管理系统核心代码。系统涵盖多协议设备接入(支持OPC UA、MQTT等12种工业协议)、实时异常检测(Flink流处理引擎实现设备状态监控)、强化学习调度(Q-Learning算法优化资源分配)、三维可视化(JavaFX与WebGL渲染实验室空间)、微服务架构(Spring Cloud构建分布式体系)及数据湖建设(Spark构建实验室数据仓库)。实际应用中,该系统显著提升了设备调度效率(响应时间从46分钟降至9秒)、设备利用率(从41%提升至89%),并大幅减少实验准备时间和维护成本。
102 0
|
Java
使用Java代码打印log日志
使用Java代码打印log日志
388 1
|
Java BI API
在Java代码中打日志需要注意什么?
日志是什么?日志是你在代码运行时打印出来的一些数据和记录,是快速排查问题的好帮手,是撕逼和甩锅的利器!
766 0
|
缓存 Java 网络架构
别在 Java 代码里乱打日志了,这才是正确的打日志姿势!
别在 Java 代码里乱打日志了,这才是正确的打日志姿势!
202 0
|
Java BI Apache
在Java代码中打日志需要注意什么?
云栖号资讯:【点击查看更多行业资讯】在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来! 为什么要打日志? 日志是什么?日志是你在代码运行时打印出来的一些数据和记录,是快速排查问题的好帮手! 做一件事情之前,先思考为什么。
在Java代码中打日志需要注意什么?
|
缓存 架构师 搜索推荐
别在 Java 代码里乱打日志了,这才是正确的日志打印姿势!
使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一。
|
Java Android开发 C语言
02_JNI中Java代码调用C代码,Android中使用log库打印日志,javah命令的使用,Android.mk文件的编写,交叉编译
 1  编写以下案例(下面的三个按钮都调用了底层的C语言): 项目案例的代码结构如下: 2 编写DataProvider的代码: package com.example.ndkpassdata;   public class DataProvider {         /**      * 计算x和y的加法  apktools      *
1421 0