荷兰国旗问题.doc
上传人:sy****28 上传时间:2024-09-14 格式:DOC 页数:7 大小:169KB 金币:18 举报 版权申诉
预览加载中,请您耐心等待几秒...

荷兰国旗问题.doc

荷兰国旗问题.doc

预览

在线预览结束,喜欢就下载吧,查找使用更方便

18 金币

下载此文档

如果您无法下载资料,请参考说明:

1、部分资料下载需要金币,请确保您的账户上有足够的金币

2、已购买过的文档,再次下载不重复扣费

3、资料包下载后请先用软件解压,在使用对应软件打开

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<iostream>usingnamespacestd;voidSwap(int*n1,int*n2){inttemp;temp=*n1;*n1=*n2;*n2=temp;}voidPrint(int*num,intlen){for(inti=0;i<len;++i){cout<<num[i]<<"";}cout<<endl;}//0,1,2,1,1,2,0,2,1,0,2,1,0,2,0,1,2,0voidWork(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<iostream>usingnamespacestd;constintN=15;intflag[N];intpre[N];intsplit1;intsplit2;intblue_red;intwhite_red;intcounts=0;//输出结果voidPrint(){for(inti=0;i<N;++i){cout<<flag[i];}cout<<endl;}voidSwap(int&x,int&y){inttemp=x;x=y;y=temp;counts++;}voidWork(){for(inti=0;i<split1;++i){if(flag[i]!=0){if(