数据结构的直接插入排序(C语言版)

一.直接插入排序的基本概念

1.直接插入排序的基本思想

  1. 将数组分为已排序和未排序两部分。

  2. 每次从未排序部分取出一个元素,将其插入到已排序部分的合适位置,使得已排序部分保持有序。

  3. 重复步骤2,直到整个数组有序。

2.排序的工作原理

  1. 假设前 i-1 个元素已经有序,现在要将第 i 个元素插入到前 i-1 个有序元素中,使得前 i 个元素也有序。

  2. 为了插入第 i 个元素,需要先找到它在前 i-1 个元素中的适当位置。可以从右到左依次与前面的元素比较,找到第一个小于第 i 个元素的位置。

  3. 找到合适的位置后,将第 i 个元素插入到该位置,同时需要将位置之后的元素都向后移动一位。

  4. 重复步骤 1-3, 直到整个数组有序。

3.排序的优点

  1. 实现简单,编码容易。

  2. 对于部分有序的数组,直接插入排序的效率很高。

  3. 是一种稳定的排序算法,即相等元素的相对位置不会改变。

  4. 在数组规模较小时,直接插入排序的性能优于其他更复杂的排序算法。

4.排序的缺点

  1. 时间复杂度为O(n^2),在数据量较大时效率较低。

  2. 需要在数组中进行大量的数据移动操作,效率较低。

  3. 不适合于元素数量较大的数组排序。如果待排序数组基本有序,直接插入排序的效率会很高,但如果数组越乱,排序效率就会越低。

  4. 无法利用cpu的缓存机制,对于大规模数据排序,其性能会明显低于其他排序算法。

5.直接插入排序的功能

  1. 将无序数组或部分有序数组排列成升序序列。

  2. 维护数组中元素的相对顺序,即相等元素的相对位置不会改变。这使得直接插入排序是一种稳定的排序算法。

  3. 适用于小规模数据的排序,当数组规模较小时它的性能比较优秀。

  4. 对于部分有序的数组,直接插入排序的效率会很高,因为需要移动的元素较少。

  5. 可以改写为降序排序,只需要在插入时改为从后向前比较并插入即可。

  6. 可以作为其他排序算法的基础,如希尔排序就是基于直接插入排序改进而来的。

二.直接插入排序的代码实现

                              

void insertionSort(int arr[], int n) {
    int i, j, key;
    for (i = 1; i < n; i++) {
        key = arr[i];
        j = i - 1;

        /* 将key插入到已排序的数组中 */
        while (j >= 0 && arr[j] > key) {
            arr[j + 1] = arr[j];
            j = j - 1;
        }
        arr[j + 1] = key;
    }
}

1.直接插入排序算法的工作原理

  1. insertionSort(int arr[], int n) 函数是直接插入排序的实现。它接受一个整型数组 arr 和数组长度 n 作为参数。

  2. 外层 for 循环从下标为 1 的元素开始遍历数组。这是因为下标为 0 的元素可以认为是一个已排序的子数组。

  3. 在每次外层循环迭代中:

    • 将当前元素 arr[i] 保存到变量 key 中。
    • 将当前元素的前一个下标 i-1 赋给变量 j。这个变量用于在已排序的子数组中找到 key 的插入位置。
  4. 内层 while 循环用于在已排序的子数组中找到 key 的插入位置。循环条件是 j >= 0 && arr[j] > key,即只要 j 不越界且 arr[j] 大于 key,就一直执行循环体。

  5. 在内层循环中:

    • 将 arr[j] 向后移动一位,赋值给 arr[j+1]。这相当于为 key 腾出一个位置。
    • 将 j 减1,继续向前检查已排序的子数组。
  6. 当内层循环结束时,也就找到了 key 的合适插入位置 j+1。此时将 key 赋值给 arr[j+1],完成了插入操作。

  7. main() 函数中创建了一个示例数组 arr,并调用 insertionSort() 函数对其进行排序。

  8. 最后,分别打印排序前后的数组。

2.算法的工作过程

  1. 将数组分为已排序和未排序两部分。
  2. 每次从未排序部分取出一个元素 key
  3. 在已排序部分中找到 key 的合适插入位置。
  4. 将 key 插入到找到的位置,完成一次插入排序。
  5. 重复步骤2-4,直到整个数组有序。

三.直接插入排序的源代码

1.insertionSort(int arr[], int n) 函数

  • 接受一个整型数组 arr 和数组长度 n 作为输入参数。
  • 实现直接插入排序算法,将数组 arr 按升序排列。

2.算法步骤

  • 从数组的第二个元素开始遍历 (i = 1n-1).
  • 对于当前元素 arr[i], 将其保存在变量 key 中.
  • 设置一个指针 j 指向当前元素的前一个位置 (j = i-1).
  • 从 j 开始向前遍历已排序子数组, 将大于 key 的元素都向后移动一位 (while (j >= 0 && arr[j] > key)).
  • 找到 key 的正确插入位置后, 将 key 插入到该位置 (arr[j+1] = key).

