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

数据结构之八大基本排序方法

在数据结构中,排序是一个重要的操作,它有助于提高数据的可读性和可操作性。排序算法有多种,各有优缺点,适用于不同的场景。以下是八大经典排序算法的介绍:

1. 冒泡排序(Bubble Sort)

原理:通过重复遍历要排序的数组,每次比较相邻的两个元素,如果它们的顺序错误就交换它们的位置。这样,最大的元素会逐步“冒泡”到数组的末尾。

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

代码示例

void bubbleSort(std::vector<int>& arr) {int n = arr.size();for (int i = 0; i < n - 1; ++i) {for (int j = 0; j < n - i - 1; ++j) {if (arr[j] > arr[j + 1]) {std::swap(arr[j], arr[j + 1]);}}}
}

2. 选择排序(Selection Sort)

原理:每次从未排序部分选择最小的元素,放到已排序部分的末尾。

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

代码示例

void selectionSort(std::vector<int>& arr) {int n = arr.size();for (int i = 0; i < n - 1; ++i) {int minIndex = i;for (int j = i + 1; j < n; ++j) {if (arr[j] < arr[minIndex]) {minIndex = j;}}std::swap(arr[i], arr[minIndex]);}
}

3. 插入排序(Insertion Sort)

原理:构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

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

代码示例

void insertionSort(std::vector<int>& arr) {int n = arr.size();for (int i = 1; i < n; ++i) {int key = arr[i];int j = i - 1;while (j >= 0 && arr[j] > key) {arr[j + 1] = arr[j];--j;}arr[j + 1] = key;}
}

4. 希尔排序(Shell Sort)

原理:是插入排序的一种改进,通过将数组分割成若干子序列分别进行插入排序,从而加快排序速度。

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

代码示例

void shellSort(std::vector<int>& arr) {int n = arr.size();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;}}
}

5. 归并排序(Merge Sort)

原理:采用分治法,将数组分成两部分分别排序,然后合并排序结果。

时间复杂度:O(n log n)

代码示例

void merge(std::vector<int>& arr, int l, int m, int r) {int n1 = m - l + 1;int n2 = r - m;std::vector<int> L(n1), R(n2);for (int i = 0; i < n1; ++i) {L[i] = arr[l + i];}for (int j = 0; j < n2; ++j) {R[j] = arr[m + 1 + j];}int i = 0, j = 0, k = l;while (i < n1 && j < n2) {if (L[i] <= R[j]) {arr[k++] = L[i++];} else {arr[k++] = R[j++];}}while (i < n1) {arr[k++] = L[i++];}while (j < n2) {arr[k++] = R[j++];}
}void mergeSort(std::vector<int>& arr, int l, int r) {if (l < r) {int m = l + (r - l) / 2;mergeSort(arr, l, m);mergeSort(arr, m + 1, r);merge(arr, l, m, r);}
}

6. 快速排序(Quick Sort)

原理:选择一个基准元素,通过一趟排序将待排序数组分成两部分,其中一部分比基准元素小,另一部分比基准元素大,然后递归地对这两部分分别进行快速排序。

时间复杂度:平均O(n log n),最坏O(n^2)

代码示例

int partition(std::vector<int>& arr, int low, int high) {int pivot = arr[high];int i = (low - 1);for (int j = low; j <= high - 1; ++j) {if (arr[j] < pivot) {std::swap(arr[++i], arr[j]);}}std::swap(arr[i + 1], arr[high]);return (i + 1);
}void quickSort(std::vector<int>& arr, int low, int high) {if (low < high) {int pi = partition(arr, low, high);quickSort(arr, low, pi - 1);quickSort(arr, pi + 1, high);}
}

7. 堆排序(Heap Sort)

原理:利用堆这种数据结构来排序。最大堆用于升序排序,最小堆用于降序排序。

时间复杂度:O(n log n)

代码示例

void heapify(std::vector<int>& arr, int n, int i) {int largest = i;int left = 2 * i + 1;int right = 2 * i + 2;if (left < n && arr[left] > arr[largest]) {largest = left;}if (right < n && arr[right] > arr[largest]) {largest = right;}if (largest != i) {std::swap(arr[i], arr[largest]);heapify(arr, n, largest);}
}void heapSort(std::vector<int>& arr) {int n = arr.size();for (int i = n / 2 - 1; i >= 0; --i) {heapify(arr, n, i);}for (int i = n - 1; i >= 0; --i) {std::swap(arr[0], arr[i]);heapify(arr, i, 0);}
}

8. 计数排序(Counting Sort)

原理:适用于元素范围较小的数组,利用数组下标进行排序。

时间复杂度:O(n + k),其中k是最大值和最小值的范围

代码示例

void countingSort(std::vector<int>& arr) {int max = *std::max_element(arr.begin(), arr.end());int min = *std::min_element(arr.begin(), arr.end());int range = max - min + 1;std::vector<int> count(range), output(arr.size());for (int i = 0; i < arr.size(); ++i) {count[arr[i] - min]++;}for (int i = 1; i < count.size(); ++i) {count[i] += count[i - 1];}for (int i = arr.size() - 1; i >= 0; --i) {output[count[arr[i] - min] - 1] = arr[i];count[arr[i] - min]--;}for (int i = 0; i < arr.size(); ++i) {arr[i] = output[i];}
}

