題目
現有紅、白、藍三個不同顏色的小球,亂序排列在一起,請重新排列這些小球,使得紅白藍三色的同顏色的球在一起。問題分析
問題轉換為:給定陣列a[0...n-1],元素只能取0、1、2三個值,設計演算法,使得陣列排列成「00...0011...1122...22」的形式借鑑快速排序中partition的過程,定義三個指標begin=0,current=0,end=n-1
a[cur]==2,則a[cur]與a[end]交換,end--,cur不變
a[cur]==1,則cur++,begin不變,end不變
a[cur]==0,則:
若begin==cur,則begin++,cur++
若begin!=cur,則a[cur]與a[begin]交換,begin++,cur不變
**如下
void holland1(int* a, int length)
else if (a[current] == 1)
else
else
}}}
第二個版本:
cur掃過的位置,即:[begin,cur)區間內,一定沒有2
因此:a[begin]要麼是0,要麼是1,不可能是2在前面的a[cur]==2中,已經被替換到陣列後面了
考察begin指向的元素的值:
歸納法:若begin!=cur,則必有a[begin]=1因此,當a[cur]==0時,
若begin==cur,則begin++,cur++;
若begin!=cur,因為a[begin]==1,則交換後,a[cur]==1,此時,可以cur++;
void holland2(int* a, int length)
else if (a[current] == 1)
else
else
}}}
終極版本
void holland(int* a, int length)
else if (a[current] == 1)
else
begin++;
current++;
} }}
荷蘭國旗問題擴充套件
將0/1/2分別計數,根據三個計數值c0/c1/c2:前c0個元素賦值為0,中間c1個元素賦值為1,最後c2個元素賦值為2;實際意義比較小,可能排序結構比較複雜的時候就用著不方便了
將(0,1)(2)根據快速排序的partition,劃分為兩部分(如pivotkey1.5);將(0)(1)根據快速排序partition,分成兩部分(如pivotkey選擇0.5);那麼可以得到結論「兩次partition==一次荷蘭國旗」,這樣可以優化快速排序的partition過程
優化快速排序根據pivotkey分成大於、小於等於兩部分或者大於等於、小於兩部分根據pivotkey的大小,將partition過程蓋在成大於、等於、小於三部分
優點:對於快速排序的等於pivotkey的數值,可以在執行下一次partition時直接跳過,利於資料規模的降低
演算法 荷蘭國旗問題
荷蘭國旗是由紅白藍3種顏色的條紋拼接而成,如下圖所示 假設這樣的條紋有多條,且各種顏色的數量不一,並且隨機組成了乙個新的圖形,新的圖形可能如下圖所示,但是絕非只有這一種情況 需求是 把這些條紋按照顏色排好,紅色的在上半部分,白色的在中間部分,藍色的在下半部分,我們把這類問題稱作荷蘭國旗問題。我們把荷...
演算法之荷蘭國旗問題
問題描述 荷蘭國旗有三橫條塊構成,自上到下的三條顏色依次為紅,白,藍。現有若干由紅,白,藍三種顏色的條塊序列,要將它們重新排列使所有相同顏色的條塊在一起。本問題要求將所有紅色的條塊放在最左邊,所有白色的條塊放在中間,所有藍色的條塊放在最右邊。解決辦法 將三種顏色放入乙個數字中,前部分為紅色,中間部分...
演算法習作 荷蘭國旗問題
出處 1.問題描述 我們將亂序的紅白藍三色小球排列成有序的紅白藍三色的同顏色在一起的小球組。這個問題之所以叫荷蘭國旗,是因為我們可以將紅白藍三色小球想象成條狀物,有序排列後正好組成荷蘭國旗。2.問題分析 這個問題我們可以將這個問題視為乙個陣列排序問題,這個陣列分為前部,中部和後部三個部分,每乙個元素...