三色旗問題演算法解析
阿新 • • 發佈:2018-11-07
- 問題: 在一根繩子上有一些紅,白,藍三種顏色的旗子,現在要把這些旗子按照 藍,白,紅的順序排序.
**要求:**旗子只能在繩子上移動,一次只能掉換兩個旗子位置
程式碼:
#define BLUE 'b'
#define WHITE 'w'
#define RED 'r'
//交換 x,y位置的旗子
#define SWAP(x,y) { char temp; \
temp = color[x]; \
color[x] = color[y]; \
color[y] = temp;}
void threeColorFlag() {
char color[] = {'b','r', 'w', 'b', 'w', 'w','b', 'r', 'b', 'w', 'r', '\0'};
int wFlag = 0;
int bFlag = 0;
int rFlag = strlen(color) - 1;
int i;
for(i = 0; i < strlen(color); i++) printf("%c ", color[i]);
printf("\n");
while (wFlag <= rFlag) {
if(color[wFlag] == WHITE)
wFlag++;
else if(color[wFlag] == BLUE) {
SWAP(bFlag, wFlag);
bFlag++; wFlag++;
}
else {
while(wFlag < rFlag && color[rFlag] == RED){
rFlag--;
}
SWAP(rFlag, wFlag); rFlag--;
}
}
for(i = 0; i < strlen(color); i++)
printf("%c ", color[i]);
printf("\n");
}
- 理解:開始的時候,建立三個位置指示器,藍色bFlag和白色指示器wFlag指向開始位置,紅色指示器rFlag指向末尾位置
注意:因為白色旗子是要放在中間的,所以wFlag作為遊標來遍歷所有未排序的旗子,藍色指示器始終指向當前藍色旗子的下一個位置,紅色指示器始終指向紅色旗子的上一個位置
wFlag從第一個旗子開始判斷該旗子的顏色,如果該旗子顏色是白色則wFlag ++,即指向下一面旗子,判斷下一面旗子的顏色,如果旗子顏色是藍色,則把該旗子和bFlag位置的旗子掉換位置,然後wFlag和bFlag都++,此時bFlag指向已經排好位置的藍色旗子的下一個位置,如果有藍色旗子和這個位置的旗子換位的話即把新的藍色旗子放在排好序的藍色旗子後面, wFlag始終指向下一面未排序的旗子;如果wFlag指向的旗子是紅色,則判斷wFlag < rFlag和rFlag位置的旗子是否是紅色,如果成立則把rFlag–,表示原先位置已經是紅色旗子,此時rFlag指向拍好序的紅色旗子的前一個位置,因為rFlag始終指向已經排好序的紅色旗子的上一個位置,所以,若果wFlag < rFlag不成立的話即表示所有旗子已經排序完畢,如果rFlag位置不是紅色旗子的話,則把wFlag位置的紅色旗子和rFlag位置的旗子交換位置,rFlag–仍然指向已經交換的紅色旗子前一個位置,繼續判斷wFlag位置旗子,直到wFlag>rFlag的時候,表示所以旗子已經排序完畢