总结

这些排序算法各有优劣,选择合适的排序算法需要根据数据规模和具体场景来决定。一般来说,快速排序和归并排序适用于大多数情况,而像计数排序则适用于特定条件下的排序。

相关文章:

数据结构之八大基本排序方法

在数据结构中&#xff0c;排序是一个重要的操作&#xff0c;它有助于提高数据的可读性和可操作性。排序算法有多种&#xff0c;各有优缺点&#xff0c;适用于不同的场景。以下是八大经典排序算法的介绍&#xff1a; 1. 冒泡排序&#xff08;Bubble Sort&#xff09; 原理&…...

《Milvus Cloud向量数据库指南》——什么是高可用:深入理解数据库系统中的高可用性架构

什么是高可用:深入理解数据库系统中的高可用性架构 在信息技术日新月异的今天,高可用性(High Availability,简称HA)已成为衡量一个系统,尤其是数据库系统稳定性和可靠性的重要标准。高可用性的核心目标在于确保系统能够持续不断地提供服务,最大限度地减少因维护活动、硬…...

C++ | Leetcode C++题解之第319题灯泡开关

题目&#xff1a; 题解&#xff1a; class Solution { public:int bulbSwitch(int n) {return sqrt(n 0.5);} };...

C# 使用 NLog 输出日志到文件夹

在项目中使用 NuGet 安装 NLog 包以及 NLog.Config 包 配置 nlog.config 在项目的根目录下创建一个 Nlog.config 文件&#xff08;如果还没有&#xff09;&#xff0c;然后添加如下配置&#xff1a; <?xml version"1.0" encoding"utf-8" ?> <…...

node.js使用NodeMachineID 生成唯一UUID和注意事项

node-machine-id用于获取或生成唯一的机器ID 如何使用 const { machineId, machineIdSync } require(node-machine-id) JSON.stringify(machineIdSync({original: true})) ;方法&#xff1a; machineIdSync 此函数同步获取操作系统本机UUID/GUID&#xff0c;默认情况下进行哈…...

AI大模型在数据治理中的应用

目前&#xff0c;企业的数据治理工作以人工实施为主&#xff0c;其中一些重复性较强的工作&#xff0c;如&#xff1a;数据标准制定和映射、元数据信息完善、数据目录挂载等&#xff0c;需要消耗大量的人力和时间成本&#xff0c;这给本来就难以量化业务价值的治理工作的顺利推…...

【初学人工智能原理】【12】循环:序列依赖问题

前言 本文教程均来自b站【小白也能听懂的人工智能原理】&#xff0c;感兴趣的可自行到b站观看。 代码及工具箱 本专栏的代码和工具函数已经上传到GitHub&#xff1a;1571859588/xiaobai_AI: 零基础入门人工智能 (github.com)&#xff0c;可以找到对应课程的代码 正文 对于…...

【QT】无法打开QT的ui文件,出现闪退情况

打开qt的ui文件出现闪退的情况&#xff1a; 解决办法&#xff1a;点击扩展-Qt VS Tools-Options 找到Qt General中的Qt Designer 的Run in detached window改为True。...

三、Spring-WebFlux实战案例-流式

目录 一、springboot之间通讯方式 1. 服务端 (Spring Boot) 1.1 添加依赖 1.2 控制器 2. 客户端 (WebClient) 2.1 添加依赖 2.2 客户端代码 3. 运行 二、web与服务之间通讯方式 1、服务端代码 2、客户端代码 3、注意事项 三、移动端与服务端之间通讯方式…...

html+css 实现hover双层按钮

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享htmlcss 绚丽效果&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 文…...

SPIFFS与LittleFS的对gz文件格式的区别

SPIFFS 只能安装在Arduino上。LittleFS支持Arduino IDE和VScode的 PlatformIO。 SPIFFS serveStatic: server.serveStatic("/", SPIFFS, "/") 负责提供 SPIFFS 文件系统中的文件。您可以在 SPIFFS 上放置 .gz 文件&#xff0c;并该方法将自动处理它们。 …...

STM32L051K8U6-开发资料

STM32L051测试 &#xff08;四、Flash和EEPROM的读写&#xff09;-云社区-华为云 (huaweicloud.com) STM32L051测试 &#xff08;四、Flash和EEPROM的读写&#xff09; - 掘金 (juejin.cn) STM32L0 系列 EEPROM 读写&#xff0c;程序卡死&#xff1f;_stm32l0片内eeprom_stm3…...

Markdown语法学习

Markdown学习 一、基础语法讲解 1. 换行 本行末尾双空格然后回车&#xff08;在Typora的中直接回车也可以&#xff09; 2. 换段 本段末尾两次回车 3. 加粗 **加粗** __加粗__效果&#xff1a;加粗 4. 斜体 *加粗* _加粗_效果&#xff1a;斜体 5. 斜体加粗 ***加粗**…...

