插入排序:一种简单而有效的排序算法

插入排序:一种简单而有效的排序算法

  • 一、什么是插入排序?
  • 二、插入排序的步骤
  • 三、插入排序的C语言实现
  • 四、插入排序的性能分析
  • 五、插入排序的优化
  • 六、总结

在我们日常生活和工作中,排序是一种非常常见的操作。比如,我们可能需要对一堆无序的文件、一组杂乱的数据或者一堆扑克牌进行排序。在计算机科学中,排序同样是一个核心问题,而插入排序就是解决这一问题的一种基础而有效的方法。

一、什么是插入排序?

插入排序(Insertion Sort)是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。

具体来说,插入排序的工作方式就像我们许多人排序一手扑克牌。开始时,我们的左手为空并且桌子上的牌面向下。然后,我们每次从桌子上拿走一张牌并将它插入左手中正确的位置。为了找到一张牌的正确位置,我们从右到左将它与已在手中的每张牌进行比较。拿在左手上的牌总是排序好的,原来这些牌是桌子上牌堆中顶部的牌。

二、插入排序的步骤

插入排序的基本操作是将一个数据元素插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,算法适用于少量数据的排序,时间复杂度为O(n^2)。是稳定的排序方法。

插入排序的步骤如下:

从第一个元素开始,该元素可以认为已经被排序;
取出下一个元素,在已经排序的元素序列中从后向前扫描;
如果该元素(已排序)大于新元素,将该元素移到下一位置;
重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
将新元素插入到该位置后;
重复步骤2~5。
在这里插入图片描述

三、插入排序的C语言实现

下面是一个简单的插入排序的C语言实现:

c
#include <stdio.h>  
  
void insertionSort(int arr[], int n) {  
    int i, key, j;  
    for (i = 1; i < n; i++) {  
        key = arr[i];  
        j = i - 1;  
  
        /* Move elements of arr[0..i-1], that are  
           greater than key, to one position ahead  
           of their current position */  
        while (j >= 0 && arr[j] > key) {  
            arr[j + 1] = arr[j];  
            j = j - 1;  
        }  
        arr[j + 1] = key;  
    }  
}  
  
/* A utility function to print array of size n */  
void printArray(int arr[], int n) {  
    int i;  
    for (i = 0; i < n; i++)  
        printf("%d ", arr[i]);  
    printf("\n");  
}  
  
/* Test the above functions */  
int main() {  
    int arr[] = {12, 11, 13, 5, 6};  
    int n = sizeof(arr) / sizeof(arr[0]);  
    insertionSort(arr, n);  
    printf("Sorted array: \n");  
    printArray(arr, n);  
    return 0;  
}

在这个例子中,我们首先定义了一个insertionSort函数,它接受一个整数数组arr和数组的长度n作为参数。然后,我们使用一个for循环来遍历数组中的每个元素。对于每个元素,我们将其保存在变量key中,并将j初始化为当前元素的索引减一。然后,我们使用一个while循环来将大于key的元素向后移动一位,直到找到key的正确位置。最后,我们将key插入到正确的位置。

在main函数中,我们定义了一个需要排序的数组arr,并计算了数组的长度n。然后,我们调用insertionSort函数对数组进行排序,并使用printArray函数打印排序后的数组。

四、插入排序的性能分析

插入排序的时间复杂度是O(n2),其中n是待排序元素的数量。在最坏的情况下,即输入序列是逆序的情况下,每次插入都需要移动大量的元素,因此时间复杂度达到O(n2)。然而,在最好的情况下,即输入序列已经是有序的情况下,插入排序的时间复杂度可以降低到O(n)。这是因为在这种情况下,每次插入操作都不需要移动任何元素。

尽管插入排序的时间复杂度相对较高,但它在实际应用中仍然有其价值。特别是当待排序的数据量较小,或者数据部分有序时,插入排序可能比其他更复杂的排序算法更有效。此外,插入排序是一种稳定的排序算法,即相等的元素的顺序在排序后不会改变。这对于某些需要保持相等元素相对顺序的应用场景来说是非常重要的。

五、插入排序的优化

虽然插入排序的基本形式在大多数情况下的性能并不是最优的,但可以通过一些优化手段来提高其效率。

二分插入排序:在基本插入排序中,我们逐个比较和移动元素。而在二分插入排序中,我们使用二分查找来确定新元素应该插入的位置,从而减少比较次数。但是,元素移动的次数仍然是相同的。

