一、三色旗说明
假设有一根绳子,上面有红,白,蓝三种颜色的旗子,数目若干,期初绳子上的旗子颜色没有顺序,你希望将它分类,并排列为蓝,白,红的顺序,每次只能交换两个旗子的位子,怎样使得移动的次数最少
假设w代表白色旗子,r代表红色旗子,b代表蓝色旗子
如将wrrbwbrbwrbrwbbbrwwwbwb的旗子排序,最终要变为bbbbbbbbbwwwwwwwwrrrrrr,只是使移动次数最少
二、代码实现
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BLUE 'b'
#define WHITE 'w'
#define RED 'r'
#define SWAP(x,y) {char temp;temp = color[x];color[x] = color[y];color[y] = temp;}
int main()
{
char color[] = {'r', 'w', 'b', 'w', 'w', 'b', 'r', 'b', 'w', 'r', '\0'};//期初的旗子顺序,这个可以随意设置
int wFlag = 0;//定义一个白色标志,开始指向color[0]
int bFlag = 0;//定义一个蓝色标志,开始指向color[0]
int rFlag = strlen(color) - 1;//定义一个红色标志,开始指向最后一个有效数据
int i;
for(i = 0; i < strlen(color); i++)
printf("%c ", color[i]);
printf("\n");
//标记移动过程中,主要是wFlag一直在向后移,直到与rFlag指向同一位置,循环结束,分类完成
while(wFlag <= rFlag)
{
if(color[wFlag] == WHITE)//若wFlag指向白色,则wFlag向后移一位
wFlag++;
else if(color[wFlag] == BLUE)//若wFlag指向蓝色,则交换,再将bFlag与wFlag都向后移一位
{
SWAP(bFlag, wFlag);
bFlag++;
wFlag++;
}
else
{
while(wFlag < rFlag && color[rFlag] == RED)//若rFlag指向红色,将rFlag向前移一位
rFlag--;//表示红色未处理部分减1
SWAP(rFlag, wFlag);
rFlag--;
}
}
for(i = 0; i < strlen(color); i++)
printf("%c ", color[i]);
printf("\n");
return 0;
}
三、
分析
wFlag、bFalg rFlag
| |
起初 r w b w w b r b w r
wFlag、bFalg rFlag
| |
r w b w w b r b w r
wFlag、bFalg rFlag
| |
w w b w w b r b r r
wFlag bFalg rFlag
| | |
w w b w w b r b r r
wFlag bFalg rFlag
| | |
w w b w w b r b r r
wFlag bFalg rFlag
| | |
b w w w w b r b r r
wFlag bFalg rFlag
| | |
b w w w w b r b r r
wFlag bFalg rFlag
| | |
b w w w w b r b r r
wFlag bFalg rFlag
| | |
b b w w w w r b r r
wFlag bFalg 、 rFlag
| |
b b w w w w b r r r
wFlag rFlag bFalg
| | |
结束 b b b w w w w r r r
四、效果展示