3.main() 函数

  • 定义一个整型数组 arr 并计算其长度 n.
  • 打印原始数组.
  • 调用 insertionSort() 函数对数组进行排序.
  • 打印排序后的数组.

通过这段代码,我们可以看到直接插入排序的具体实现过程。它将数组分为已排序和未排序两部分,并且每次从未排序部分取出一个元素,找到它在已排序部分的正确位置并插入。这种简单高效的排序方法在小规模数据和部分有序数组中表现出色。

#include <stdio.h>

void insertionSort(int arr[], int n) {
    int i, j, key;
    for (i = 1; i < n; i++) {
        key = arr[i];
        j = i - 1;

        /* 将key插入到已排序的数组中 */
        while (j >= 0 && arr[j] > key) {
            arr[j + 1] = arr[j];
            j = j - 1;
        }
        arr[j + 1] = key;
    }
}

int main() {
    int arr[] = {64, 25, 12, 22, 11};
    int n = sizeof(arr) / sizeof(arr[0]);
    
    printf("原始数组: ");
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    insertionSort(arr, n);

    printf("排序后的数组: ");
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    return 0;
}

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

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

相关文章

基于微信小程序+ JAVA后端实现的【医院挂号预约系统】 设计与实现 (内附设计LW + PPT+ 源码+ 演示视频 下载)

项目名称 项目名称&#xff1a; 《基于微信小程序的医院挂号预约系统设计与实现》 项目技术栈 该项目采用了以下核心技术栈&#xff1a; 后端框架/库&#xff1a; Java, SSM框架数据库&#xff1a; MySQL前端技术&#xff1a; 微信小程序, uni-app 项目展示 全文概括 本…

Linux_应用篇(09) 进程

本章将讨论进程相关的知识内容&#xff0c; 虽然在前面章节内容已经多次向大家提到了进程这个概念&#xff0c;但并未真正地向大家解释这个概念&#xff1b;在本章&#xff0c;我们将一起来学习 Linux 下进程相关的知识内容&#xff0c;虽然进程的基本概念比较简单&#xff0c;…

Tensors张量操作

定义Tensor 下面是一个常见的tensor&#xff0c;包含了里面的数值&#xff0c;属性&#xff0c;以及存储位置 tensor([[0.3565&#xff0c;0.1826&#xff0c;0.6719],[0.6695&#xff0c;0.5364&#xff0c;0.7057]]&#xff0c;dtypetorch.float32,devicecuda:0)Tensor的属…

【动态规划】零基础解决路径问题(C++)

目录 62.路径问题 解法&#xff08;动态规划&#xff09;&#xff1a; 1. 状态表⽰&#xff1a; 2. 状态转移⽅程&#xff1a; 3. 初始化&#xff1a; 4. 填表顺序&#xff1a; 5. 返回值&#xff1a; 不同路径2.0 解法&#xff08;动态规划&#xff09;&#xff1a; …

LLM中的RoPE位置编码代码解析与RoPE的性质分析(一)

本博客需要对位置编码有一定了解&#xff0c;但不熟悉代码实现的老哥看。 正弦位置编码&#xff08;sinusoidal&#xff09; 在介绍RoPE之前&#xff0c;先回顾一下正弦位置编码。 数学表达 P E ( p o s , 2 i ) s i n ( p o s 1000 0 2 i / d m o d e l ) PE(pos, 2i) sin…

行转列——kettle开发14

一、行转列 如图所示&#xff0c;行转列就是把数据字段的字段名转换为一列&#xff0c;把数据行变成数据列。即我们将昨天输出的张三在周一至周日的工作小时转换为7行数据。对应7行数据分别为张三在周一工作多个小时&#xff0c;在周二工作多少个小时等等。 我们来看下行转列组…

怎么设置电脑锁屏密码?一键给你的电脑“上锁”

在保护个人电脑安全方面&#xff0c;设置锁屏密码是一种简单而有效的方法。无论是在家里还是在公共场所&#xff0c;锁屏密码都可以有效防止他人未经授权访问您的电脑&#xff0c;保护您的隐私和数据安全。 然而&#xff0c;对于一些新手用户来说&#xff0c;怎么设置电脑锁屏…

期货学习笔记-横盘行情学习1

横盘行情的特征及分类 横盘行情的概念 横盘行情时中继形态的一种&#xff0c;一般常出现在大涨或大跌之后出现横盘行情是对当前趋势行情的修正&#xff0c;是对市场零散筹码的清理&#xff0c;是为了集中筹码更便于后期行情的展开 横盘行情的特征 1.水平运动&#xff1a;该…

Java基础-反射原理

