【算法】插入排序 与 希尔排序 概念+图解+代码【Python C C++】

1.插入排序

1.1概念

插入排序(InsertionSort),一般也被称为直接插入排序。

对于少量元素的排序,它是一个有效的算法。插入排序是一种最简单的排序方法,它的基本思想是将一个元素插入到已经排好序的有序表中,从而构造出一个新的、记录数增 1 的有序表。

并假设最开始该有序列表只有第一个元素,将后面的每个元素按顺序依次插入到前面有序列表的合适位置中去即可。

在其实现过程使用双层循环,外层循环对除了第一个元素之外的所有元素,内层循环对当前元素前面有序表进行待插入位置查找,并进行移动。

时间复杂度:O(n^2)

空间复杂度: O(1)

1.2图解(以C语言代码为例)

1.3代码

1.3.1 C

#include <stdio.h>void insertionSort(int arr[], int n);  // 声明插入排序函数
void printArray(int arr[], int size);  // 声明打印数组函数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;  // 程序结束
}void insertionSort(int arr[], int n) {int i, key, j;  // 定义局部变量for (i = 1; i < n; i++) {  // 从第二个元素开始遍历key = arr[i];  // 将当前元素保存为keyj = i - 1;  // 设置j为前一个元素的索引// 移动比key大的元素while (j >= 0 && arr[j] > key) {arr[j + 1] = arr[j];  // 将元素向右移动j = j - 1;  // 移动到下一个元素}arr[j + 1] = key;  // 将key插入到正确的位置}
}void printArray(int arr[], int size) {int i;  // 定义索引变量for (i = 0; i < size; i++)  // 遍历数组printf("%d ", arr[i]);  // 打印每个元素printf("\n");  // 换行
}

1.3.2 Python

def insertionSort(x):for i in range(1, len(x)):temp = x[i]j = i - 1while j >= 0 and x[j] > temp:x[j+1] = x[j]j -= 1x[j + 1] = tempx1 = [2, 5, 2, 1, 9, 4, 7]
print(x1)
insertionSort(x1)
print(x1)# 输出
[2, 5, 2, 1, 9, 4, 7]
[1, 2, 2, 4, 5, 7, 9]

1.3.3 C++

#include <iostream>// 插入排序函数
void insertionSort(int arr[], int n) {for (int i = 1; i < n; i++) {  // 从第二个元素开始,到数组末尾int key = arr[i];  // 保存当前要插入的元素int j = i - 1;  // 初始化一个指针,指向当前元素的前一个位置// 当 j 大于等于 0 且前一个元素大于当前元素时while (j >= 0 && arr[j] > key) {  arr[j + 1] = arr[j];  // 将前一个元素向后移动一位j = j - 1;  // 将 j 向前移动一位}arr[j + 1] = key;  // 将当前元素插入到正确的位置}
}// 打印数组函数
void printArray(int arr[], int size) {for (int i = 0; i < size; i++)std::cout << arr[i] << " ";std::cout << std::endl;
}// 测试案例
int main() {int arr[] = {12, 11, 13, 5, 6};int n = sizeof(arr) / sizeof(arr[0]);std::cout << "排序前的数组为: ";printArray(arr, n);insertionSort(arr, n);std::cout << "排序后的数组为: ";printArray(arr, n);return 0;
}

2.希尔排序

2.1 概念

希尔排序(Shell Sort)是插入排序的一种,它是针对直接插入排序算法的改进

希尔排序又称缩小增量排序,因 DL.Shell 于 1959 年提出而得名。

它通过比较相距一定间隔的元素来进行,通过确定分隔间隔(总数除2取整,再递归除2,直到为1)来分出多个数列分别进行从少到多插入排序,各趟比较所用的距离随着算法的进行而减小,直到只比较相邻元素的最后一趟排序为止

时间复杂度:O(n^(1.3-2))

没有时间复杂度为 O(n(logn)) 的快速排序算法快 ,因此对中等大小规模表现良好,但对规模非常大的数据排序不是最优选择,

比一般 O(n^2 ) 复杂度的算法快得多

空间复杂度: O(1)

可能有人会觉得,希尔排序的最后一步不就相当于插入排序,一个一个加到有序列表中去

但其实希尔排序通过先将数组按照较大的间隔进行分组排序,使得数组在一开始就变得部分有序。随着间隔逐渐缩小,最终达到类似于插入排序的效果。虽然希尔排序的最后一步在较小间隔时类似于插入排序,但由于前面的分组排序操作,使得元素的初始顺序相对较好,减少了插入排序时元素移动的次数。插入排序在最坏情况下,对于一个逆序的数组,每次插入操作都需要移动大量的元素,时间复杂度为 O(n^2)。而希尔排序通过合理选择间隔序列,可以在大多数情况下,有效地减少排序的总比较和移动次数,不过对于希尔排序最坏的情况也是O(n^2),只能说大部分情况下比插入排序优。

2.2 图解(以C语言代码为例)

2.3代码

2.3.1 C 

//gcc -g D:\C\the_C\算法知识相关\希尔排序\2.c -o D:\C\the_C\算法知识相关\希尔排序\b.exe
#include <stdio.h>// 希尔排序函数
void shellSort(int arr[], int n) {int gap, i, j, temp;for (gap = n / 2; gap > 0; gap = gap / 2) {for (i = gap; i < n; i++) {temp = arr[i];for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) {arr[j] = arr[j - gap];}arr[j] = temp;}}
}// 打印数组函数
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("before sorting: ");printArray(arr, n);shellSort(arr, n);printf("after sorting: ");printArray(arr, n);return 0;
}

