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

C++十大排序算法

目录

1.冒泡排序

2.选择排序

3. 插入排序

4.希尔排序(插入排序的优化)

5.归并排序

6.快速排序

7.堆排序

8.计数排序  

9.桶排序

10.基数排序


1.冒泡排序

        冒泡排序(Bubble Sort)是一种简单的排序算法,它通过重复地遍历待排序的列表,比较相邻的元素并交换它们的位置来实现排序。该算法的名称来源于较小的元素会像"气泡"一样逐渐"浮"到列表的顶端。

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

        空间复杂度:O(1)

        特点:稳定,效率低

代码实现:

  vector<int> sortArray(vector<int>& nums) {for(int i=0;i<nums.size();i++){int flag = false;for(int j = 1;j<nums.size()-i;j++){if(nums[j-1]>nums[j]){flag = true;swap(nums[j-1],nums[j]);}}if(!flag){break;}}return nums;}

2.选择排序

        选择排序基本思想是每次从待排序的数据中选择最小(或最大)的元素,放到已排序序列的末尾,直到全部数据排序完成。

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

        空间复杂度:O(1)

        特点:不稳定,效率低

代码实现

 vector<int> sortArray(vector<int>& nums) {for(int i=0;i<nums.size();i++){int index = i ;for(int j = i+1;j<nums.size();j++){if(nums[index]>nums[j]){index = j;}}swap(nums[i],nums[index]);}return nums;}

3. 插入排序

        插入排序通过构建有序序列,对于未排序的数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序的代码实现虽然没有冒泡排序和选择排序那么简单粗暴,但它的原理应该是最容易理解的了,因为只要打过扑克牌的人都应该能够秒懂。

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

        空间复杂度:O(1)

        特点:稳定,效率低

代码实现:

 vector<int> sortArray(vector<int>& nums) {for(int i=1;i<nums.size();i++){int num = nums[i];int j = i-1;while(j>=0&&num<nums[j]){nums[j+1] = nums[j];j--;}nums[j+1] = num;}return nums;}

4.希尔排序(插入排序的优化)

        希尔排序的基本思想是:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录"基本有序"时,再对全体记录进行依次直接插入排序。

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

        空间复杂度:O(1)

        特点:不稳定,效率相对低。

代码实现

vector<int> sortArray(vector<int>& nums) {int n = nums.size();int gap = n/2; while(gap>0){for(int i = gap;i<n;i++){int temp = nums[i];int j = i;while(j>=gap&&nums[j-gap]>temp){nums[j] = nums[j-gap];j-=gap;}nums[j] = temp;}gap/=2;}return nums;}

5.归并排序

        归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。归并排序的核心思想是将一个大问题分解成若干个小问题,分别解决这些小问题,然后将结果合并起来,最终得到整个问题的解。

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

        空间复杂度:O(n)

        特点:稳定,效率较高,但需要额外空间。

代码实现

 vector<int> merge_sort(vector<int>& nums){if(nums.size()<=1){return nums;}int mid = nums.size()/2;vector<int> left(nums.begin(),nums.begin()+mid);vector<int> right(nums.begin()+mid,nums.end());vector<int> merge_left = merge_sort(left);vector<int> merge_right = merge_sort(right);return merge(merge_left,merge_right);}vector<int> merge( const vector<int>& left,const vector<int>& right){vector<int> result;int i=0, j = 0;while(i<left.size()&&j<right.size()){if(left[i]<right[j]){result.push_back(left[i]);i++;}else{result.push_back(right[j]);j++;}}while(i<left.size()){result.push_back(left[i++]);}while(j<right.size()){result.push_back(right[j++]);}return result;}

6.快速排序

        快速排序(Quick Sort)是一种高效的排序算法,基于分治法(Divide and Conquer)的思想。它的核心是通过选择一个基准元素(pivot),将列表分为两部分:一部分小于基准元素,另一部分大于基准元素,然后递归地对这两部分进行排序。     

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

        空间复杂度:O(log n)

        特点:不稳定,但效率较高。快速排序的空间复杂度主要来自递归调用栈的深度,而不是额外的数组空间。

代码实现

    void fast_sort(vector<int>& nums,int left,int right){if(right-left<=1){return;}int index  = left+rand()%(right-left);int value = nums[index];swap(nums[left],nums[index]);int i = left+1;int j = right-1;while(i<=j){while(i<=j&&nums[i]<=value) i++;while(i<=j&&nums[j]>value) j--;if(i<j){swap(nums[i],nums[j]);}}swap(nums[left],nums[j]);fast_sort(nums,left,j);fast_sort(nums,j+1,right)}

7.堆排序

        堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。堆排序可以说是一种利用堆的概念来排序的选择排序。分为两种方法:

  1. 大顶堆:每个节点的值都大于或等于其子节点的值,在堆排序算法中用于升序排列;
  2. 小顶堆:每个节点的值都小于或等于其子节点的值,在堆排序算法中用于降序排列;

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

        空间复杂度:O(1)

        特点:不稳定,但效率较高。

代码实现

 vector<int> sortArray(vector<int>& nums) {int n = nums.size();for(int i = n/2-1;i>=0;i--){heap_sort(nums,n,i);}for(int i = n-1;i>=0;i--){swap(nums[i],nums[0]);heap_sort(nums,i,0);}return nums;}void heap_sort(vector<int>& nums,int n,int i){int max = i;int left = 2*i+1;int right = 2*i+2;if(left<n&& nums[left]>nums[max]) max = left;if(right<n&& nums[right]>nums[max]) max = right;if(max!=i) {swap(nums[max],nums[i]);heap_sort(nums,n,max);}}

