荷兰国旗问题(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

转载于:https://www.cnblogs.com/freelancy/p/7940803.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值