【数据结构】排序算法---直接插入排序

news2024/9/20 22:36:40

在这里插入图片描述

文章目录

  • 1. 定义
  • 2. 算法步骤
  • 3. 动图演示
  • 4. 性质
  • 5. 算法分析
  • 6. 代码实现
    • C语言
    • Python
    • Java
    • C++
    • Go
  • 7. 折半插入排序
    • 代码实现——C++
  • 结语

1. 定义

直接插入排序是一种简单直观的排序算法。它的工作原理为将待排列元素划分为「已排序」和「未排序」两部分,每次从「未排序的」元素中选择一个插入到「已排序的」元素中的正确位置。

直接插入排序的代码实现虽然没有冒泡排序和选择排序那么简单粗暴,但它的原理应该是最容易理解的了,因为只要打过扑克牌的人都应该能够秒懂。

在这里插入图片描述

直接插入排序和冒泡排序一样,也有一种优化算法,叫做折半插入

2. 算法步骤

一般来说,直接插入排序都采用in-place在数组上实现。具体算法描述如下:

  1. 从第一个元素开始,该元素可以认为已经被排序;

  2. 取出下一个元素,在已经排序的元素序列中从后向前扫描;

  3. 如果该元素(已排序)大于新元素,将该元素移到下一位置;

  4. 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;

  5. 将新元素插入到该位置后;

  6. 重复步骤2~5。

3. 动图演示

在这里插入图片描述

4. 性质

稳定性

直接插入排序是一种稳定的排序算法。

空间复杂度

直接插入排序的空间复杂度为 O ( 1 ) O(1) O(1)

时间复杂度

  • 元素集合越接近有序,直接插入排序算法的时间效率越高。

  • 直接插入排序的最优时间复杂度为 O ( n ) O(n) O(n),在数列几乎有序时效率很高。

  • 直接插入排序的最坏时间复杂度和平均时间复杂度都为 O ( n 2 ) O(n^2) O(n2)

5. 算法分析

直接插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。

6. 代码实现

C语言

void insertion_sort(int arr[], int len){
        int i,j,key;
        for (i=1;i<len;i++){
                key = arr[i];
                j=i-1;
                while((j>=0) && (arr[j]>key)) {
                        arr[j+1] = arr[j];
                        j--;
                }
                arr[j+1] = key;
        }
}

Python

def insertionSort(arr):
    for i in range(len(arr)):
        preIndex = i-1
        current = arr[i]
        while preIndex >= 0 and arr[preIndex] > current:
            arr[preIndex+1] = arr[preIndex]
            preIndex-=1
        arr[preIndex+1] = current
    return arr

Java

public class InsertSort implements IArraySort {

    @Override
    public int[] sort(int[] sourceArray) throws Exception {
        // 对 arr 进行拷贝,不改变参数内容
        int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);

        // 从下标为1的元素开始选择合适的位置插入,因为下标为0的只有一个元素,默认是有序的
        for (int i = 1; i < arr.length; i++) {

            // 记录要插入的数据
            int tmp = arr[i];

            // 从已经排序的序列最右边的开始比较,找到比其小的数
            int j = i;
            while (j > 0 && tmp < arr[j - 1]) {
                arr[j] = arr[j - 1];
                j--;
            }

            // 存在比其小的数,插入
            if (j != i) {
                arr[j] = tmp;
            }

        }
        return arr;
    }
}

C++

void insertion_sort(int arr[],int len){
        for(int i=1;i<len;i++){
                int key=arr[i];
                int j=i-1;
                while((j>=0) && (key<arr[j])){
                        arr[j+1]=arr[j];
                        j--;
                }
                arr[j+1]=key;
        }
}

Go

func insertionSort(arr []int) []int {
        for i := range arr {
                preIndex := i - 1
                current := arr[i]
                for preIndex >= 0 && arr[preIndex] > current {
                        arr[preIndex+1] = arr[preIndex]
                        preIndex -= 1
                }
                arr[preIndex+1] = current
        }
        return arr
}

7. 折半插入排序

直接插入排序还可以通过二分算法优化性能,在排序元素数量较多时优化的效果比较明显。

时间复杂度:

折半插入排序与直接插入排序的基本思想是一致的,折半插入排序仅对插入排序时间复杂度中的常数进行了优化,所以优化后的时间复杂度仍然不变。

