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

news2024/12/26 9:31:10

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];  // 将当前元素保存为key
        j = 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 - 1
        while j >= 0 and x[j] > temp:
            x[j+1] = x[j]
            j -= 1
        x[j + 1] = temp


x1 = [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) // 2
    while gap >= 1:
        i = gap
        while i < len(x):
            temp = x[i]
            j = i - gap
            while j >= 0 and x[j] > temp:
                x[j + gap] = x[j]
                j -= gap
            x[j + gap] = temp
            i += 1
        gap //= 2


x1 = [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.coloradmin.cn/o/1948451.html

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

相关文章

EXCEL自动公式计算始终为0

如果你的数据单元格的左上角存在绿色的三角小箭头&#xff0c;那么就会造成这种问题&#xff1a; 你的数字是以文本形式存入的单元格 解决办法&#xff1a; 选中数据列&#xff0c;数据->分列 直接选择完成 此时就可以进行公式计算了

用友U8 Cloud MeasureQueryFrameAction SQL注入漏洞复现

0x01 产品简介 用友U8 Cloud是用友推出的新一代云ERP,主要聚焦成长型、创新型企业,提供企业级云ERP整体解决方案。 0x02 漏洞概述 用友U8 Cloud MeasureQueryFrameAction接口处存在SQL注入漏洞,未经身份验证的远程攻击者除了可以利用 SQL 注入漏洞获取数据库中的信息(例…

Vue3逻辑复用及内置组件

Vue3的逻辑复用主要通过“组合式函数”、“自定义指令”及“插件”来实现。提高了代码复用性&#xff0c;增强代码可维护性及促进团队合作。 1 逻辑复用 1.1 组合式函数 利用Vue组合式API来封装和复用有状态逻辑的函数。对组合式函数有如下约定&#xff1a; 命名&#xff0…

高通Hexagon ENPU4 从ONNX模型转换成EAI浮点模型

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…

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

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

Maven的概念

1.什么是Maven 1.1.什么是Maven Maven是跨平台的项目管理工具&#xff0c;主要服务于基于Java平台的项目构建、依赖管理以及项目信息管理。 1.2.什么是理想的项目构建 高度自动化&#xff0c;标准化&#xff0c;跨平台&#xff0c;可重用的组件 1.3.什么是依赖&#xff0c…

wget下载github文件得到html文件

从github/gitee下载源文件&#xff0c;本来是22M下载下来只有11k 原因&#xff1a; Github会提供html页面&#xff0c;包括指定的文件、上下文与相关操作。通过wget或者curl下载时&#xff0c;会下载该页面 解决方式&#xff1a; github点击Code一栏的raw按钮&#xff0c;获得源…

HTTPS证书价格差异体现在哪?

HTTPS证书作为保障网站安全的重要工具&#xff0c;其类型、功能和费用差异成为用户选择时的关键考量因素。本文将深入探讨HTTPS证书的不同类型、功能以及费用差异&#xff0c;以帮助用户做出更合适的选择。 HTTPS证书的类型 HTTPS证书主要分为三种&#xff1a;DV&#xff08;D…

24证券从业考试报名『个人信息表』填写模板❗

24证券从业考试报名『个人信息表』填写模板❗ 1️⃣居住城市、通讯地址&#xff1a;写自己现居住的地址就可以。 2️⃣学历&#xff1a;需要注意的是学历填写的是考生已经取得的学历&#xff0c;在校大学生已经不具有报名资格&#xff0c;选择大专以上&#xff0c;或者是高中学…

【轨物方案】成套开关柜在线监测物联网解决方案

随着物联网技术的发展&#xff0c;电力设备状态监测技术也得到了迅速发展。传统的电力成套开关柜设备状态监测方法主要采用人工巡检和定期维护的方式&#xff0c;这种方法不仅效率低下&#xff0c;而且难以保证设备的实时性和安全性。因此&#xff0c;基于物联网技术的成套开关…

ARM架构(二)—— arm v7-a/v8/v9寄存器介绍

1、ARM v7-A寄存器 1.1 通用寄存器 V7 V8开始 FIQ个IRQ优先级一样&#xff0c; 通用寄存器&#xff1a;31个 1.2 程序状态寄存器 CPSR是程序状态毒存器&#xff0c;保存条件标志位&#xff0c;中断禁止位&#xff0c;当前处理器模式等控制和状态位。每种异常模式下还存在SPS…

MySQL之索引及简单运用

索引&#xff1a; 什么是索引 索引是数据库中一种非常重要的数据结构&#xff0c;用于帮助快速查询数据库表中的数据。它就像一本书的目录&#xff0c;能够让你快速定位到书中的某个具体章节或内容&#xff0c;而不需要一页一页地翻阅整本书。 在数据库管理系统中&#xff0c;…

Servlet 3.0的新特征

版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhlServlet 3.0概述 Servlet 3.0规范是在2009年随着Java EE 6的发布而推出的。它引入了一系列新特性和改进,旨在简化Web应用的开发和部署过程,并提高Web应用的性能和可扩展性。Servlet 3.0的发布标…

C++ | Leetcode C++题解之第279题完全平方数

题目&#xff1a; 题解&#xff1a; class Solution { public:// 判断是否为完全平方数bool isPerfectSquare(int x) {int y sqrt(x);return y * y x;}// 判断是否能表示为 4^k*(8m7)bool checkAnswer4(int x) {while (x % 4 0) {x / 4;}return x % 8 7;}int numSquares(i…

河南萌新联赛2024第(二)场---G. lxy的通风报信

题目描述 在 nnn mmm 的平面星球里&#xff08; 5<n5 < n5<n&#xff0c; m<1000m < 1000m<1000 &#xff09;&#xff0c;存在着 aaa 支军队 ( 2<a<502 < a < 502<a<50 ) , 和 bbb 支驻扎在地图中的敌军 ( 0<b<n∗m−a0 < b &…

Python写UI自动化--playwright(通过UI文本匹配实现定位)

本篇简单拓展一下元素定位技巧&#xff0c;通过UI界面的文本去实现定位 目录 匹配XPath 匹配文本元素 .count()统计匹配数量 处理匹配文本返回多个元素 1、使用.nth(index)选择特定元素: 2、获取所有匹配的元素并遍历: 3、错误处理: 匹配XPath 比如我们要定位到下图的…

SpringBoot 项目配置文件注释乱码的问题解决方案

一、问题描述 在项目的配置文件中&#xff0c;我们写了一些注释&#xff0c;如下所示&#xff1a; 但是再次打开注释会变成乱码&#xff0c;如下所示&#xff1a; 那么如何解决呢&#xff1f; 二、解决方案 1. 点击” File→Setting" 2. 搜索“File Encodings”, 将框…

JCR一区级 | Matlab实现TTAO-Transformer-LSTM多变量回归预测

JCR一区级 | Matlab实现TTAO-Transformer-LSTM多变量回归预测 目录 JCR一区级 | Matlab实现TTAO-Transformer-LSTM多变量回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.【JCR一区级】Matlab实现TTAO-Transformer-LSTM多变量回归预测&#xff0c;三角拓扑聚合…

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

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

Sentinel限流规则详解

上一期教程讲解了 Sentinel 的快速入门&#xff1a;Sentinel快速入门&#xff0c;这一期主要讲述 Sentinel 的限流规则 簇点链路 簇点链路就是项目内的调用链路&#xff08;Controller -> Service -> Mapper&#xff09;&#xff0c;链路中被监控的每个接口就是一个资源…