问题描述
- 给定数组中只有“1”,“2”,“3”三种数字,且个数不等
- 排序
- 最终结果的顺序为:所有的1在前,所有的2在中间,所有的3在后
- 如:原数组:1232313231,排序后:1112223333
解决思路
- 将前部和后部各排在数组的前边和后边,中部自然就排好了。
算法伪代码
Status Sort(int L[], int n) {
// 荷兰国旗问题
// 数组L[n], 有n个数
// red, white, blue 分别为1,2,3,正好组成荷兰国旗
int r = 0, w = 0, b = n-1;
while(w <= b){
x = L[w];
if(x == 1){// 若为前排的数字,则调换到前排
L[w] = L[r]; L[r] = x;// 交换“0” “1”
w ++; r++;// 指向前排和中排的游标增1
}
else if(x == 2){// 若为中间的数字,则不处理
w ++;
}
else{// 若为后排的数字,则调换到后排
L[w] = L[b]; L[b] = x;
b --;// 指向后排的游标减一
}//else
}//for
return OK;
}
Java
public class DutchNationalFlag {
/**
* 通过荷兰国旗算法排序只含有1,2,3的数组
*
* @param arr 数组
*/
public static void dutchNationalFlagProblem(int[] arr) {
// red, white, blue
int r = 0;
int w = 0;
int b = arr.length - 1;
while (w <= b) {
int x = arr[w];
if (x == 1) {// 若为前排的数字,则调换到前排
arr[w] = arr[r];
arr[r] = x;// 交换“0” “1”
w++;
r++;// 指向前排和中排的游标增1
} else if (x == 2) {// 若为中间的数字,则不处理
w++;
} else {// 若为后排的数字,则调换到后排
arr[w] = arr[b];
arr[b] = x;
b--;// 指向后排的游标减一
}
}
}
}
public class Test {
public static void main(String[] args) {
// 初始的数组
int[] arr = {1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 3, 2, 1};
// 使用荷兰国旗算法进行排序
DutchNationalFlag.dutchNationalFlagProblem(arr);
// 打印排序后的结果
for (int a : arr)
System.out.println(a);
}
}
1
1
1
1
1
1
1
1
1
1
2
2
2
2
2
2
2
2
2
2
3
3
3
3
3
3
3
3
3
3