希尔排序:也被称为缩小增量排序,是插入排序的一种高效版本。希尔排序首先比较较远的元素,然后逐步减小排序的间隔。当间隔为1时,算法就变成了普通的插入排序。通过这种方式,希尔排序能够在早期阶段消除大量的无序情况,使得后续的插入排序更加高效。

六、总结

插入排序是一种简单直观的排序算法,它通过将未排序的元素插入到已排序的序列中来逐步构建有序序列。虽然它的时间复杂度在最坏情况下是O(n^2),但在数据量较小或数据部分有序时,插入排序可以表现得相当不错。此外,插入排序是稳定的,能够保持相等元素的相对顺序。

通过了解插入排序的工作原理和实现方式,我们可以更好地理解排序算法的基础,并为学习更复杂的排序算法打下坚实的基础。在实际应用中,我们可以根据具体的数据特性和需求来选择合适的排序算法,以达到最优的排序效果。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

B端界面又丑又乱,也不会总结规范,来,我给5个规范模板,照着学

发5个别人总结的规范&#xff0c;一定会对你的B端系统改进&#xff0c;有帮助的。

TSINGSEE青犀AI烟火识别等算法打造电瓶车消防安全解决方案

一、背景分析 根据国家消防救援局的统计&#xff0c;2023年全国共接报电动自行车火灾2.1万起&#xff0c;相比2022年上升17.4%&#xff0c;电动自行车火灾安全隐患问题不容忽视。 电瓶车火情主要问题和原因&#xff1a; 电瓶车/电池质量良莠不齐用户安全意识薄弱&#xff0c…

虚拟机NAT模式配置

注意这里IP要和网关在同一网段&#xff0c;且虚拟机默认网关末尾为.2&#xff08;如果默认网关配置为.1会与宿主机冲突&#xff0c;导致无法ping通外网&#xff09; 点击NAT模式下的NAT设置即可查看默认网关 这里的网关可以理解为主机与虚拟机交互的入口

蓝桥杯算法训练VIP-数组查找及替换

题目 1634: 蓝桥杯算法训练VIP-数组查找及替换 时间限制: 3s 内存限制: 192MB 提交: 1629 解决: 890 题目描述 给定某整数数组和某一整数b。要求删除数组中可以被b整除的所有元素&#xff0c;同时将该数组各元素按从小到大排序。如果数组元素数值在A到Z的ASCII之间&#xff0…

MySQL:SQL优化

1. 插入优化 使用insert语句单条单条数据插入效率偏低&#xff0c;建议使用insert批量插入数据&#xff0c;批量控制在500-1000条数据较为合适&#xff0c;当面对数以百万的数据时&#xff0c;可以使用load指令&#xff0c;提升插入数据效率 相关指令 #客户端连接服务端加上参…

Java后端面试经验分享,~纯分享

本文将从面试、工作、学习三个方面分享最近面试的一些心得以及以后发展的一些规划&#xff0c;仅供参考&#xff0c;哈哈&#xff0c;毕竟本人也很菜&#xff0c;因为菜才要多学习。一会儿也会分享两本Java面试题库&#xff08;题库是b站大学找的&#xff0c;一会儿我也会分享出…

C# Onnx C2PNet 图像去雾 室内场景

目录 介绍 效果 模型信息 项目 代码 下载 C# Onnx C2PNet 图像去雾 室内场景 介绍 github地址&#xff1a;GitHub - YuZheng9/C2PNet: [CVPR 2023] Curricular Contrastive Regularization for Physics-aware Single Image Dehazing [CVPR 2023] Curricular Contrasti…

DataGrip 面试题及答案整理,最新面试题

DataGrip的数据库兼容性和多数据库支持如何实现&#xff1f; DataGrip实现数据库兼容性和多数据库支持的方式包括&#xff1a; 1、广泛的数据库支持&#xff1a; DataGrip支持多种数据库&#xff0c;包括但不限于MySQL, PostgreSQL, SQL Server, Oracle, SQLite, 和MongoDB&a…

C++:类之六脉神剑——默认成员函数

个人主页&#xff1a;日刷百题 系列专栏&#xff1a;〖C/C小游戏〗〖Linux〗〖数据结构〗 〖C语言〗 &#x1f30e;欢迎各位→点赞&#x1f44d;收藏⭐️留言&#x1f4dd; ​ ​ 一、默认成员函数 如果一个类中什么成员都没有&#xff0c;简称为 空类 。 空类中真的什么都…

