作者:gnuhpc
出處:http://www.cnblogs.com/gnuhpc/
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。
3.解決代碼:
/*
* =====================================================================================
*
* Filename: Dutchflag.cpp
*
* Description:
*
* Version: 1.0
* Created: 02/25/2011 09:31:21 AM
* Revision: none
* Compiler: gcc
*
* Author: gnuhpc , warmbupt@gmail.com
*
* =====================================================================================
*/
#include <iostream>
#include <stdlib.h>
using namespace std;
#define N 10
void swap (int &var1, int &var2)
{
int temp = var1;
var1 = var2;
var2 = temp;
}
void shuffle(int *array)
{
int current = 0;
int end = N-1;
int begin = 0;
while( current<=end )
{
if( array[current] ==0 )
{
swap(array[current],array[begin]);
current++;
begin++;
}
else if( array[current] == 1 )
{
current++;
}
else{//When array[current] =2
swap(array[current],array[end]);
end--;
}
}
}
int main(int argc, char *argv[])
{
int a[N];
int i;
for( i=0 ; i<N; i++ )
{
a[i] = rand()%3;
cout << a[i] << " ";
}
cout << endl;
shuffle(a);
for( int i=0 ; i<N ; i++ )
{
cout << a[i] << " ";
}
cout << endl;
return 0;
}