代码实现——C++

void insertion_sort(int arr[], int len) {
  if (len < 2) return;
  for (int i = 1; i != len; ++i) {
    int key = arr[i];
    auto index = upper_bound(arr, arr + i, key) - arr;
    // 使用 memmove 移动元素,比使用 for 循环速度更快,时间复杂度仍为 O(n)
    memmove(arr + index + 1, arr + index, (i - index) * sizeof(int));
    arr[index] = key;
  }
}

结语

今天的分享到这里就结束啦!如果觉得文章还不错的话,可以三连支持一下。

也可以点点关注,避免以后找不到我哦!

Crossoads主页还有很多有趣的文章,欢迎小伙伴们前去点评,您的支持就是作者前进的动力!

带你初步了解排序算法:https://blog.csdn.net/2301_80191662/article/details/142211265
直接插入排序:https://blog.csdn.net/2301_80191662/article/details/142300973
希尔排序:https://blog.csdn.net/2301_80191662/article/details/142302553
十大经典排序算法总结与分析:https://blog.csdn.net/2301_80191662/article/details/142211564

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2140477.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PHP Swoole实现简易聊天室,附加小程序端连接websocket简易代码

目录 用到的工具&#xff1a; PHP Swoole拓展 | PHP Redis拓展 | Redis 7 一、安装上述必要工具&#xff08;下面是以宝塔面板中操作为例&#xff09; 给PHP安装Swoole和Redis拓展&#xff1a; 安装Redis软件 二、创建websocket服务器文件"wss_server.php" 具…

node.js+Koa框架+MySQL实现注册登录

完整视频展示&#xff1a;https://item.taobao.com/item.htm?ftt&id831092436619&spma21dvs.23580594.0.0.52de2c1bg9gTfM 效果展示&#xff1a; 一、项目介绍 本项目是基于node.jsKoamysql的注册登录的项目,主要是给才学习node.js和Koa框架的萌新才写的。 二、项目…

java数据结构----图