管理类联考–复试–政治--二十大--记忆宫殿

文章目录 整体记忆宫殿门床头柜床书桌阳台 口诀记忆法 整体 记忆宫殿 要有逻辑的放到房间了 何为逻辑&#xff0c;如下大佬总结的便是&#xff0c;或者可自行总结&#xff0c;有前后顺序&#xff0c;做事逻辑即可 第一步&#xff1a;将逻辑的点放到房间里的点&#xff0c;…

每日OJ题_简单多问题dp⑥_力扣714. 买卖股票的最佳时机含手续费

目录 力扣714. 买卖股票的最佳时机含手续费 状态机分析 解析代码 力扣714. 买卖股票的最佳时机含手续费 714. 买卖股票的最佳时机含手续费 难度 中等 给定一个整数数组 prices&#xff0c;其中 prices[i]表示第 i 天的股票价格 &#xff1b;整数 fee 代表了交易股票的手续…

cannot find -xml2: No such file or directory的解决方法

一&#xff0c;问题现象 在编译库的时候出现如下图所示的报错&#xff1a;C:/msys64/mingw32/bin/…/lib/gcc/i686-w64-mingw32/13.2.0/…/…/…/…/i686-w64-mingw32/bin/ld.exe: ca nnot find -lxml2: No such file or directory collect2.exe: error: ld returned 1 exit s…

spring boot集成redis实现共享存储session

spring boot集成redis实现共享存储session redis实现共享存储session 首先下载redis,我下载的版本是5.0.14,目前官网貌似找不到5.x版本&#xff0c;可以自行去网上寻找。我这里的springboot版本是2.6.4引入redis依赖 <!-- https://mvnrepository.com/artifact/org.spring…

火车订票管理系统|基于springboot框架+ Mysql+Java+B/S结构的火车订票管理系统设计与实现(可运行源码+数据库+设计文档)

推荐阅读100套最新项目 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 目录 前台功能效果图 管理员功能登录前台功能效果图 用户功能模块 系统功能设计 数据库E-R图设计 lunwen…

【已解决】Nginx启动[emerg] bind() to 0.0.0.0:80 failed(98:Address alreadyin use)

原因分析 在Ubuntu系统上启动nginx服务时&#xff0c;出现如下报错&#xff1a; 该错误表明端口 80 已经被其他进程占用&#xff0c;导致 Nginx 无法绑定到该端口上。原因就是系统里面显存一个nginx服务。需要先停下来&#xff0c;才能再次启动服务。 解决步骤 1.执行命名服务…

SpringBoot打造企业级进销存储系统 第五讲

package com.java1234.repository;import com.java1234.entity.Menu; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query;import java.util.List;/*** 菜单Repository接口*/ public interface MenuReposit…

find_package 总结

本文参考&#xff1a;“轻松搞定CMake”系列之find_package用法详解 原理 find_package 即在指定目录CMAKE_MODULE_PATH 或 CMAKE_PREFIX_PATH查找对应的cmake文件。 find 模式 Module模式(默认)&#xff1a;查询Findxxx.cmake配置文件, 在CMAKE_MODULE_PATH 目录Config模式…

安装PYQT5 遇到Microsoft Visual C++ 14.0 is required解决方法

# Time: 2024/03/16 #Author: Xiaohong # 运行环境: OS: Windows 7 旗舰版 # Python: 3.7.9 Pyqt5 # 目的: 解决安装PYQT5 遇到Microsoft Visual C 14.0 is required 1.安装PYQT5时&#xff0c;遇到Microsoft Visual C 14.0 is required&#xff0c;如图 2.查Microsoft…

力扣L13--- 409.最长回文串(JAVA版)-2024年3月1日

1.题目描述 2.知识点 注1&#xff1a;向下取整是将一个数值向下舍入到最接近的整数&#xff0c;但不超过这个数值的整数。具体规则如下&#xff1a; 对于正数&#xff0c;向下取整后得到的整数是不大于原数值的最大整数&#xff1b; 对于负数&#xff0c;向下取整后得到的整数…

STM32基础--使用寄存器点亮流水灯

GPIO 简介 GPIO 是通用输入输出端口的简称&#xff0c;简单来说就是 STM32 可控制的引脚&#xff0c;STM32 芯片的 GPIO 引脚与外部设备连接起来&#xff0c;从而实现与外部通讯、控制以及数据采集的功能。STM32 芯片的 GPIO被分成很多组&#xff0c;每组有 16 个引脚&#xf…