0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

C++基础语法十大排序算法后五个分享

C语言编程学习基地 来源:C语言编程学习基地 作者:C语言编程学习基地 2021-10-08 15:06 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

本期是C++基础语法分享的第十六节,今天给大家来梳理一下十大排序算法后五个!

a9519302-2426-11ec-82a8-dac502259ad0.png

归并排序

归并排序:把数据分为两段,从两段中逐个选最小的元素移入新数据段的末尾。可从上到下或从下到上进行。

/***************** 迭代版*****************

///整數或浮點數皆可使用,若要使用物件(class)時必須設定“小於”(《)的運算子功能template《typename T》void merge_sort(T arr[], int len) { T* a = arr;

T* b = new T[len]; for (int seg = 1;

seg 《 len; seg += seg) { for (int start = 0; start 《 len; start += seg + seg) { int low = start, mid = min(start + seg, len), high = min(start + seg + seg, len);

int k = low; int start1 = low, end1 = mid; int start2 = mid, end2 = high; while (start1 《 end1 && start2 《 end2) b[k++] = a[start1] 《 a[start2] ? a[start1++] : a[start2++]; while (start1 《 end1) b[k++] = a[start1++];

while (start2 《 end2) b[k++] = a[start2++]; } T* temp = a;

a = b; b = temp; } if (a != arr) { for (int i = 0; i 《 len; i++) b[i] = a[i]; b = a;

} delete[] b;}

/***************** 递归版*****************/template《typename T》void merge_sort_recursive(T arr[], T reg[], int start, int end) { if (start 》= end) return; int len = end - start, mid = (len 》》 1) + start; int start1 = start, end1 = mid;

int start2 = mid + 1, end2 = end; merge_sort_recursive(arr, reg, start1, end1); merge_sort_recursive(arr, reg, start2, end2);

int k = start; while (start1 《= end1 && start2 《= end2) reg[k++] = arr[start1] 《 arr[start2] ? arr[start1++] : arr[start2++];

while (start1 《= end1) reg[k++] = arr[start1++]; while (start2 《= end2) reg[k++] = arr[start2++];

for (k = start; k 《= end; k++) arr[k] = reg[k];}//整數或浮點數皆可使用,若要使用物件(class)時必須設定“小於”(《)的運算子功能template《typename T》 void merge_sort(T arr[], const int len) { T *reg = new T[len]; merge_sort_recursive(arr, reg, 0, len - 1); delete[] reg;}

希尔排序

希尔排序:每一轮按照事先决定的间隔进行插入排序,间隔会依次缩小,最后一次一定要是1。

template《typename T》void shell_sort(T array[], int length) { int h = 1; while (h 《 length / 3) { h = 3 * h + 1; } while (h 》= 1) { for (int i = h; i 《 length; i++) { for (int j = i; j 》= h && array[j] 《 array[j - h]; j -= h) { std::swap(array[j], array[j - h]); } } h = h / 3; }}

计数排序

计数排序:统计小于等于该元素值的元素的个数i,于是该元素就放在目标数组的索引i位(i≥0)。

计数排序基于一个假设,待排序数列的所有数均为整数,且出现在(0,k)的区间之内。

如果 k(待排数组的最大值) 过大则会引起较大的空间复杂度,一般是用来排序 0 到 100 之间的数字的最好的算法,但是它不适合按字母顺序排序人名。

计数排序不是比较排序,排序的速度快于任何比较排序算法。

时间复杂度为 O(n+k),空间复杂度为 O(n+k)

算法的步骤如下:

1. 找出待排序的数组中最大和最小的元素

2. 统计数组中每个值为 i 的元素出现的次数,存入数组 C 的第 i 项

3. 对所有的计数累加(从 C 中的第一个元素开始,每一项和前一项相加)

4. 反向填充目标数组:将每个元素 i 放在新数组的第 C[i] 项,每放一个元素就将 C[i] 减去 1

#include 《iostream》#include 《vector》#include 《algorithm》

using namespace std;

// 计数排序void CountSort(vector《int》& vecRaw, vector《int》& vecObj){ // 确保待排序容器非空 if (vecRaw.size() == 0) return;

// 使用 vecRaw 的最大值 + 1 作为计数容器 countVec 的大小 int vecCountLength = (*max_element(begin(vecRaw), end(vecRaw))) + 1; vector《int》 vecCount(vecCountLength, 0);

// 统计每个键值出现的次数 for (int i = 0; i 《 vecRaw.size(); i++) vecCount[vecRaw[i]]++; // 后面的键值出现的位置为前面所有键值出现的次数之和 for (int i = 1; i 《 vecCountLength; i++) vecCount[i] += vecCount[i - 1];

// 将键值放到目标位置 for (int i = vecRaw.size(); i 》 0; i--) // 此处逆序是为了保持相同键值的稳定性 vecObj[--vecCount[vecRaw[i - 1]]] = vecRaw[i - 1];}

