荷兰国旗问题(Dutch National Flag Problem)

问题描述


  • 给定数组中只有“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
posted @ 2017-12-01 10:41  Freelancy  阅读(1099)  评论(0编辑  收藏  举报