8.计数排序  

        计数排序(Counting Sort)是一种非比较型的排序算法,适用于对整数或有限范围内的数据进行排序。它的核心思想是通过统计每个元素的出现次数,然后根据统计结果将元素放回正确的位置。计数排序的时间复杂度为 O(n + k),其中 n 是待排序元素的数量,k 是数据的范围大小。

        计数排序的核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。

        时间复杂度:O(n + k)

        空间复杂度:O(n + k)

        特点:当 k 较小时,性能优异,稳定(逆序遍历原数组,正序是不稳定的)。

代码实现

   vector<int> sortArray(vector<int>& nums) {int max_num = INT_MIN;for(int num:nums){max_num = max(max_num,num);} vector<int> count(max_num+1);  for(int num:nums){count[num]++;}for(int i=1;i<count.size();i++){count[i]+=count[i-1];}vector<int> result(count[count.size()-1],0);for(int i=nums.size()-1;i>=0;--i){result[count[nums[i]]-1] = nums[i];count[nums[i]]-=1;}return result;}

9.桶排序

        桶排序(Bucket Sort)是一种分布式排序算法,它将待排序的元素分配到若干个桶(Bucket)中,然后对每个桶中的元素进行排序,最后将所有桶中的元素按顺序合并。桶排序的核心思想是将数据分到有限数量的桶中,每个桶再分别排序(可以使用其他排序算法或递归地使用桶排序)。

        桶排序是计数排序的升级版。它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。为了使桶排序更加高效,我们需要做到这两点:

  1. 在额外空间充足的情况下,尽量增大桶的数量
  2. 使用的映射函数能够将输入的 N 个数据均匀的分配到 K 个桶中

同时,对于桶中元素的排序,选择何种比较排序算法对于性能的影响至关重要。

        时间复杂度:O(n + k * m log m)

        空间复杂度:O(n + k)

        特点:数据分布均匀时,性能优异。

代码实现

 vector<int> sortArray(vector<int>& nums) {int n = nums.size();if(n<=1) return nums;int max_num = *max_element(nums.begin(),nums.end());int min_num = *min_element(nums.begin(),nums.end());int bucketNum = static_cast<float>(max_num-min_num)/n+1;vector<vector<int>> buckets(bucketNum);for(int num:nums){int bucketIndex = (num-min_num)/n;buckets[bucketIndex].push_back(num);}for(auto& bucket: buckets){sort(bucket.begin(),bucket.end());}vector<int> result;for(auto& bucket:buckets){for(auto num:bucket){result.push_back(num);}}return result;}

10.基数排序

        基数排序(Radix Sort)是一种非比较型的排序算法,它通过逐位比较元素的每一位(从最低位到最高位)来实现排序。基数排序的核心思想是将整数按位数切割成不同的数字,然后按每个位数分别进行排序。基数排序的时间复杂度为 O(n * k),其中 n 是列表长度,k 是最大数字的位数。

        时间复杂度:O(n * k)

        空间复杂度:O(n + k)

        特点:当 k 较小时,性能优异,性能优异。

代码实现

 vector<int> count_sort(vector<int>& nums,int exp){int n = nums.size();vector<int> result(n,0);int count[10];for(int num:nums){int index = (num/exp)%10;count[index]++;}for(int i=1;i<10;i++){count[i]+=count[i-1];}for(int i = n-1;i>=0;i--){int index = (nums[i]/exp)%10;result[count[index]-1] = nums[i];count[index]-=1;}return result;}

        更多详细内容可以参考1.0 十大经典排序算法 | 菜鸟教程

http://www.dtcms.com/a/537427.html

相关文章:

  • 公司网站维护由那个部门做百度竞价点击工具
  • Vue2 elementUI年份区间选择组件
  • 工装设计方案网站wordpress的仪表盘进不去
  • 深度学习笔记40-CGAN|生成手势图像
  • 浙江建设职业技术学院oa网站怎么做微信推广和宣传
  • React 08
  • 企业信息门户网站建设方案设计素材的网站
  • 如何将自己做的网站变成中文帮忙制作网页的公司
  • gpu driven:vello新执行流程
  • LangGraph的Agent长短时记忆的原理有什么区别,分别适用于什么业务场景
  • 定制网站开发的目的是什么做单位网站的公司吗
  • 做网站建立数据库自适应的网站模板
  • 路由硬盘做网站空间不中国城乡建中国城乡建设部网站
  • 电脑怎么做服务器 网站wordpress手机号网站
  • 跨境电商技术与运营双升级!亚马逊 / TikTok/Temu 本周新政解读,附卖家技术适配指南​
  • C++ 类的学习(七) 类的转换 和 嵌套类
  • C++进阶: 虚函数1-----继承中的灵魂
  • 软件协议使用应知应会
  • C语言进阶:深入探讨指针(一)
  • 网站备案 信息wordpress支付接口同步回调
  • 当 AI 开始书写历史:我们如何用 Gateone.ai 把“历史人物时间线”从学术幻想变成 SaaS 产品
  • 如何推广企业网站杭州物联网前十名公司
  • SQL Server
  • state machine diagrams用于需求分析阶段还是设计阶段
  • 【穿越Effective C++】Scott Meyers的《Effective C++》逻辑框架概要汇总--各条款是什么?为什么?怎么做?
  • 易旅游网站建设wap网站开发和自适应
  • 免费iOS加固方案指南
  • 登封快乐送餐在那个网站做的广告wordpress版本对应php版本
  • 云南网站建设一度科技网站团购活动页面怎么做
  • 电动自行车为何限速25公里每小时?——安全、法规与技术的平衡之道