2.3.2 python

def ShellSort(x):gap = len(x) // 2while gap >= 1:i = gapwhile i < len(x):temp = x[i]j = i - gapwhile j >= 0 and x[j] > temp:x[j + gap] = x[j]j -= gapx[j + gap] = tempi += 1gap //= 2x1 = [2, 5, 2, 1, 9, 4, 7]
print(x1)
ShellSort(x1)
print(x1)# 输出
[2, 5, 2, 1, 9, 4, 7]
[1, 2, 2, 4, 5, 7, 9]

2.3.3 C++

#include <iostream>// 希尔排序函数
void shellSort(int arr[], int n) {for (int gap = n / 2; gap > 0; gap /= 2) {for (int i = gap; i < n; i++) {int temp = arr[i];int j;for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) {arr[j] = arr[j - gap];}arr[j] = temp;}}
}// 打印数组函数
void printArray(int arr[], int size) {for (int i = 0; i < size; i++) {std::cout << arr[i] << " ";}std::cout << std::endl;
}// 测试示例
int main() {int arr[] = {12, 11, 13, 5, 6};int n = sizeof(arr) / sizeof(arr[0]);std::cout << "排序前的数组为: ";printArray(arr, n);shellSort(arr, n);std::cout << "排序后的数组为: ";printArray(arr, n);return 0;
}

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

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

相关文章

mathtype7.4永久激活码(mathtype7永久注册码网盘下载)

大家好&#xff0c;我是你们的数学小能手&#xff01;今天我要安利一款超实用的工具——MathType&#xff0c;让你在数学的世界里游刃有余&#xff0c;轻松搞定各种公式和计算。准备好被种草了吗&#xff1f;跟我一起来瞧瞧吧&#xff01; MathType是理科生专用的必备工具&…

EXCEL 排名(RANK,COUNTIFS)

1.单列排序 需求描述&#xff1a;如有下面表格&#xff0c;需要按笔试成绩整体排名。 解决步骤&#xff1a; 我们使用RANK函数即可实现单列整体排名。 Number 选择第一列。 Ref 选择这一整列&#xff08;CtrlShift向下箭头、再按F4&#xff09;。 "确定"即可计算…

一键解锁百变发型!上交联合Tiamat震撼发布Stable-Hair发型移植黑科技!

Stable-Hair 是一种基于扩散的新型发型转移方法&#xff0c;可以稳健地转移各种现实世界的发型。在各种具有挑战性的发型上实现了高度详细和高保真度的转移&#xff0c;效果令人印象深刻&#xff0c;同时保留了原始身份内容和结构。 相关链接 论文链接: https://arxiv.org/pdf…

案例实践 | 基于长安链的福建省气象综合治理区块链平台

案例名称-【福建省气象综合治理区块链平台】 ■ 实施单位 福建福链科技有限公司 ■ 业主单位 福建省气象信息中心 ■ 上线时间 2023年10月 ■ 用户群体 福建省气象、防灾减灾相关单位 ■ 用户规模 全省2100余个气象站、气象局以及防灾减灾部门 案例背景与解决痛点 …

跟代码执行流程,读Megatron源码(四)megatron初始化脚本initialize.py之initialize_megatron()分布式环境初始化

在前文中&#xff0c;我们讲述了pretrain函数的执行流程&#xff0c;其首要步骤是megatron分组的初始化与环境的配置。本文将深入initialize_megatron函数源码&#xff0c;剖析其初始化分布式训练环境的内部机制。 注&#xff1a;在此假设读者具备3D并行相关知识 一. initiali…

【MARL】MADDPG + attention 实现(+论文解读)

文章目录 前言注意力机制论文里的attention回顾知识-MADDPG讲解1.Q的定义2.Q的恒等式3.论文里的attention4.好处 实现 和 修改结果展示原论文代码 翻改版修改后原maddpg代码 前言 导师让在MADDPG上加一个注意力机制&#xff0c;试了很多种&#xff0c;下面的参考的论文的效果最…

C++——保持原有库头文件不变的情况下,成功编译运行工程

问&#xff1a;想要保持原来库方式&#xff0c;应该怎么操作呢&#xff1f; 答&#xff1a;如果想保持原来的方式&#xff0c;则只需要将 库所在路径 tracker/detector/rknn_model_zoo/utils 加入到 工程库包含中即可。

基于jeecgboot-vue3的Flowable流程-自定义业务表单流程历史信息显示