[最短路Floyd],启动!!!

B3647 【模板】Floyd #include<bits/stdc.h> #define ll long long #define fi first #define se second #define pb push_back #define PII pair<int,int > #define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) using namespace std; const int N …...

7月29(信息差)

&#x1f30d;最强模型 Llama 3.1 如期而至&#xff01;扎克伯格最新访谈&#xff1a;Llama 会成为 AI 界的 Linux &#x1f384;谷歌AlphaProof攻克国际奥赛数学题 https://www.51cto.com/article/793632.html ✨SearchGPT第一波评测来了&#xff01;响应速度超快还没广告&…...

ubuntu中禁止使用鼠标拖动来移动文件

windows和ubuntu中都可以拖动文件到其他路径&#xff0c;然后达到移动文件的目的。 这种方式有好处也有坏处&#xff0c;好处是移动文件方便了&#xff0c;坏处是误操作后会造成故障&#xff0c;尤其是ubuntu中&#xff0c;本身鼠标就特别灵敏并且操作不便&#xff0c;拖动一个…...

【密码学】椭圆曲线密码体制(ECC)

椭圆曲线密码体制&#xff08;Elliptic Curve Cryptography, ECC&#xff09;是一种基于椭圆曲线数学特性的公钥密码系统。在介绍椭圆曲线之前&#xff0c;我们先来了解一下椭圆曲线的基本概念。 一、椭圆曲线是什么&#xff1f; &#xff08;1&#xff09;椭圆曲线的数学定义…...

第25集《大佛顶首楞严经》

丑二、腾疑细释 分二&#xff1a;寅一、阿难腾疑&#xff1b;寅二、如来细释 请大家打开讲义第五十六页&#xff0c;“丑二、腾疑细释”。 本经的修学重点&#xff0c;就是修学首楞严王三昧。它的整个重点&#xff0c;其实就是一个心地法门。我们在行菩萨道的时候慢慢会发觉…...

python 读写文件之 open 和 with open() 详细解析

python 读写文件之 open 和 with open() 详细解析 文章目录 python 读写文件之 open 和 with open() 详细解析1. open() 和 with open() 能打开不同的文件类型吗&#xff1f;2. 文本文件和二进制文件的区别2.1 文本文件 (Text Files)2.2 二进制文件 (Binary Files)区别 3. 读文…...

操作系统:内存----知识点

什么是虚拟内存&#xff1f; 虚拟内存简称虚存&#xff0c;是计算机系统内存管理的一种技术。它是相对于物理内存而言的&#xff0c;可以理解为“假的”内存。它使得应用程序认为它拥有连续可用的内存&#xff08;一个连续完整的地址空间&#xff09;&#xff0c;允许程序员编…...

Debian系统简介

目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版&#xff…...

【JVM】- 内存结构

引言 JVM&#xff1a;Java Virtual Machine 定义&#xff1a;Java虚拟机&#xff0c;Java二进制字节码的运行环境好处&#xff1a; 一次编写&#xff0c;到处运行自动内存管理&#xff0c;垃圾回收的功能数组下标越界检查&#xff08;会抛异常&#xff0c;不会覆盖到其他代码…...

Spring Boot面试题精选汇总

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/

使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题&#xff1a;docker pull 失败 网络不同&#xff0c;需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

ios苹果系统,js 滑动屏幕、锚定无效

现象&#xff1a;window.addEventListener监听touch无效&#xff0c;划不动屏幕&#xff0c;但是代码逻辑都有执行到。 scrollIntoView也无效。 原因&#xff1a;这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作&#xff0c;从而会影响…...

网络编程(UDP编程)

思维导图 UDP基础编程&#xff08;单播&#xff09; 1.流程图 服务器&#xff1a;短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

毫米波雷达基础理论(3D+4D)

3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文&#xff1a; 一文入门汽车毫米波雷达基本原理 &#xff1a;https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…...

HubSpot推出与ChatGPT的深度集成引发兴奋与担忧

上周三&#xff0c;HubSpot宣布已构建与ChatGPT的深度集成&#xff0c;这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋&#xff0c;但同时也存在一些关于数据安全的担忧。 许多网络声音声称&#xff0c;这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...

嵌入式常见 CPU 架构

架构类型架构厂商芯片厂商典型芯片特点与应用场景PICRISC (8/16 位)MicrochipMicrochipPIC16F877A、PIC18F4550简化指令集&#xff0c;单周期执行&#xff1b;低功耗、CIP 独立外设&#xff1b;用于家电、小电机控制、安防面板等嵌入式场景8051CISC (8 位)Intel&#xff08;原始…...

es6+和css3新增的特性有哪些

一&#xff1a;ECMAScript 新特性&#xff08;ES6&#xff09; ES6 (2015) - 革命性更新 1&#xff0c;记住的方法&#xff0c;从一个方法里面用到了哪些技术 1&#xff0c;let /const块级作用域声明2&#xff0c;**默认参数**&#xff1a;函数参数可以设置默认值。3&#x…...