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

排序算法 -插入排序

文章目录

  • 1.插入排序(Insertion Sort)
    • 1.1 简介
    • 1.2 插入排序的步骤
    • 1.3 插入排序的C实现
    • 1.4 插入排序的时间复杂度
    • 1.5 插入排序的空间复杂度
    • 1.6 插入排序的动画
  • 2. 二分插入排序(Binary Insertion Sort)
    • 2.1 简介
    • 2.2 二分插入排序步骤
    • 2.3 二分插入排序C语言实现
    • 2.4 二分插入排序的时间复杂度
    • 2.5 二分插入排序的时间复杂度

1.插入排序(Insertion Sort)

1.1 简介

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

1.2 插入排序的步骤

  1. 初始状态:假设第一个元素已经排序(即长度为1的数组是有序的)。
  2. 遍历未排序部分:从第二个元素开始,依次取出每一个元素。
  3. 插入元素
    • 将已取出的元素(记为key)与已排序部分的元素从后向前比较。
    • 如果已排序部分的元素大于key,则将该元素向后移动一位。
    • 重复上述步骤,直到找到key的合适位置,将其插入。
  4. 重复:重复步骤2和3,直到所有元素均已排序。

1.3 插入排序的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;// 将arr[i]插入到已排序的arr[0..i-1]部分while (j >= 0 && arr[j] > key) {arr[j + 1] = arr[j];j = j - 1;}arr[j + 1] = key;}
}// 打印数组函数
void printArray(int arr[], int size) {int i;for (i = 0; i < size; i++)printf("%d ", arr[i]);printf("\n");
}// 主函数
int main() {int arr[] = {12, 11, 13, 5, 6};int n = sizeof(arr) / sizeof(arr[0]);printf("排序前的数组: \n");printArray(arr, n);insertionSort(arr, n);printf("排序后的数组: \n");printArray(arr, n);return 0;
}

1.4 插入排序的时间复杂度

  • 最佳情况:O(n)(数组已经是有序的)
  • 最坏情况:O(n2)(数组是逆序的)
  • 平均情况:O(n2)

1.5 插入排序的空间复杂度

  • 插入排序是in-place排序算法,因此其空间复杂度为O(1)。

1.6 插入排序的动画

Insertion Sort

2. 二分插入排序(Binary Insertion Sort)

2.1 简介

它通过引入二分查找(Binary Search)算法来优化查找插入位置的过程。在标准的插入排序中,为了将当前元素插入到已排序部分的正确位置,算法需要从后向前扫描已排序部分,直到找到比当前元素大的第一个元素或到达数组的开头。

2.2 二分插入排序步骤

  1. 从数组的第二个元素开始,将每个元素视为待插入元素。
  2. 使用二分查找算法在已排序部分中查找待插入元素的正确位置。
  3. 将已排序部分中大于待插入元素的元素向后移动一位,以腾出空间。
  4. 将待插入元素插入到正确位置。
  5. 重复步骤1-4,直到数组完全排序。

2.3 二分插入排序C语言实现


