【C++】十大排序算法之 插入排序 希尔排序

本次介绍内容参考自:十大经典排序算法(C++实现) - fengMisaka - 博客园 (cnblogs.com)

排序算法是《数据结构与算法》中最基本的算法之一。

十种常见排序算法可以分为两大类:

  • 比较类排序:通过比较来决定元素间的相对次序,时间复杂度为 O(nlogn)~O(n²)。
  • 非比较类排序:不通过比较来决定元素间的相对次序,其时间复杂度可以突破 O(nlogn),以线性时间运行。

【十大经典排序算法分类】

十大经典排序算法的复杂度分析

名词解释

  • 时间/空间复杂度:描述一个算法执行时间/占用空间与数据规模的增长关系。

  • n:待排序列的个数。

  • k:“桶”的个数(上面的三种非比较类排序都是基于“桶”的思想实现的)。

  • In-place:原地算法,指的是占用常量内存,不占用额外内存。即空间复杂度为 O(1) 。

  • Out-place:非原地算法,占用额外内存。

  • 稳定性:假设待排序列中两元素相等,排序前后这两个相等元素的相对位置不变,则认为是稳定的。



一、插入排序(Insertion-Sort)

        插入排序(Insertion-Sort)的算法描述是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

1.1、算法描述

  • 将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。
  • 从头到尾依次扫描未排序序列,将扫描到的每个元素与有序序列的每个元素进行比较,小于哪个有序序列的元素就进行交换,相当于插入到该元素索引位置。

(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。)

1.2、动图演示

插入排序动图演示


1.3、C++编码

/**
* @version Copyright (c) 2024 NCDC, Servo。 Unpublished - All rights reserved
* @file InsertSort.hpp
* @brief 插入排序
* @autor 写代码的小恐龙er
* @date 2024/03/04
*/

void InsertSort(int arr[], int n) {
	int i, j, temp;
	for (i = 1; i < n; i++) {
		temp = arr[i];

		for (j = i; j > 0 && arr[j - 1] > temp; j--)
			arr[j] = arr[j - 1]; // 把已排序元素逐步向后挪位

		arr[j] = temp; // 插入
	}
}

