1 .问题描述
我们将乱序的红白蓝三色小球排列成有序的红白蓝三色的同颜色在一起的小球组。这个问题之所以叫荷兰国旗 是因为我们可以将红白蓝三色小球想象成条状物有序排列后正好组成荷兰国旗。
2.问题分析
这个问题我们可以将这个问题视为一个数组排序问题 这个数组分为前部 中部和后部三个部分每一个元素红白蓝分别对应0、 1 、 2必属于其中之一。 由于红、 白、蓝三色小球数量并不一定相同 所以这个三个区域不一定是等分的也就是说如果我们将整个区域放在[0, 1]的区域里 由于三色小球之间数量的比不同此处假设1 :2:2 可能前部为[0,0.2) 中部为[02,0 6) 后部为[06, 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;whi le(num[cur]==0)
{begin++;cur=begin;
}whi le(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} ; int len=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];intspl it1;intspl it2;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<spl it1;++i)
{if(flag[i] !=0)
{if(blue_red>=spl it2)
{
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=spl it1;i<spl it2;++i)
{if(flag[i] !=1)
{whi le(flag[b]==2)b--;
Swap(flag[ i] ,flag[b]) ;b--;
}
}
}
//初始化voidInit( )
{intred_num=0;intwhite_num=0;intpreI=-1;for(inti=0;i<N;++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~spl it1-1(红),spl ite1~spl it2-1(白) spl it2~N-1(蓝)spl it1=red_num;spl it2=red_num+white_num;blue_red=preI;inti=spl it2-1;whi le(flag[i] !=0) i--;//检查白色中有没有红色white_red=i;
}intmain()
{
Init();cout<<"原始 "<<endl ;
Print( ) ;
Work();cout<<"移动 "<<counts<<"次"<<endl;Print( ) ;return0;
}
酷锐云是一家2019年开业的国人主机商家,商家为企业运营,主要销售主VPS服务器,提供挂机宝和云服务器,机房有美国CERA、中国香港安畅和电信,CERA为CN2 GIA线路,提供单机10G+天机盾防御,提供美国原生IP,支持媒体流解锁,商家的套餐价格非常美丽,CERA机房月付20元起,香港安畅机房10M带宽月付25元,有需要的朋友可以入手试试。酷锐云自开业以来一直有着良好的产品稳定性及服务态度,支...
ZJI本月新上线了香港葵湾机房站群服务器,提供4个C段238个IPv4,支持使用8折优惠码,优惠后最低每月1400元起。ZJI是原Wordpress圈知名主机商家:维翔主机,成立于2011年,2018年9月更名为ZJI,提供中国香港、台湾、日本、美国独立服务器(自营/数据中心直营)租用及VDS、虚拟主机空间、域名注册等业务,所选数据中心均为国内普遍访问速度不错的机房。葵湾二型(4C站群)CPU:I...
傲游主机怎么样?傲游主机是一家成立于2010年的老牌国外VPS服务商,在澳大利亚及美国均注册公司,是由在澳洲留学的害羞哥、主机论坛知名版主组长等大佬创建,拥有多家海外直连线路机房资源,提供基于VPS主机和独立服务器租用等,其中VPS基于KVM或者XEN架构,可选机房包括中国香港、美国洛杉矶、韩国、日本、德国、荷兰等,均为CN2或者国内直连优秀线路。傲游主机提供8折优惠码:haixiuge,适用于全...