因为这个项目license问题无法开源&#xff0c;更多技术支持与服务请加入我的知识星球。 1、对于自定义业务表单的流程历史记录信息做了调整&#xff0c;增加显示自定义业务表单 <el-tab-pane label"表单信息" name"form"><div v-if"customF…

ESP32开发进阶:OLED屏幕显示旋转的3D模型

一、硬件接线 我选择的是最常见的一块板子&#xff1a;ESP-WROOM-32&#xff0c;硬件接线如下&#xff1a; 21 - SDA 22 - SCL 二、Arduino端代码 我们使用Arduino和Adafruit SSD1306库在OLED显示屏上绘制和旋转一个3D立方体。 首先&#xff0c;定义立方体顶点和…

CSS(七)——CSS 列表和CSS Table(表格)

目录 CSS 列表 列表 作为列表项标记的图像 列表 - 简写属性 移除默认设置 所有的CSS列表属性 CSS 表格 表格边框 折叠边框&#xff08;border-collapse&#xff09; 表格宽度和高度 表格文字对齐 表格填充 表格颜色 CSS 列表 CSS 列表属性作用如下&#xff1a; 设…

C#开发的全屏图片切换效果应用 - 开源研究系列文章 - 个人小作品

这天无聊&#xff0c;想到上次开发的图片显示软件《 PhotoNet看图软件 》&#xff0c;然后想到开发一个全屏图片切换效果的应用&#xff0c;类似于屏幕保护程序&#xff0c;于是就写了此博文。这个应用比较简单&#xff0c;主要是全屏切换换图片效果的问题。 1、 项目目录&…

【Vue3】watch 监视 ref 定义的数据

【Vue3】watch 监视 ref 定义的数据 背景简介开发环境开发步骤及源码参数说明 背景 随着年龄的增长&#xff0c;很多曾经烂熟于心的技术原理已被岁月摩擦得愈发模糊起来&#xff0c;技术出身的人总是很难放下一些执念&#xff0c;遂将这些知识整理成文&#xff0c;以纪念曾经努…

【C++进阶学习】第八弹——红黑树的原理与实现——探讨树形结构存储的最优解

二叉搜索树&#xff1a;【C进阶学习】第五弹——二叉搜索树——二叉树进阶及set和map的铺垫-CSDN博客 AVL树&#xff1a; ​​​​​​【C进阶学习】第七弹——AVL树——树形结构存储数据的经典模块-CSDN博客 前言&#xff1a; 在前面&#xff0c;我们已经学习了二叉搜索树和…

PCIe 6.0为什么需要14-bit tag

1.TLP中的tag是什么 在PCIe TLP&#xff08;Transaction Layer Packet&#xff09;中&#xff0c;tag是分配给特定Non-Posted Request的编号&#xff0c;协议要求CPL/CPLD中的tag 与对应non-post request TLP中的tag保持一致&#xff0c;因此Requester可以使用tag来识别CPL…

免费【2024】springboot 趵突泉景区的智慧导游小程序

博主介绍&#xff1a;✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术范围&#xff1a;SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化…

十、SpringBoot 统⼀功能处理【拦截器、统一数据返回格式、统一异常处理】

十、SpringBoot 统⼀功能处理 1. 拦截器【HandlerInterceptor、WebMvcConfig】1.1 拦截器快速⼊⻔⾃定义拦截器&#xff1a;实现HandlerInterceptor接⼝&#xff0c;并重写其所有⽅法注册配置拦截器&#xff1a;实现WebMvcConfigurer接⼝&#xff0c;并重写addInterceptors⽅法…

堆(c++)

堆是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵树的数组对象。 堆总是满足下列性质&#xff1a; 堆中某个节点的值总是不大于或不小于其父节点的值&#xff1b;堆总是一棵完全二叉树。 常见的堆有二叉堆、斐波那契堆等。 堆是非线性数据结构&#…

初识C++ · map和set的使用

目录 前言&#xff1a; 1 set 2 map 前言&#xff1a; 在前面阶段&#xff0c;我们已经学习了stl里面的部分容器&#xff0c;比如vector,list,deque等&#xff0c;这些容器都被称为序列式容器&#xff0c;也就是每个值之间式没有关联的&#xff0c;那么今天介绍的容器&…

IGV.js | 载入自己下载的gtf文件

1.安装 htslib-1.20 https://www.htslib.org/doc/tabix.html J3$ cd ~/Downloads/ $ wget https://github.com/samtools/htslib/releases/download/1.20/htslib-1.20.tar.bz2 $ tar jxvf htslib-1.20.tar.bz2编译安装&#xff1a; $ cd htslib-1.20/ $ ./configure --prefix/…

vue的三大核心知识点

响应式&#xff1a; 监听data属性getter setter(包括数组)模板编译&#xff1a; 模板到render函数再到vnodevdom&#xff1a; patch(elem, vnode)和patch(vnode, newVnode) vue组件初次渲染过程 解析模板为render函数&#xff08;或在开发环境已完成&#xff0c;vue-loader&a…