int main(){ vector《int》 vecRaw = { 0,5,7,9,6,3,4,5,2,8,6,9,2,1 }; vector《int》 vecObj(vecRaw.size(), 0);

CountSort(vecRaw, vecObj);

for (int i = 0; i 《 vecObj.size(); ++i) cout 《《 vecObj[i] 《《 “ ”; cout 《《 endl;

return 0;}

桶排序

桶排序:将值为i的元素放入i号桶,最后依次把桶里的元素倒出来。

桶排序序思路:

1. 设置一个定量的数组当作空桶子。

2. 寻访序列,并且把项目一个一个放到对应的桶子去。

3. 对每个不是空的桶子进行排序。

4. 从不是空的桶子里把项目再放回原来的序列中。

假设数据分布在[0,100)之间,每个桶内部用链表表示,在数据入桶的同时插入排序,然后把各个桶中的数据合并。

const int BUCKET_NUM = 10;

struct ListNode{ explicit ListNode(int i=0):mData(i),mNext(NULL){} ListNode* mNext; int mData;};

ListNode* insert(ListNode* head,int val){ ListNode dummyNode; ListNode *newNode = new ListNode(val); ListNode *pre,*curr; dummyNode.mNext = head; pre = &dummyNode; curr = head; while(NULL!=curr && curr-》mData《=val){ pre = curr; curr = curr-》mNext; } newNode-》mNext = curr; pre-》mNext = newNode; return dummyNode.mNext;}

ListNode* Merge(ListNode *head1,ListNode *head2){ ListNode dummyNode; ListNode *dummy = &dummyNode; while(NULL!=head1 && NULL!=head2){ if(head1-》mData 《= head2-》mData){ dummy-》mNext = head1; head1 = head1-》mNext; }else{ dummy-》mNext = head2; head2 = head2-》mNext; } dummy = dummy-》mNext; } if(NULL!=head1) dummy-》mNext = head1; if(NULL!=head2) dummy-》mNext = head2; return dummyNode.mNext;}

void BucketSort(int n,int arr[]){ vector《ListNode*》 buckets(BUCKET_NUM,(ListNode*)(0)); for(int i=0;i《n;++i){ int index = arr[i]/BUCKET_NUM; ListNode *head = buckets.at(index); buckets.at(index) = insert(head,arr[i]); } ListNode *head = buckets.at(0); for(int i=1;i《BUCKET_NUM;++i){ head = Merge(head,buckets.at(i)); } for(int i=0;i《n;++i){ arr[i] = head-》mData; head = head-》mNext; }}

基数排序

基数排序:一种多关键字的排序算法,可用桶排序实现。

int maxbit(int data[], int n) //辅助函数,求数据的最大位数{ int maxData = data[0]; ///《 最大数 /// 先求出最大数,再求其位数,这样有原先依次每个数判断其位数,稍微优化点。 for (int i = 1; i 《 n; ++i) { if (maxData 《 data[i]) maxData = data[i];

} int d = 1;

int p = 10; while (maxData 》= p) { //p *= 10; // Maybe overflow maxData /= 10; ++d; } return d;/* int d = 1; //保存最大的位数 int p = 10; for(int i = 0; i 《 n; ++i) { while(data[i] 》= p) { p *= 10; ++d;

} } return d;*/}void radixsort(int data[], int n) //基数排序{ int d = maxbit(data, n);

int *tmp = new int[n]; int *count = new int[10];

//计数器 int i, j, k; int radix = 1; for(i = 1; i 《= d; i++) //进行d次排序 { for(j = 0; j 《 10; j++) count[j] = 0; //每次分配前清空计数器 for(j = 0; j 《 n; j++) { k = (data[j] / radix) % 10; //统计每个桶中的记录数 count[k]++; } for(j = 1; j 《 10; j++) count[j] = count[j - 1] + count[j];

//将tmp中的位置依次分配给每个桶 for(j = n - 1; j 》= 0; j--) //将所有桶中记录依次收集到tmp中 { k = (data[j] / radix) % 10; tmp[count[k] - 1] = data[j];

count[k]--; } for(j = 0; j 《 n; j++) //将临时数组的内容复制到data中 data[j] = tmp[j]; radix = radix * 10;

} delete []tmp; delete []count;}

今天的分享就到这里了,大家要好好学C++哟~

责任编辑:haq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 编程
    +关注

    关注

    90

    文章

    3707

    浏览量

    96765
  • C++
    C++
    +关注

    关注

    22

    文章

    2122

    浏览量

    76714

原文标题:C++基础语法梳理:算法丨十大排序算法(二)