#include <stdio.h>// 二分查找函数,返回插入位置的前一个索引
int binarySearch(int arr[], int item, int low, int high) {if (high <= low)return (item > arr[low]) ? (low + 1) : low;int mid = (low + high) / 2;if (item == arr[mid])return mid + 1;if (item > arr[mid])return binarySearch(arr, item, mid + 1, high);return binarySearch(arr, item, low, mid - 1);
}// 二分插入排序函数
void binaryInsertionSort(int arr[], int n) {int i, j, key, loc;for (i = 1; i < n; i++) {key = arr[i];// 使用二分查找找到插入位置loc = binarySearch(arr, key, 0, i - 1);// 移动元素以腾出空间for (j = i - 1; j >= loc; j--) {arr[j + 1] = arr[j];}arr[loc] = key;}
}// 打印数组函数
void printArray(int arr[], int size) {int i;for (i = 0; i < size; i++)printf("%d ", arr[i]);printf("\n");
}// 主函数
int main() {int arr[] = {37, 23, 0, 17, 12, 72, 31, 46, 100, 88, 54};int n = sizeof(arr) / sizeof(arr[0]);printf("排序前的数组: \n");printArray(arr, n);binaryInsertionSort(arr, n);printf("排序后的数组: \n");printArray(arr, n);return 0;
}

二分插入排序的时间和空间复杂度分析如下:

2.4 二分插入排序的时间复杂度

二分插入排序的时间复杂度主要由两部分组成:二分查找和元素移动。

  1. 二分查找:在每次插入时,使用二分查找来确定插入位置。二分查找的时间复杂度是对数级别的,即O(log n),其中n是已排序部分的长度。然而,需要注意的是,这里的n并不是整个数组的长度,而是已排序部分的长度。在插入排序的过程中,已排序部分的长度是逐渐增加的。
  2. 元素移动:当找到插入位置后,需要将该位置及其之后的元素向后移动一位,以腾出空间插入新元素。这个过程的时间复杂度是线性的,即O(n),其中n是已排序部分的长度(在插入当前元素之前的长度)。在最坏情况下,当前元素可能需要被插入到已排序部分的开头,导致所有已排序的元素都需要向后移动一位。

由于二分插入排序在每次插入时都需要进行二分查找和元素移动,因此其总体时间复杂度仍然是O(n2)。这是因为,虽然二分查找减少了比较次数,但元素移动的次数并没有减少。在插入n个元素的过程中,每个元素都可能需要进行O(n)次的移动(在最坏情况下),因此总的时间复杂度是O(n2)。

2.5 二分插入排序的时间复杂度

二分插入排序是就地排序算法(in-place sorting algorithm),它不需要额外的存储空间来存储中间结果。算法在排序过程中只需要几个额外的变量来存储临时值和索引,因此其空间复杂度是O(1)。

综上所述,二分插入排序的时间复杂度是O(n2),空间复杂度是O(1)。这些复杂度特性使得二分插入排序在处理小规模数据集或几乎已排序的数据集时可能表现出较好的性能,但在处理大规模数据集时则不是最优选择。

相关文章:

排序算法 -插入排序

文章目录 1.插入排序&#xff08;Insertion Sort&#xff09;1.1 简介1.2 插入排序的步骤1.3 插入排序的C实现1.4 插入排序的时间复杂度1.5 插入排序的空间复杂度1.6 插入排序的动画 2. 二分插入排序&#xff08;Binary Insertion Sort&#xff09;2.1 简介2.2 二分插入排序步骤…...

如何使用.bat实现电脑自动重启?

1、在电脑桌面新建一个记事本文档&#xff0c;将如下内容写进去&#xff1a; echo off shutdown /r /t 02、然后&#xff0c;保存一下&#xff0c;再把桌面此文件重命名为电脑重启.bat 3、双击此程序&#xff0c;可以立刻重启电脑。 PS&#xff1a;① 此程序会不保存任何当前…...

使用VSCode远程连接服务器并解决Neo4j无法登陆问题

摘要&#xff1a;本文介绍了如何通过VSCode连接内网部署的Neo4j服务器&#xff0c;并启动服务。在访问Neo4j登录界面时&#xff0c;遇到了端口映射问题导致无法登录。通过手动添加7687端口的映射后&#xff0c;成功登录Neo4j。 我在内网部署了一台服务器&#xff0c;并在其上运…...

使用React和Vite构建一个AirBnb Experiences克隆网站

这一篇文章中&#xff0c;我会教你如何做一个AirBnb Experiences的克隆网站。主要涵盖React中Props的使用。 克隆网站最终呈现的效果&#xff1a; 1. 使用vite构建基础框架 npm create vitelatestcd airbnb-project npm install npm run dev2. 构建网站的3个部分 网站从上…...

HBase压测 ycsb

## ycsb 导入数据 rootXX.14.40.1971、对portrait压测 ansible hadoop -i hosts_hbase_portrait_20230730.txt -m shell -a "hostname && chdir/data/workspace/ycsb-0.17.0 nohup bin/ycsb load hbase20 -P workloads/workload_insert -cp /usr/local/fqlhadoop/…...

基于Python+Django+Vue3+MySQL实现的前后端分类的商场车辆管理系统

项目名称&#xff1a;基于PythonDjangoVue3MySQL实现的前后端分离商场车辆管理系统 技术栈 开发工具&#xff1a;PyCharm、Visual Studio Code (VSCode)运行环境&#xff1a;Python 3.10、MySQL 8.0、Node.js 18技术框架&#xff1a;Django 5、Vue 3.4、Ant-Design-Vue 4.12 …...

网络安全web基础_HTML基础(扫盲篇)

web基础_HTML扫盲篇 一、什么是 HTML&#xff1f; 二、HTML 的基本特点 三、HTML 基本结构概述 1.文档声明&#xff08;!DOCTYPE html&#xff09; 2. html元素 3. head元素 4. body 元素 四、HTML5的主要标签清单 文档结构标签 文本内容标签 链接和锚点标签 表格标…...

(附项目源码)Java开发语言,监督管家APP的设计与实现 58,计算机毕设程序开发+文案(LW+PPT)

摘要 随着互联网的快速发展和智能手机的普及&#xff0c;越来越多的用户选择通过移动应用程序进行事项设定、提醒通知和事项打卡。监督管家APP作为一个专注于事项设定、提醒通知、事项打卡的监督管理平台&#xff0c;具有广泛的应用前景和商业价值。本研究旨在构建一个功能丰富…...

前端基础的讲解-JS(11)

对象 对象是什么&#xff1f; 在 JavaScript 中&#xff0c;对象是一组无序的相关属性和方法的集合&#xff0c;所有的事物都是对象&#xff0c;所有的数据类型都可以存放在内。 属性&#xff1a;即事物的特征&#xff0c;在对象中用属性来表示&#xff08;常用名词&#xf…...

Python魔法方法深度解析:解密__call__、__new__和__del__的核心奥义

解锁Python编程的无限可能&#xff1a;《奇妙的Python》带你漫游代码世界 《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门&#xff01; Python中的魔法方法&#xff08;Magic Methods&#xff09;是构建Python高级功能的基础&#xff0c;它们使得对象可以…...

当微软windows的记事本被AI加持

1985年&#xff0c;微软发布了Windows 1.0&#xff0c;推出了一款革命性的产品&#xff1a;记事本&#xff08;Notepad&#xff09;。这款软件旨在鼓励使用一种未来主义的新设备——鼠标&#xff0c;并让人们可以不依赖VI等键盘工具就能书写文本和编写代码。记事本因其简洁和高…...

Python酷库之旅-第三方库Pandas(213)

目录 一、用法精讲 996、pandas.DatetimeIndex.day属性 996-1、语法 996-2、参数 996-3、功能 996-4、返回值 996-5、说明 996-6、用法 996-6-1、数据准备 996-6-2、代码示例 996-6-3、结果输出 997、pandas.DatetimeIndex.hour属性 997-1、语法 997-2、参数 99…...

普林斯顿:LLM基于边际优化的梯度纠缠

&#x1f4d6;标题&#xff1a;A Common Pitfall of Margin-based Language Model Alignment: Gradient Entanglement &#x1f310;来源&#xff1a;arXiv, 2410.13828 &#x1f31f;摘要 &#x1f538;从人类反馈中强化学习&#xff08;RLHF&#xff09;已成为对齐语言模型…...

通俗易懂:什么是 Java 类加载?

文章目录 类加载过程的三个阶段一个简单的案例&#xff1a;类加载的工作原理使用这个类类加载的顺序类加载的特点类加载的好处总结推荐阅读文章 在 Java 中&#xff0c; 类加载是一种将我们写的 Java 类文件加载到内存中的过程&#xff0c;让 JVM&#xff08;Java 虚拟机&…...

Dijkstra 算法的实现方案

下面是一个基于 Dijkstra 算法的实现方案,能够在 DEM(数字高程模型)数据上进行寻路,并满足以下需求: 使用 Qt C++ 编写; 规避 DEM 中的障碍物; 支持指定起点和终点; 使用 GDAL 库读取 DEM 文件; 输出路径到 TXT 文件; 输出的坐标为地理坐标(例如经纬度),而不是像…...

OpenGL 进阶系列07 - 阴影贴图(shadowmap )

一:概述: 在 OpenGL 中,Shadow Mapping(阴影贴图)是一种常用的实时阴影技术,用于渲染物体的阴影效果。这种方法通过生成光源视角下的深度贴图,再在场景渲染时使用它来判断物体是否被遮挡,从而实现阴影效果。下面是实现 Shadow Mapping 的基本步骤和相关知识。 二:绘制…...

【CAN介绍】【第一篇章】

1. CAN简介 • CAN 总线&#xff08; Controller Area Network Bus &#xff09;控制器局域网总线 • CAN 总线是由 BOSCH 公司开发的一种简洁易用、传输速度快、易扩展、可靠性高的串行通信总线&#xff0c;广泛应用于汽车、嵌入式、工业控制等领域 • CAN 总线特征&#xff1…...

【统计子矩阵——部分前缀和+双指针】

题目 代码 #include <bits/stdc.h> using namespace std; typedef long long ll; const int N 510; int s[N][N]; int main() {ios::sync_with_stdio(0);cin.tie(0);int n, m, k;cin >> n >> m >> k;for(int i 1; i < n; i)for(int j 1; j <…...

用正则表达式检查是IP否为内网地址

用正则表达式检查是ip否为内网地址 PHP function isIntranet($ip) {/* IPV4内网地址A 类10.0.0.0&#xff5e;10.255.255.255B 类172.16.0.0&#xff5e;172.31.255.255C 类192.168.0.0&#xff5e;192.168.255.255*/// 检查是否为 IPv4 内网地址if (preg_match(/^10\./, $ip…...

Leetcode刷题笔记14

136. 只出现一次的数字 136. 只出现一次的数字 - 力扣&#xff08;LeetCode&#xff09; 核心思想&#xff1a;按位异或运算 利用按位异或运算的性质来解决这个问题&#xff1a; 异或运算的性质&#xff1a; a ^ a 0&#xff1a;相同的数异或结果为0。 a ^ 0 a&#xff1a…...

Chapter03-Authentication vulnerabilities

文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

Java 语言特性(面试系列1)

一、面向对象编程 1. 封装&#xff08;Encapsulation&#xff09; 定义&#xff1a;将数据&#xff08;属性&#xff09;和操作数据的方法绑定在一起&#xff0c;通过访问控制符&#xff08;private、protected、public&#xff09;隐藏内部实现细节。示例&#xff1a; public …...

SciencePlots——绘制论文中的图片

文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了&#xff1a;一行…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

vscode(仍待补充)

写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh&#xff1f; debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

spring:实例工厂方法获取bean

spring处理使用静态工厂方法获取bean实例&#xff0c;也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下&#xff1a; 定义实例工厂类&#xff08;Java代码&#xff09;&#xff0c;定义实例工厂&#xff08;xml&#xff09;&#xff0c;定义调用实例工厂&#xff…...

【python异步多线程】异步多线程爬虫代码示例

claude生成的python多线程、异步代码示例&#xff0c;模拟20个网页的爬取&#xff0c;每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程&#xff1a;允许程序同时执行多个任务&#xff0c;提高IO密集型任务&#xff08;如网络请求&#xff09;的效率…...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...

Python ROS2【机器人中间件框架】 简介

销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...