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

十大基础排序算法

排序算法分类

排序:将一组对象按照某种逻辑顺序重新排列的过程。

  • 按照待排序数据的规模分为:

    1. 内部排序:数据量不大,全部存在内存中;
    2. 外部排序:数据量很大,无法一次性全部存在内存中,因此排序中需要访问外存。
  • 按照排序是否稳定分为:

    1. 稳定排序:相等的元素在排序前后的相对位置不变。例如,a等于b,且原序列a在b前,排序后a仍在b前,则为稳定排序。
    2. 不稳定排序:相等元素在排序前后的相对位置可能发生变化。
  • 按照是否需要额外内存分为:

    1. 原地排序:在排序过程中不申请多余的存储空间,只利用原来存储待排数据的存储空间进行比较和交换的数据排序。
    2. 非原地排序:需要额外内存空间存储数组副本以辅助排序。
  • 按照排序方式分为:

    1. 比较类排序:通过比较来决定元素间的相对次序。
    2. 非比较类排序:不通过元素间的比较进行排序。
      在这里插入图片描述

比较类排序

冒泡排序

冒泡排序是一种典型的交换排序

算法原理:

  • 比较相邻的元素。如果第一个比第二个大,就交换它们两个;
  • 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。这一步结束后,排在最后的元素会是所有数据中最大的数;
  • 针对所有的元素重复以上的步骤,除了最后一个;
  • 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

冒泡排序基本代码如下:

void BubbleSort(vector<int>& nums){const int size = nums.size();for(int i = 0; i < size; ++i)for(int j = 0; j < size-i-1; ++j)if(nums[j] > nums[j+1])swap(nums[j], nums[j+1]);
}

性能评价:

  • nums[j] == nums[j+1]时,我们并不交换它们。所以冒泡排序是稳定的;
  • 共循环了(n-1)+(n-2)+…+2+1=n(n-1)/2,所以时间复杂度是O(n^2)。

快速排序

快速排序是从冒泡排序演变而来的,实际上是在冒泡排序基础上的递归分治法。
快速排序在每一轮挑选一个基准元素,并让其他比它大的元素移动到数列一边,比它小的元素移动到数列的另一边,从而把数列拆解成了两个部分。

快排也用了分治策略,其本质框架类似二叉树的前序遍历。

其实现代码如下:

void QuickSort(std::vector<int>& nums, int left, int right){if(left >= right){return;}//"治"int i = left;int j = right;while(i < j){while(i < j && nums[j] > nums[left])     --j;while(i < j && nums[i] <= nums[left])    ++i;std::swap(nums[i], nums[j]);}std::swap(nums[i], nums[left]);//“分”QuickSort(nums, left, i - 1);QuickSort(nums, i + 1, right);
}

注意事项

  1. 如果选取数列的第一个元素为基准元素,则从right所指向的元素开始与基准元素进行比较;如果选取数列的最后一个元素为基准元素,则从left所指向的元素开始与基准元素进行比较。
  2. 如果选取数列的第一个元素为基准元素,left所指向的元素与基准元素第一次对比时,left下标与基准元素下标相等(即:判断条件中添加等号);如果选取数列的最后一个元素为基准元素,right所指向的元素与基准元素第一次对比时,right下标与基准元素下标相等。

时间复杂度:O(nlogn)
空间复杂度:O(1)
稳定性:不稳定

插入排序

基本思想:将待排序数据看成由已排序未排序两部分组成。对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

算法流程:

  1. 从第一个元素开始,该元素可以认为已经被排序;
  2. 取出下一个元素,在已经排序的元素序列中从后向前扫描;
  3. 如果该元素(已排序)大于新元素,将该元素移到下一位置;
  4. 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
  5. 将新元素插入到该位置后;
  6. 重复步骤2~5。

其实现代码如下:

void InsertSort(vector<int>& nums){const int size = nums.size();for(int i = 1; i < size; ++i){int curr = nums[i];int j = i - 1;while(j >= 0 && curr < nums[j]){nums[j+1] = nums[j];--j;}nums[j+1] = curr;}
}

性能评价:

  • 插入排序是稳定的。
  • 时间复杂度为O(n^2)。

希尔排序

在插入排序中,当需要插入的数是较小的数时,后移的次数明显增多,对效率有影响.

希尔排序是对插入排序的优化。它与插入排序的不同之处在于,它会优先比较距离较远的元素。希尔排序又叫缩小增量排序
在这里插入图片描述

其实现代码如下:

