news 2026/5/25 3:17:01

Batcher双调排序及其实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Batcher双调排序及其实现

长度为nnn的序列a1a_1a1,a2a_2a2,—,ana_nan被称为双调序列当且仅当存在1<=k<=n1<=k<=n1<=k<=n满足ak,ak+1,−−−,an,a1,−−−,ak−1a_k,a_{k+1},---,a_n,a_1,---,a_{k-1}ak,ak+1,,an,a1,,ak1是先单调增后单调减或先单调减后单调增的序列

nnn为偶数
有如下的Batcher定理:
ai=min(ai,ai+n/2),ai+n/2=max(ai,ai+n/2)1<=i<=n/2a_i = min(a_i,a_{i+n/2}),a_{i+n/2} = max(a_i,a_{i+n/2}) 1<=i<=n/2ai=min(ai,ai+n/2),ai+n/2=max(ai,ai+n/2)1<=i<=n/2(ai∣1<=i<=n/2)(a_i|1<=i<=n/2)(ai∣1<=i<=n/2)(ai+n/2∣1<=i<=n/2)(a_{i+n/2}|1<=i<=n/2)(ai+n/2∣1<=i<=n/2)均为双调序列且前者任意元素均小于等于后者任意元素,当然如果令ai=max(ai,ai+n/2),ai+n/2=min(ai,ai+n/2)1<=i<=n/2a_i = max(a_i,a_{i+n/2}),a_{i+n/2} = min(a_i,a_{i+n/2}) 1<=i<=n/2ai=max(ai,ai+n/2),ai+n/2=min(ai,ai+n/2)1<=i<=n/2则前者任意元素均大于等于后者任意元素
这个定理的证明我不会,希望好心人在评论区给出文献

nnn为2的幂
得到(ai∣1<=i<=n/2)(a_i|1<=i<=n/2)(ai∣1<=i<=n/2)(ai+n/2∣1<=i<=n/2)(a_{i+n/2}|1<=i<=n/2)(ai+n/2∣1<=i<=n/2)的操作称为Batcher操作,如果ai=min(ai,ai+n/2),ai+n/2=max(ai,ai+n/2)1<=i<=n/2a_i = min(a_i,a_{i+n/2}),a_{i+n/2} = max(a_i,a_{i+n/2}) 1<=i<=n/2ai=min(ai,ai+n/2),ai+n/2=max(ai,ai+n/2)1<=i<=n/2则称为Batcher_Min操作,否则称为Batcher_Max操作,进行Batcher_Min操作后递归地在(ai∣1<=i<=n/2)(a_i|1<=i<=n/2)(ai∣1<=i<=n/2)(ai+n/2∣1<=i<=n/2)(a_{i+n/2}|1<=i<=n/2)(ai+n/2∣1<=i<=n/2)上执行Batcher_Min操作称为Batcher_Min排序,进行Batcher_Max操作后递归地在(ai∣1<=i<=n/2)(a_i|1<=i<=n/2)(ai∣1<=i<=n/2)(ai+n/2∣1<=i<=n/2)(a_{i+n/2}|1<=i<=n/2)(ai+n/2∣1<=i<=n/2)上执行Batcher_Max操作称为Batcher_Max排序,

双调排序:
采用自底向上归并的方法,要求待排序序列sss长度n必须为2的幂
先将sss两两为一组,对每一组交替执行Batcher_Min排序和Batcher_Max排序(第一组执行Batcher_Min排序),结束后奇数组单调增,偶数组单调减,然后将sss每四个为一组,对每一组交替执行Batcher_Min排序和Batcher_Max排序(第一组执行Batcher_Min排序,注意每一次执行排序前前两个元素单调增,后两个元素单调减),结束后奇数组单调增,偶数组单调减,因此类推
.最后将sss每n/2个为一组分成两组,对第一组执行Batcher_Min排序,对第二组执行Batcher_Max排序(注意执行排序前每一组前n/4个元素单调增,后n/4个元素单调减),结束后第一组单调增,第二组单调减.最终为了使sss从小到大有序,我们对整个sss执行Batcher_Min排序,至此sss完全有序,排序结束.

c++实现(该算法非常容易并行化,在cpu,gpu上都是如此,请自己思考,以下只给出cpu上执行的串行代码)

