荷兰国旗

现有n个红白蓝三种不同颜色的小球,乱序排列在一起,请通过两两交换任意两个球,使得从左到右依次为红球、白球、蓝球。

可以借鉴快速排序的思路,先看三路快速排序的实现


三路快速排序法

适用于有大量重复元素的排序。

public class Quick3Way {
    public static void sort(Comparable[] a)
    {
        sort(a, 0, a.length-1);
    }

    private static void sort(Comparable[] a, int lo, int hi)
    {   

        int M = 5;
        if(hi <= lo + M) //小数组切换到插入排序 
        {
            int N = hi - lo + 1;
            for(int i = 1; i < N; i++)
            {
                for(int j = i; j > 0 && less(a[j], a[j-1]); j--)
                    exch(a, j, j-1);
            }
            return;
        }

        int lt = lo, i = lo + 1, gt = hi;
        Comparable v = a[lo];
        while(i <= gt)
        {
            int cmp = a[i].compareTo(v);
            if(cmp < 0)
                exch(a, lt++, i++);
            else if(cmp > 0)
                exch(a, i, gt--);
            else
                i++;
        }
        sort(a, lo, lt-1);
        sort(a, gt + 1, hi);

    }

    private static boolean less(Comparable v, Comparable w)
    {
        return v.compareTo(w) < 0;
    }

    private static void exch(Comparable[] a, int i, int j)
    {
        Comparable t = a[i];
        a[i] = a[j];
        a[j] = t;
    }

    private static void show(Comparable[] a)
    {
        for(int i = 0; i < a.length; i++)
            System.out.print(a[i] + " ");
        System.out.println();
    }

    public static boolean isSorted(Comparable[] a)
    {
        for(int i = 1; i < a.length; i++)
            if(less(a[i], a[i-1]))
                return false;
        return true;
    }

    public static void main(String[] args)
    {
        String[] a = {"S", "O", "R", "T", "E", "X", "A", "M", "P", "L", "E"};
        sort(a);
        isSorted(a);
        show(a);
    }
}
荷兰国旗问题三指针法

为了方便讨论,用数字0表示红球,数字1表示白球,数字2表示篮球。所以最后问题转换为数字排列0、1、2.

  • 当current指针所指元素为0时,与begin指针所指元素交换,而后current++, begin++;
  • 当current指针所指元素为1时,不做任何交换,而后current++;
  • 当current指针所指元素为2时,与end指针所指元素交换,而后current指针不动,end–。
import java.util.Arrays;

public class ThreePointSortTest {
    private static void ThreePointSort(int a[])
    {
        int begin = 0;
        int current = 0;
        int end = a.length - 1;

        while(current <= end)
        {
            if(a[current] == 0)
            {
                int t = a[current];
                a[current] = a[begin];
                a[begin] = t;
                current++;
                begin++;
            }

            else if(a[current] == 1)
                current++;

            else
            {
                int t = a[current];
                a[current] = a[end];
                a[end] = t;
                end--;
            }
        }
    }

    public static void main(String[] args)
    {
        int a[] = {0,1,2,1,2,1,0,0,1,2,0,2,1};
        ThreePointSort(a);
        System.out.println(Arrays.toString(a));
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值