void ShellSort(std::vector<int>& nums){const int size = nums.size();for(int gap = size / 2; gap > 0; gap /= 2){for(int i = gap; i < size; ++i){int curr = nums[i];int j = i - gap;while(j >= 0 && curr < nums[j]){nums[j+gap] = nums[j];j -= gap;}nums[j+gap] = curr;}}
}

选择排序

基本思想:首先在未排序数据找到最小的数,然后把该最小数放到排序序列的末尾,直到所有数据排序完毕。

其实现代码如下:

void SelectionSort(vector<int>& nums){const int size = nums.size();for(int i = 0; i < size-1; ++i){int minIndex = i;for(int j = i+1; j < size; ++j)if(nums[j] < nums[minIndex])minIndex = j;swap(nums[i], nums[minIndex]);}
}

性能评价:

  • 简单选择排序是不稳定排序;
  • 无论什么数据进去,它的比较次数都是n(n-1)/2,所以时间复杂度是O(n^2)。

堆排序

首先将等待排序的数组构造成一个大根堆,构造结束后整个数组当中的最大值就是堆顶元素;
然后将堆顶元素与数组末尾元素交换位置,交换结束后数组末尾元素为最大值,剩下其他的待排序的数组个数为n-1个;
将剩余的n-1个数再次构造成一个大根堆,再将堆顶元素与数组第n-1个位置的元素交换位置,重复上述步骤可以最终得到一个有序数组。

其实现代码如下:

//堆调整
void Heapify(std::vector<int>& nums, int index, int heap_size){int parent_index = index;int leftChild_index = 2 * parent_index + 1;while(leftChild_index < heap_size){int maxValue_index = leftChild_index+1 < heap_size && nums[leftChild_index+1] > nums[leftChild_index] ? leftChild_index+1 : leftChild_index;maxValue_index = nums[maxValue_index] > nums[parent_index] ? maxValue_index : parent_index;if(maxValue_index == parent_index)return;std::swap(nums[maxValue_index], nums[parent_index]);parent_index = maxValue_index;leftChild_index = 2 * parent_index + 1;} 
}
//堆排序
void HeapSort(std::vector<int>& nums){if(nums.size() < 2)return;int heap_size = nums.size();//从下标最大的父节点开始。(最后一个元素的下标是n-1,最后一个父节点的下标是n/2-1)for(int i = heap_size/2 - 1; i >= 0; --i)Heapify(nums, i, heap_size);std::swap(nums[0], nums[--heap_size]);while(heap_size > 0){Heapify(nums, 0, heap_size);std::swap(nums[0], nums[--heap_size]);}
}

时间复杂度:O(nlogn)
空间复杂度:O(1)
稳定性:不稳定

归并排序

简单归并排序即二路归并排序。

归并排序采用分治策略,其本质框架类似二叉树的后序遍历,左右子树的递归就是“分”,根结点的处理部分就是“治”。

在这里插入图片描述

其实现代码如下:

std::vector<int> temp;
void MergeSort(std::vector<int>& nums, int left, int right){if(left >= right){return;}int mid = left + (right - left) / 2;//“分”MergeSort(nums, left, mid);MergeSort(nums, mid + 1, right);//"治"int i = left;int j = mid + 1;int t = left;while(i <= mid && j <= right){if(nums[i] <= nums[j]){temp[t++] = nums[i++];}else{temp[t++] = nums[j++];}}while(i <= mid){temp[t++] = nums[i++];}while(j <= right){temp[t++] = nums[j++];}for(int k = left; k <= right; ++k){nums[k] = temp[k];}
}

时间复杂度:O(nlogn)
空间复杂度:O(n)
稳定性:稳定

非比较类排序

基数排序

计数排序

桶排序

总结

在这里插入图片描述

不稳定排序记忆口诀:一堆(堆排序)作业,心态不稳,快(快速排序)选择(选择排序)一些(希尔排序)朋友出去玩。

相关文章:

十大基础排序算法

排序算法分类 排序&#xff1a;将一组对象按照某种逻辑顺序重新排列的过程。 按照待排序数据的规模分为&#xff1a; 内部排序&#xff1a;数据量不大&#xff0c;全部存在内存中&#xff1b;外部排序&#xff1a;数据量很大&#xff0c;无法一次性全部存在内存中&#xff0c;…...

IP协议及相关技术协议

一、IP基本认识 1. IP的作用 IP在TCP/IP模型中处于网络层&#xff0c;网络层的主要作用是实现主机与主机之间的通信&#xff0c;而IP的作用是在复杂的网络环境中将数据包发送给最终目的主机。 2. IP与MAC的关系 简单而言&#xff0c;MAC的作用是实现“直连”的两个设备之通信…...

小红书x-s算法及补环境 单旋转验证码