#include<iostream>#include<vector>#include<algorithm>#include<random>usingstd::vector;enumclassop_type{MIN,Max};voidBatcherOperation(vector<longlong>&seq,size_t left,size_t right,size_t k,op_type op)//right-left是2^k{if(k==0)return;size_t gap=1ull<<(k-1);for(size_t i=left;i<left+gap;++i){if(op==op_type::MIN){if(seq[i]>seq[i+gap]){std::swap(seq[i],seq[i+gap]);}}else{if(seq[i]<seq[i+gap]){std::swap(seq[i],seq[i+gap]);}}}BatcherOperation(seq,left,left+gap,k-1,op);BatcherOperation(seq,left+gap,right,k-1,op);}voidgenAndSortBitonicSeq(vector<longlong>&seq,size_t k)//2^k == seq.size(){size_t n=1;while(n<=k){size_t gap=1ull<<n;op_type flag=op_type::MIN;for(size_t i=0;i<seq.size();i=i+gap){BatcherOperation(seq,i,i+gap,n,flag);if(flag==op_type::MIN){flag=op_type::Max;}else{flag=op_type::MIN;}}++n;}}boolBitonicSort(vector<longlong>&seq){if(seq.empty())returntrue;for(size_t i=0;i<seq.size();++i){if(seq[i]==std::numeric_limits<longlong>::max()){std::cerr<<"错误,初始待排序序列不能包含最大可能值"<<std::endl;returnfalse;}}size_t k=0;while((1ull<<k)<seq.size()){++k;}size_t original=seq.size();for(size_t i=0;i<(1ull<<k)-original;++i){seq.push_back(std::numeric_limits<longlong>::max());}genAndSortBitonicSeq(seq,k);seq.erase(seq.begin()+original,seq.end());returntrue;}intmain(){/* vector<long long> seq{10, 20, 5, 9, 3, 8, 12, 14, 90, 0, 60, 40, 23, 35, 95, 18}; BitonicSort(seq); for (size_t i = 0; i < seq.size(); ++i) { std::cout << seq[i] << " "; } std::cout << std::endl;*/constsize_t N=2000;for(size_t i=1;i<=N;++i){vector<longlong>seq(i);for(size_t j=0;j<i;++j){seq[j]=j+1;}vector<longlong>seq_c;seq_c.insert(seq_c.end(),seq.begin(),seq.end());seq_c.insert(seq_c.end(),seq.begin(),seq.end());shuffle(seq_c.begin(),seq_c.end(),std::default_random_engine());if(BitonicSort(seq_c)){std::cout<<"N="<<i<<"排序结果: ";for(size_t j=0;j<seq_c.size();j+=2){if(seq_c[j]!=j/2+1||seq_c[j+1]!=j/2+1){std::cout<<"错误!"<<std::endl;exit(-1);}}std::cout<<"正确!"<<std::endl;}else{std::cerr<<"N="<<i<<"的排序失败"<<std::endl;exit(-1);}}return0;}
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/25 3:15:04

给客户打电话经常被挂?电话号码企业认证来帮忙

忙碌的销售部门里&#xff0c;电话铃声此起彼伏&#xff0c;但回应往往是沉默。销售员小张今天拨出了150个电话&#xff0c;其中有120个被直接挂断&#xff0c;剩下的30个里&#xff0c;有一半在听到自我介绍的一瞬间就收到了“嘟嘟”的忙音。这种困境不是个案。在防骚扰软件普…

作者头像 李华
网站建设 2026/5/25 3:06:44

2026免费在线去水印软件推荐,手把手教你5种方法,第三种0.3秒搞定!

你是不是也遇到过这种抓狂的情况&#xff1f;刷到一个绝美风景视频想保存当壁纸&#xff0c;结果右下角一个巨大的水印把画面全毁了&#xff1b;好不容易在小红书看到一篇干货满满的教程截图下来&#xff0c;底下那排平台ID怎么裁都裁不干净&#xff1b;想搬运一段B站搞笑片段发…

作者头像 李华
网站建设 2026/5/25 2:57:01

AI Agent开发框架推荐

AI Agent 开发领域&#xff0c;可基于成熟框架快速构建复杂应用的项目推荐、核心框架对比及最佳实践如下。 一、主流 AI Agent 开发框架与项目推荐 当前&#xff0c;AI Agent 的开发已从零散提示词工程转向基于结构化框架的工程化实践。下表对比了三大主流方向及其代表性项目&…

作者头像 李华