图的存储结构: 代码实现 public class Graph {// 标记顶点数目private int V;// 标记边数目private int E;// 邻接表private Queue<Integer>[] adj;public Graph(int v) {V v;this.E 0;this.adj new Queue[v];for (int i 0; i < adj.length; i) {adj[i] new Queu…

C++的类与对象中(主讲默认成员函数)

目录 1.类的默认成员函数 2.构造函数 1.全缺省构造函数 2.第7点中的对自定义类型的成员变量构造&#xff08;调用编译器自动生成的默认构造函数&#xff09; 3.析构函数 4.拷贝构造函数 5.运算符重载 1.概念 2.赋值运算符重载 6.const成员函数 1.类的默认成员函数 默…

微服务——网关路由(Spring Cloud Gateway)

网关路由 1.什么是网关 网关又称网间连接器、协议转换器&#xff0c;是在网络层以上实现网络互连的复杂设备&#xff0c;主要用于两个高层协议不同的网络之间的互连。网关就是网络的关口。数据在网络间传输&#xff0c;从一个网络传输到另一网络时就需要经过网关来做数据的路由…

【深度智能】:迈向高级时代的人工智能全景指南

​ ​ 前几天偶然发现了一个超棒的人工智能学习网站&#xff0c;内容通俗易懂&#xff0c;讲解风趣幽默&#xff0c;简直让人欲罢不能。忍不住分享给大家&#xff0c;人工智能立刻跳转&#xff0c;开启你的AI学习之旅吧&#xff01; 第一阶段&#xff1a;基础知识 1. 计算机科…

人脸防伪检测系统源码分享

人脸防伪检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vis…

【Python基础】Python 装饰器(优雅的代码增强工具)

本文收录于 《Python编程入门》专栏&#xff0c;从零基础开始&#xff0c;分享一些Python编程基础知识&#xff0c;欢迎关注&#xff0c;谢谢&#xff01; 文章目录 一、前言二、装饰器基础三、语法糖 四、带参数的装饰器五、多层装饰器六、总结 一、前言 在Python编程的世界里…

【手撕】快排-分治

1. 颜色分类 . - 力扣&#xff08;LeetCode&#xff09;. - 备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/sort-colors/description/ 代码 class Solution {public…

Neo4j入门案例:三星堆

创建一个关于三星堆的知识图谱可以是一个非常有趣的项目&#xff0c;它可以帮助理解如何使用Neo4j来存储和查询复杂的关系数据。三星堆文化以其独特的青铜器、金器和其他文物而闻名&#xff0c;这为我们提供了一个丰富的历史背景来构建知识图谱。 数据模型定义 实体类型&#…

数据安全查询-—SAAS本地化及未来之窗行业应用跨平台架构

一、数据库安全查询 默认数据库查询是不区分大小写的&#xff0c;这样无法区分Mm&#xff0c;Admin&#xff0c;admin 二、thinkphp 区分大小写 $condition "binary appdhj_sn {$应用sn}"; 三、原始mysql select * from TableA where binary columnA aaa; 四、…

mtk7628 网口灯问题

板子上电插入网线到网口&#xff0c;只有wan口灯会亮&#xff0c;插入lan口灯不会亮。对比了ok的代码&#xff0c;先对比设备树&#xff0c;未看到网口相关的GPIO。 mt7628an_WMD-7688A-12816.dts mt7628an_hilink_hlk-7628n.dts 继续查看网口相关代码&#xff0c;加打印&…

Android应用程序启动源码分析

文章目录 Android应用程序启动源码分析一、启动流程二、Launcher通知AndroidOS(用户点击图标)2.1 Activity.java2.2 Instrumentation.java2.3 ActivityTaskManagerService.java2.4 ActivityStarter.java2.5 RootWindowContainer.java2.5.1 Task.java2.5.2 TaskFragment.java 2.…

基于python+django+vue的个性化餐饮管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于pythondjangovueMySQL的视…

勇于尝试,永远行动 - 《洛克菲勒写给儿子的38封信》读书笔记

两倍速听过好几遍的书&#xff0c;洛克菲勒的思想和志向&#xff0c;配得上他的成就。 “在尝试中寻找突破&#xff0c;在行动中成就自我。”这是洛克菲勒写给儿子的箴言&#xff0c;也是他一生的真实写照。在这38封信中&#xff0c;他不仅分享了自己的工作心得&#xff0c;更…

Docker安装mysql安装nginx安装Redis

Docker安装mysql 下载镜像 docker pull mysql:8.0注意,使用此方法安装镜像需要提前配置镜像源,详情看之前的文章 安装 docker run -d -p 3306:3306 \ --name mysql \ --restartalways \ --privilegedtrue \ -e TZAsia/Shanghai \ -e MYSQL_ROOT_PASSWORDroot \ mysql:8.0进…

【重学 MySQL】二十九、函数的理解

【重学 MySQL】二十九、函数的理解 什么是函数不同 DBMS 函数的差异函数名称和参数功能实现数据类型支持性能和优化兼容性和可移植性 MySQL 的内置函数及分类单行函数多行函数&#xff08;聚合函数&#xff09;使用注意事项 什么是函数 函数&#xff08;Function&#xff09;在…

【PHP代码审计】 PHP环境搭建

&#x1f31d;博客主页&#xff1a;泥菩萨 &#x1f496;专栏&#xff1a;Linux探索之旅 | 网络安全的神秘世界 | 专接本 | 每天学会一个渗透测试工具 安装phpstudy 泥菩萨-CSDN博客 安装vscode 直接去官网下载安装包&#xff0c;然后双击安装即可。官网地址&#xff1a;htt…

24/9/15 kaggle数字识别器

这次做的是数字识别器&#xff0c;借鉴了大佬的文章Kaggle竞赛实战系列&#xff08;一&#xff09;&#xff1a;手写数字识别器&#xff08;Digit Recognizer&#xff09;得分99.53&#xff05;、99.91%和100%_手写数字识别实现 digist-CSDN博客 加入了自己对大佬里面步骤的解…

多模态大语言模型综述(中)-算法实用指南

本文是Multimodal Large Language Models: A Survey的译文之算法实用指南部分。 上&#xff1a;摘要、概念与技术要点实用指南中&#xff1a;算法实用指南(本文)下: 任务的实用指南(应用)、挑战等 原始信息 标题: Multimodal Large Language Models: A Survey译文: 多模态大…