前言 大家好呀!新的一年,先祝大家新年快乐咯.祝大家逆向,风控都一把过咯. 新年第一篇文章,后续会持续更新哦! 春晚见证了中国经济的新风口,今年春晚互联网企业赞助商就两家,小红书和京东.小红书类似国外的ins,有预感未来小红书会大火,所以写了这篇文章,有需要的加我,联系方式…...

代码检测规范和git提交规范

摘要&#xff1a;之前开发的项目&#xff0c;代码检测和提交规范都是已经配置好的&#xff0c;最近自己新建的项目就记录下相关配置过程。 1. ESlint配置 2013年6月创建开源项目&#xff0c;提供一个插件化的JavaScript代码检测工具&#xff0c;创建项目是生成的eslintrc.js文…...

Elasticsearch:什么是搜索引擎?

搜索引擎定义 搜索引擎是一种软件程序或系统&#xff0c;旨在帮助用户查找存储在互联网或特定数据库中的信息。 搜索引擎的工作原理是对各种来源的内容进行索引和编目&#xff0c;然后根据用户的搜索查询向用户提供相关结果列表。 搜索引擎对于希望快速有效地查找特定信息的用…...

人工智能几个关键节点:深蓝,AlphaGo,ChatGPT,Sora

近30年&#xff0c;人工智能几个关键节点&#xff1a;深蓝&#xff0c;AlphaGo&#xff0c;ChatGPT&#xff0c;Sora 深蓝&#xff1a; 1997年&#xff0c;深蓝击败卡斯帕罗夫的比赛是通过一系列复杂的算法和策略实现的。深蓝的开发团队使用了一种名为“暴力搜索”的技术&…...

WordPres Bricks Builder 前台RCE漏洞复现(CVE-2024-25600)

0x01 产品简介 Bricks Builder是一款用于WordPress的开发主题,提供直观的拖放界面,用于设计和构建WordPress网站。它使用户能够轻松创建自定义的网页布局和设计,无需编写或了解复杂的代码。Bricks Builder具有用户友好的界面和强大的功能,使用户可以通过简单的拖放操作添加…...

代码随想录算法训练营总结 | 慢慢总结,想起啥就先写上