1.4 、算法分析

        插入排序在实现上,通常采用 in-place 排序(即只需用到 O(1) 的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。



二、希尔排序(Shell Sort)

        1959年Shell发明,第一个突破 O(n2) 的排序算法,是插入排序的改进版。它与插入排序的不同之处在于,它会优先比较距离较远的元素。希尔排序又叫缩小增量排序

2.1 、算法描述

        先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,具体算法描述:

  • 选择一个增量序列 t1,t2,…,tk,其中 ti>tj,tk=1;
  • 按增量序列个数 k,对序列进行 k 趟排序;
  • 每趟排序,根据对应的增量 ti,将待排序列分割成若干长度为 m 的子序列,分别对各子表进行直接插入排序。仅增量因子为 1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。

2.2 、动图演示

 选希尔排序动图演示


2.3、C++编码

/**
* @version Copyright (c) 2024 NCDC, Servo。 Unpublished - All rights reserved
* @file ShellSort.hpp
* @brief 希尔排序
* @autor 写代码的小恐龙er
* @date 2024/03/04
*/

void ShellSort(int *arr[], int size)  
{  
    int i, j, tmp, increment; 
    // 选择一个增量序列 t1,t2,…,tk,其中 ti>tj,tk=1;
    // 按增量序列个数 k,对序列进行 k 趟排序;
    for (increment = size/ 2; increment > 0; increment /= 2) {   
        // 每趟排序,根据对应的增量 ti,将待排序列分割成若干长度为 m 的子序列,
        // 分别对各子表进行直接插入排序。
        // 仅增量因子为 1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。
        for (i = increment; i < size; i++) {  
            tmp = arr[i];  
            // 直接插入排序
            for (j = i - increment; j >= 0 && tmp < arr[j]; j -= increment) {  
                arr[j + increment] = arr[j];  
            }  
            // 插入
            arr[j + increment] = tmp;
        }  
    }  
}  

2.4 、算法分析

        希尔排序是不稳定排序,所比较快,因为相比冒泡排序,每次交换是跳跃式的。每次排序的时候设置一个基准点,将小于等于基准点的数全部放到基准点的左边,将大于等于基准点的数全部放到基准点的右边。这样在每次交换的时候就不会像冒泡排序一样每次只能在相邻的数之间进行交换,交换的距离就大的多了。因此总的比较和交换次数就少了,速度自然就提高了。当然在最坏的情况下,仍可能是相邻的两个数进行了交换。因此希尔排序的最差时间复杂度和冒泡排序是一样的都是 O(n²),它的平均时间复杂度为 O(n log n)。

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

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

相关文章

鸿蒙开发就业前景以及发展方向分析~

鸿蒙操作系统作为华为公司自主研发的操作系统&#xff0c;已经成为当下炙手可热的话题。作为一个全新的操作系统&#xff0c;鸿蒙开发为IT行业带来了巨大的就业机会。本文将围绕鸿蒙开发的就业前景以及发展方向展开讨论。 一、鸿蒙开发就业前景 随着鸿蒙操作系统的发布&#…

二叉树——从中序与后序遍历序列构造二叉树、654. 最大二叉树、617. 合并二叉树

从中序与后序遍历序列构造二叉树 给定两个整数数组 inorder 和 postorder &#xff0c;其中 inorder 是二叉树的中序遍历&#xff0c; postorder 是同一棵树的后序遍历&#xff0c;请你构造并返回这颗 二叉树 。 示例 1: 在这里插入代码片 输入&#xff1a;inorder [9,3,15…

leetcode 热题 100_和为 K 的子数组

题解一&#xff1a; 前缀和数组哈希表&#xff1a;可以计算所有子数组之和暴力求解&#xff0c;但复杂度太高。对于子数组求和的过程&#xff0c;我们可以采用前缀和数组进行优化&#xff0c;前缀和数组中pre[index]代表nums[0]~nusm[index]之和&#xff0c;当我们要计算子数组…

NLP评价指标

一、分类任务常见评估&#xff1a; 准确度(Accuracy) 评估预测正确的比例&#xff0c;精确率(Precision) 评估预测正例的查准率&#xff0c;召回率(Recall) 评估真实正例的查全率。如果是多分类&#xff0c;则每个类别各自求P、R最终求平均值。 TP&#xff08;True Positives…

SwiftUI 在 App 中弹出全局消息横幅(上)

功能需求 在 SwiftUI 开发的 App 界面中,有时我们需要在全局层面向用户展示一些消息: 如上图所示:我们弹出的全局消息横幅位于所有视图之上,这意味这它不会被任何东西所遮挡;而且用户可以点击该横幅关闭它。这是怎么做到的呢? 在本篇博文中,您将学到以下内容 功能需求…

mac电脑使用pyinstaller打包python脚本

pyinstaller -F template.py 出现报错"AssertionError: Executable contains code signature!" 移除签名 codesign --remove-signature /Users/f7692281/PycharmProjects/TPtestlist/transmit_v6.0.py 打包命令 pyinstaller --windowed transmit_v6.0.py pyinst…

如何使用两个 ESP32-DevKit 开发板的 SDIO 接口测试 AT 固件?

文档参考 ESP32 SDIO AT GuideSDIO 硬件接线说明 硬件准备 两个 ESP32-DevKit 开发板10 KHz 电阻长度低于 10cm 的杜邦线 管脚ESP32 SDIO HostESP32 SDIO SlaveCLK1414CMD1515DAT022DAT144DAT21212DAT31313GNDGNDGND 1-bit SD 模式&#xff08;默认&#xff09;&#xff1…

HTTP代理扫描的技术解析(HTTP代理扫描的技术原理和使用方法)

HTTP代理扫描的技术解析 近年来&#xff0c;随着互联网的快速发展&#xff0c;HTTP代理扫描技术也日益成熟。HTTP代理扫描是指通过扫描网络中的HTTP代理服务器&#xff0c;获得有效代理的IP地址和端口&#xff0c;进而实现网络请求的转发。通过HTTP代理扫描&#xff0c;用户可…

深入了解直播美颜SDK,美颜SDK是什么?

在实现直播美颜功能的背后&#xff0c;美颜SDK扮演了重要的角色。今天&#xff0c;笔者将为大家讲解美颜SDK的定义、功能以及在直播行业中的应用。 一、美颜SDK的定义 美颜SDK是一种软件开发工具包&#xff0c;旨在为应用开发者提供一套实现美颜功能的接口和算法。它通常包含…

探究java反射取值与方法取值性能对比

探究java反射取值与方法取值性能对比 由于我开发框架时&#xff0c;经常需要对象取值。常用的取值方式有&#xff1a; 反射取值方法调用取值 环境 同一台电脑&#xff1a; jdk 21.0.2 idea 2023.3.3 1. 测试代码&#xff08;常用&#xff09; 1.1 反射取值 public stat…

从零开始手写RPC框架(4)

这一节主要讲述网络传输模块的代码&#xff0c;并且几乎每一行代码都加上了我个人理解的注释&#xff0c;同时也讲述了其中一些以前没见过的函数&#xff0c;和大致的底层运行逻辑。 目录 网络传输实体类网络传输实现基于Socket实现网络传输基于Netty实现网络传输客户端服务端 …

华为---MSTP(一)---MSTP生成树协议

目录 1. MSTP技术产生背景 2. STP/RSTP的缺陷 ​编辑 2.1 无法均衡流量负载 2.2 数据使用次优路径 3. MSTP生成树协议 3.1 MSTP相关概念 3.2 MSTP树生成的形成过程 4. MSTP报文 1. MSTP技术产生背景 RSTP在STP基础上进行了改进&#xff0c;实现了网络拓扑快速收敛。但…

【k8s管理--可视化界面】

1、可视化界面的软件 kubernetes的可视化软件有以下这些kubernetes dashboard&#xff1a;https://github.com/kubernetes/dashboardkubesphere官网&#xff1a; https://kubesphere.io/zh/rancher 官网&#xff1a; https://www.rancher.cn/kuboard 官网&#xff1a; https:/…

C++11常用知识分享(一)【列表初始化 || 简化声明 || 范围for || 左右值 || 可变参数模板】

目录 一. 列表初始化 1&#xff09;用法 2) initializer_list 小节&#xff1a; 二&#xff0c;简化声明 1) &#xff0c;auto 2) &#xff0c;decltype类 3)&#xff0c;nullptr 三&#xff0c;范围for 四&#xff0c;C11后&#xff0c;STL容器变化 五&#xff0c…

【数据结构】实现堆

大家好&#xff0c;我是苏貝&#xff0c;本篇博客带大家了解堆&#xff0c;如果你觉得我写的还不错的话&#xff0c;可以给我一个赞&#x1f44d;吗&#xff0c;感谢❤️ 目录 一. 堆的概念及结构二. 堆的实现堆的结构体初始化销毁插入数据删除数据&#xff08;默认删除堆顶即…

【JS】WebSocket实现简易聊天室

【JS】WebSocket实现简易聊天室 聊天室思路示例 聊天室思路 聊天室思路 1、连接服务器先建立连接&#xff0c;默认生成匿名用户(admin01) 2、客户端发送消息&#xff0c;其它客户端用户都会同步接收消息(服务端接受消息广播所有连接用户) 3、客户端修改昵称&#xff0c;其它客…

鸿蒙应用组件

基础组件 索引组件—AlphabetIndexer&#xff08;相当于安卓的seedbar&#xff09; 使用&#xff1a;AlphabetIndexer(value: {arrayValue: Array<string>, selected: number})空白填充组件—Blank&#xff08;占位使用&#xff0c;当父组件为Row/Column/Flex时生效&am…

[SpringCloud] OpenFeign核心架构原理 (一)

Feign的本质: 动态代理 七大核心组件 Feign底层是基于JDK动态代理来的, Feign.builder()最终构造的是一个代理对象, Feign在构建对象的时候会解析方法上的注解和参数, 获取Http请求需要用到基本参数以及和这些参数和方法参数的对应关系。然后发送Http请求, 获取响应, 再根据响…

2024-3-4 市场分歧视角

今天市场有一个单独分歧视角可以观察思考&#xff0c;竞价氢能这边严重不符合预期&#xff0c;隔夜单 四川金顶 和 东方精工 大幅减少&#xff0c;预期就是这两个货会高位分歧&#xff0c;最高板 东方精工 开盘就是瀑布杀&#xff0c;四川金顶先杀到1个多点&#xff0c;9&#…

分库分表如何管理不同实例中几万张分片表?

在进行分库分表设计时&#xff0c;确认好了数据节点数量和分片策略以后&#xff0c;接下来要做的就是管理大量的分片表。实际实施过程中可能存在上百个分片数据库实例&#xff0c;每个实例中都可能有成千上万个分片表&#xff0c;如果仅依靠人力来完成这些任务显然是不现实的。…