文章出处:【微信号:cyuyanxuexi,微信公众号:C语言编程学习基地】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    C++程序异常的处理机制

    语法 C++异常处理涉及到3关键字: throw---抛出一异常,带参数 try---用于标识可能会出现异常的代码段 catch--是用于标识异常处理的代码段 下面以一
    发表于 12-02 07:12

    C语言的常见算法

    # C语言常见算法 C语言中常用的算法可以分为以下几大类: ## 1. 排序算法 ###
    发表于 11-24 08:29

    国产海光 OPS 电脑十大排

    国产海光OPS电脑的市场竞争已从单一参数比拼,转向“性能+适配+服务+口碑”的综合实力竞争。本次十大排名基于产品性能、适配兼容性、品牌实力、行业案例、客户口碑大核心维度,通过第三方数据调研、客户
    的头像 发表于 11-21 09:25 447次阅读
    国产海光 OPS 电脑<b class='flag-5'>十大排</b>名

    科技动态|解锁2025全球十大工程成就

    。——爱因斯坦2025年10月13日发布了“2025全球十大工程成就”,从浩瀚宇宙到能源革命,从基础科学到日常生活,勾勒出人类工程科技创新的壮阔图景。在这全球十大工程
    的头像 发表于 10-24 18:37 660次阅读
    科技动态|解锁2025全球<b class='flag-5'>十大</b>工程成就

    OPS 电脑厂家十大排名榜:2025年最新榜单

    在OPS电脑采购中,“选对厂家”直接决定设备稳定性、适配效率与长期运维成本。本次OPS电脑厂家十大排名榜,基于研发实力、生产规模、品牌合作背书、售后保障、场景落地能力大核心维度综合评测,所有数据均
    的头像 发表于 10-16 16:24 1114次阅读
    OPS 电脑厂家<b class='flag-5'>十大排</b>名榜:2025年最新榜单

    rtsmart开启C++特性支持,工具链编译内核不通过怎么解决?

    各位大佬好,本人在rtsmart项目中需要使用C++11特性,在menuconfig那里配置了支持C++特性,使用7.3.0版本的arm-linux-musleabi编译器编译内核时出现 错误
    发表于 09-29 07:49

    工业路由器品牌前十大排

    、产品覆盖广泛的企业。本文结合行业权威榜单与市场动态,梳理2024-2025年工业路由器品牌前十大排名(排名不分先后) 一、品牌综合实力与产品特点 1. 星创易联 星创易联凭借高性能处理器与多协议兼容性稳居国内工业路由器市场前列。其产
    的头像 发表于 03-27 16:21 1848次阅读

    C++学到什么程度可以找工作?

    C++学到什么程度可以找工作?要使用C++找到工作,特别是作为软件开发人员或相关职位,通常需要掌握以下几个方面: 1. **语言基础**:你需要对C++的核心概念有扎实的理解,包括但不限于指针、内存
    发表于 03-13 10:19

    rtsmart开启C++特性支持,工具链编译内核不通过怎么解决?

    各位大佬好,本人在rtsmart项目中需要使用C++11特性,在menuconfig那里配置了支持C++特性,使用7.3.0版本的arm-linux-musleabi编译器编译内核时出现 错误
    发表于 03-10 08:06

    基于OpenHarmony标准系统的C++公共基础类库案例:ThreadPoll

    1、程序简介该程序是基于OpenHarmony标准系统的C++公共基础类库的线程池处理:ThreadPoll。本案例完成如下工作:创建1线程池,设置该线程池内部有1024线程空间。启动5
    的头像 发表于 02-10 18:09 600次阅读
    基于OpenHarmony标准系统的<b class='flag-5'>C++</b>公共基础类库案例:ThreadPoll

    年度电解槽十大品牌+年度制氢十大供应商,稳石氢能荣获两大奖项!

    此前,2024年10月16日,由国能网与国能能源研究院联合举办的第九届新能源行业品牌盛典(GPBC)圆满召开,稳石氢能荣获2024年度·氢能行业品牌榜“年度电解槽十大品牌”与“年度制氢十大供应商”两大奖项!
    的头像 发表于 01-24 14:53 1494次阅读

    Spire.XLS for C++组件说明

    Spire.XLS for C++ 是一款专业的 C++ Excel 组件,可以用在各种 C++ 框架和应用程序中。Spire.XLS for C++ 提供了一
    的头像 发表于 01-14 09:40 1297次阅读
    Spire.XLS for <b class='flag-5'>C++</b>组件说明

    华为发布2025智能光伏十大趋势

    华为数字能源以“融合创新,智构未来,加速光伏成为主力能源”为主题,举办2025智能光伏十大趋势发布会。华为数字能源智能光伏产品线总裁周涛发布了智能光伏十大趋势和重磅白皮书,为光储产业的高质量发展提供前瞻性支持。
    的头像 发表于 01-06 17:12 1299次阅读

    TimSort:一在标准函数库中广泛使用的排序算法

    排序算法呢? 本文将带你走进 TimSort,一在标准函数库中广泛使用的排序算法。 这个算法
    的头像 发表于 01-03 11:42 954次阅读

    AKI跨语言调用库神助攻C/C++代码迁移至HarmonyOS NEXT

    )开发框架。它极大地简化了JS与C/C++之间的跨语言访问,为开发者提供了一种边界性编程体验友好的解决方案。通过AKI,开发者可以使用让代码更易读的语法糖,实现JS与C/
    发表于 01-02 17:08