二叉树总结 二叉树的结构 stauct TreeNode {int val&#xff1b;TreeNode* left;TreeNode* right; }二叉树的递归函数分析 二叉树的递归函数当做只有一个根节点&#xff0c;一个左子树&#xff0c;一个右节点的数去看&#xff0c;这看着是个废话&#xff0c; 其实很重要 回溯…...

基于开源模型对文本和音频进行情感分析

应用场景 从商品详情页爬取商品评论&#xff0c;对其做舆情分析&#xff1b;电话客服&#xff0c;对音频进行分析&#xff0c;做舆情分析&#xff1b; 通过开发相应的服务接口&#xff0c;进一步工程化&#xff1b; 模型选用 文本&#xff0c;选用了通义实验室fine-tune的st…...

SQL中为什么不要使用1=1

最近看几个老项目的SQL条件中使用了11&#xff0c;想想自己也曾经这样写过&#xff0c;略有感触&#xff0c;特别拿出来说道说道。 编写SQL语句就像炒菜&#xff0c;每一种调料的使用都可能会影响菜品的最终味道&#xff0c;每一个SQL条件的加入也可能会影响查询的执行效率。那…...

python 几种常见的音频数据读取、保存方式

1. soundfile 库的使用 soundfile库是一个Python库&#xff0c;主要用于读取和写入音频文件。它支持多种音频格式&#xff0c;包括WAV、AIFF、FLAC和OGG等。通过soundfile库&#xff0c;用户可以方便地将numpy数组存储到音频文件或者将音频文件加载到numpy数组中。此外&#x…...

关于msvcr120.dll丢失怎样修复的详细解决步骤方法分享,msvcr120.dll文件的相关内容

在电脑使用过程中&#xff0c;我们经常遇到各种系统错误&#xff0c;其中msvcr120.dll丢失是一个常见问题。msvcr120.dll文件是Visual C Redistributable for Visual Studio 2015/2017的一个组件&#xff0c;主要用于支持某些应用程序的正常运行。当电脑出现msvcr120.dll丢失情…...

简单几步通过DD工具把云服务器系统Linux改为windows

简单几部通过DD安装其他系统&#xff0c;当服务器的web控制台没有我们要装的系统&#xff0c;就需要通过DD&#xff08;Linux磁盘&#xff09;工具来更改系统&#xff0c;&#xff08;已知支持KVM系统&#xff09; 本文如何简单的更换系统&#xff0c;不通过web控制台来更换&a…...

使用 package.json 配置代理解决 React 项目中的跨域请求问题

使用 package.json 配置代理解决 React 项目中的跨域请求问题 当我们在开发前端应用时&#xff0c;经常会遇到跨域请求的问题。为了解决这个问题&#xff0c;我们可以通过配置代理来实现在开发环境中向后端服务器发送请求。 在 React 项目中&#xff0c;我们可以使用 package…...

生成 Let‘s Encrypt 免费证书

文章目录 1. 安装 acme.sh2. 添加云服务商安全访问密钥并授权管理DNS记录3. 当前 Shell 添加安全访问密钥变量4. 生成证书5. 拷贝证书6. 清理安全访问密钥变量7. 打开脚本自动更新 代码仓库地址&#xff1a;https://github.com/Neilpang/acme.sh 1. 安装 acme.sh yum -y insta…...

int128的实现(基本完成)

虽然有一个声明叫_int128但是这并不是C标准&#xff1a; long long 不够用&#xff1f;详解 __int128 - FReQuenter - 博客园 (cnblogs.com) 网络上去找int128的另类实现方法&#xff0c;发现几乎都是在介绍_int128的 然后我就自己想了个办法&#xff0c;当时还没学C&#xf…...

【linux】使用 acme.sh 实现了 acme 协议生成免费的SSL 证书

acme.sh 实现了 acme 协议, 可以从 letsencrypt 生成免费的证书. 主要步骤: 安装 acme.sh生成证书copy 证书到 nginx/apache 或者其他服务更新证书更新 acme.sh出错怎么办, 如何调试 下面详细介绍. 1. 安装 acme.sh 安装很简单, 一个命令: curl https://get.acme.sh | sh…...

MACOS上面C/C++获取网卡索引,索引获取网卡接口名

依赖函数&#xff1a; if_nametoindex IF名字 to IF索引 if_indextoname IF索引 to IF名字 MACOS 10.7 版本支援&#xff08;就是2011年发不OSX的第一个面向用的系统版本&#xff09; int GetInterfaceIndex(const ppp::string& ifrName) noexcept{if (ifrName.empt…...

解决SSH远程登录开饭板出现密码错误问题

输入“adduser Zhanggong回车”&#xff0c;使用adduser命令创建开发板用户名为Zhanggong 输入密码“123456” 输入密码“123456”...

什么时候用ref和reactive

在Vue 3中&#xff0c;ref和reactive都是用于创建响应式数据的工具&#xff0c;但它们的使用场景有所不同。 使用ref的情况&#xff1a; 基本数据类型&#xff1a;当你需要响应式地处理基本数据类型&#xff08;如数字、字符串、布尔值&#xff09;时&#xff0c;应该使用ref…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端&#xff0c;同时完善学生端的构建。本次工作主要包括&#xff1a; 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解

【关注我&#xff0c;后续持续新增专题博文&#xff0c;谢谢&#xff01;&#xff01;&#xff01;】 上一篇我们讲了&#xff1a; 这一篇我们开始讲&#xff1a; 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下&#xff1a; 一、场景操作步骤 操作步…...

python/java环境配置

环境变量放一起 python&#xff1a; 1.首先下载Python Python下载地址&#xff1a;Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个&#xff0c;然后自定义&#xff0c;全选 可以把前4个选上 3.环境配置 1&#xff09;搜高级系统设置 2…...

【第二十一章 SDIO接口(SDIO)】

第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?

论文网址&#xff1a;pdf 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔记&#xff0c;谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

[Java恶补day16] 238.除自身以外数组的乘积

给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时间复杂度…...

push [特殊字符] present

push &#x1f19a; present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中&#xff0c;push 和 present 是两种不同的视图控制器切换方式&#xff0c;它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...

腾讯云V3签名

想要接入腾讯云的Api&#xff0c;必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口&#xff0c;但总是卡在签名这一步&#xff0c;最后放弃选择SDK&#xff0c;这次终于自己代码实现。 可能腾讯云翻新了接口文档&#xff0c;现在阅读起来&#xff0c;清晰了很多&…...

Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换

目录 关键点 技术实现1 技术实现2 摘要&#xff1a; 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式&#xff08;自动驾驶、人工驾驶、远程驾驶、主动安全&#xff09;&#xff0c;并通过实时消息推送更新车…...

日常一水C

多态 言简意赅&#xff1a;就是一个对象面对同一事件时做出的不同反应 而之前的继承中说过&#xff0c;当子类和父类的函数名相同时&#xff0c;会隐藏父类的同名函数转而调用子类的同名函数&#xff0c;如果要调用父类的同名函数&#xff0c;那么就需要对父类进行引用&#…...