荷兰国旗问题.doc
- 文档编号:390032
- 上传时间:2022-10-09
- 格式:DOC
- 页数:7
- 大小:157KB
荷兰国旗问题.doc
《荷兰国旗问题.doc》由会员分享,可在线阅读,更多相关《荷兰国旗问题.doc(7页珍藏版)》请在冰豆网上搜索。
1.问题描述:
我们将乱序的红白蓝三色小球排列成有序的红白蓝三色的同颜色在一起的小球组。
这个问题之所以叫荷兰国旗,是因为我们可以将红白蓝三色小球想象成条状物,有序排列后正好组成荷兰国旗。
2.问题分析:
这个问题我们可以将这个问题视为一个数组排序问题,这个数组分为前部,中部和后部三个部分,每一个元素(红白蓝分别对应0、1、2)必属于其中之一。
由于红、白、蓝三色小球数量并不一定相同,所以这个三个区域不一定是等分的,也就是说如果我们将整个区域放在[0,1]的区域里,由于三色小球之间数量的比不同(此处假设1:
2:
2),可能前部为[0,0.2),中部为[0.2,0.6),后部为[0.6,1]。
我们的思路如下:
将前部和后部各排在数组的前边和后边,中部自然就排好了。
具体的:
设置两个标志位begin和end分别指向这个数组的开始和末尾,然后用一个标志位current从头开始进行遍历:
1)若遍历到的位置为0,则说明它一定属于前部,于是就和begin位置进行交换,然后current向前进,begin也向前进(表示前边的已经都排好了)。
2)若遍历到的位置为1,则说明它一定属于中部,根据总思路,中部的我们都不动,然后current向前进。
3)若遍历到的位置为2,则说明它一定属于后部,于是就和end位置进行交换,由于交换完毕后current指向的可能是属于前部的,若此时current前进则会导致该位置不能被交换到前部,所以此时current不前进。
而同1),end向后退1。
//author:
何佳
#include
usingnamespacestd;
voidSwap(int*n1,int*n2)
{
inttemp;
temp=*n1;
*n1=*n2;
*n2=temp;
}
voidPrint(int*num,intlen)
{
for(inti=0;i { cout< } cout< } //0,1,2,1,1,2,0,2,1,0,2,1,0,2,0,1,2,0 voidWork(int*num,intbegin,intend) { intcur=begin; while(num[cur]==0) { begin++; cur=begin; } while(num[cur]! =2) { cur++; } while(cur! =end) { if(num[cur]==2) { Swap(&num[cur],&num[end]); end--; } if(num[cur]! =num[begin]&&num[cur]! =2) { Swap(&num[begin],&num[cur]); begin++; } while(num[cur]==num[begin]) { cur++; } } if(num[end]! =2) { Swap(&num[cur],&num[begin]); } } intmain() { intnum[]={0,1,2,1,1,2,0,2,1,0,2,0,1,2,0,1,2,0,1,1,1,2,1,2,1,1}; intlen=sizeof(num)/sizeof(int); Print(num,len); Work(num,0,len-1); Print(num,len); } /*左飞C++数据结构与经典问题求解*/ /*荷兰国旗问题*/ /*众所周知,荷兰国旗由红色、白色和蓝色3中颜色组成,现在假设有很多这3中颜色的线被存放在一个数字里,要求每次操作仅能进行一次交换,待对数字进行一遍扫描后,3中颜色自然分开,颜色顺序应为红、白、蓝。 另外,要求在O(n)的复杂度下,使移动次数最小。 */ #include usingnamespacestd; constintN=15; intflag[N]; intpre[N]; intsplit1; intsplit2; intblue_red; intwhite_red; intcounts=0; //输出结果 voidPrint() { for(inti=0;i { cout< } cout< } voidSwap(int&x,int&y) { inttemp=x; x=y; y=temp; counts++; } voidWork() { for(inti=0;i { if(flag[i]! =0) { if(blue_red>=split2) { Swap(flag[i],flag[blue_red]); blue_red=pre[blue_red]; } else { Swap(flag[i],flag[white_red]); white_red=pre[white_red]; } } } intb=N-1; for(inti=split1;i { if(flag[i]! =1) { while(flag[b]==2)b--; Swap(flag[i],flag[b]); b--; } } } //初始化 voidInit() { intred_num=0; intwhite_num=0; intpreI=-1; for(inti=0;i { flag[i]=rand()%3; if(flag[i]==0) { red_num++; pre[i]=preI; preI=i; } else if(flag[i]==1) { white_num++; } } //将国旗分成3中颜色区域 //0~split1-1(红),splite1~split2-1(白),split2~N-1(蓝) split1=red_num; split2=red_num+white_num; blue_red=preI; inti=split2-1; while(flag[i]! =0)i--;//检查白色中有没有红色 white_red=i; } intmain() { Init(); cout<<"原始: "< Print(); Work(); cout<<"移动: "< Print(); return0; }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 荷兰 国旗 问题