总结放前面&#xff1a; 反射是可以通过一个类对象或类名称获取到该类的全部信息&#xff08;属性和方法&#xff09;&#xff0c;包括为权限为private。 要使用反射第一步&#xff0c;要获取的类的Class对象&#xff0c;该Class对象存放在堆区&#xff0c;于类加载时创建&…

互联网政务应用安全管理规定:使用安全连接方式访问

前几日&#xff0c;由中央网络安全和信息化委员会办公室、中央机构编制委员会办公室、工业和信息化部、公安部等4部门联合制定的《互联网政务应用安全管理规定》&#xff08;以下简称规定&#xff09;发布了&#xff0c;规定定义了互联网政务应用&#xff0c;也对互联网政务应用…

[GDB] GDB调试

目录 一 简介 二 功能: 三 命令: 四 调试准备: 五 开始调试: 5.1 添加断点&#xff1a; 5.2 条件编译 5.3 断点查看 5.4 断点删除: 5.5 查看源码 5.6 单步调试(逐过程)&#xff1a; 5.7 断点调试: 5.8 单步跟踪(逐语句): 5.9 调试过程&#xff1a; 5.9.1 开始调…

一屏万象,场景无限:蓝牙墨水屏标签多功能多场景应用带您领略未来

在数字化浪潮汹涌澎湃的今天&#xff0c;智能科技产品层出不穷&#xff0c;它们不仅极大地改变了我们的生活方式&#xff0c;更在无形中拓宽了我们的视野。而今&#xff0c;一款融合了创新技术与实用性于一体的蓝牙墨水屏标签&#xff0c;正以其多功能多场景应用的特性&#xf…

【wiki知识库】02.wiki知识库SpringBoot后端的准备

&#x1f4dd;个人主页&#xff1a;哈__ 期待您的关注 目录 一、&#x1f525;今日目标 二、&#x1f4c2;打开SpringBoot项目 2.1 导入所需依赖 2.2修改application.yml配置文件 2.3导入MybatisPlus逆向工程工具 2.4创建一个公用的返回值 2.5创建CopyUtil工具类 2.6创建…

固定Linux的ip地址,通过图形化界面操作,简单易上手

目录 1、查看Linux的网络 2、修改设置 3、修改Windows网络设置 1、查看Linux的网络 2、修改设置 3、修改Windows网络设置 Microsoft Windows [版本 10.0.19045.3996] (c) Microsoft Corporation。保留所有权利。C:\Users\dgq>ipconfigWindows IP 配置无线局域网适配器 WLAN:…

DataGrip软件执行已将创建好的sql文件步骤

一、在需要导入sql文件上右击找到SQLScript &#xff0c;然后点击 Run SQL Script 二、找到sql文件&#xff0c;点击OK就可以了

【编译原理复习笔记】正则表达式与自动机

正则表达式 正则表达式是一种用来描述正则语言的更紧凑的表达方法 e.g. r a ( a ∣ b ) ∗ ( ϵ ∣ ( . ∣ ) ( a ∣ b ) ) ra(a|b)^*(\epsilon|(.|\\_ )(a|b)) ra(a∣b)∗(ϵ∣(.∣)​(a∣b)) 正则表达式可以由较小的正则表达式按照特定的规则递归地构建。每个正则表达式定义…

【软件设计师】程序语言

1.程序设计语言基本概念 1.1 低级语言与高级语言 低级语言&#xff1a;机器语言和汇编语言称为低级语言 机器语言指0.&#xff0c;1组成的机器指令序列 汇编语言指用符号表示指令的语言&#xff0c;如MOV AX&#xff0c;2 高级语言&#xff1a;从人类的逻辑角度出发&#xff0…

蓝卓入选工信部2023年度“揭榜挂帅”项目

蓝卓“面向多元异构和应用快速开发演化的智能工厂操作系统解决方案”&#xff0c;凭借行业领先的平台技术能力以及数智赋能的硬核实力成功揭榜挂帅。 本次入选不仅代表了蓝卓又一次获得工信部权威专家及国家认可&#xff0c;更是“工厂操作系统”首次在国家层面获得表彰。 智能…

听说京东618裁员?所以日常准备很重要呀

文末有最少必要的面试题&#xff0c;还准备了离线 PDF 版本。 京东也要向市场输送人才了? 这几天看到技术群里不少朋友在讨论京东裁员相关的信息。 我去看了下京东近期的操作&#xff0c;京东内部考勤调整和午休时间缩短&#xff0c;以及强化打卡机制等管理调整&#xff1b;有…

IDEA设置运行内存

1.开启内存指示条​​​​​​​ 查看idea右下角​​​​​​​ 2.环境变量查看ideaVM地址&#xff0c;没有的话那就是默认的配置文件&#xff1a; idea 安装 bin 目录下 idea64.exe.vmoptions 3.去对应路径修改内存参数大小 4.重启IDEA&#xff0c;end