我实施荷兰国旗算法有什么问题?

时间:2015-03-29 02:35:21

标签: java algorithm

Here's the original question

  

给你一个有n个整数的数组,它有正数和   负整数。现在你需要以一种特殊的方式对这个数组进行排序。之后   那个,负整数应该在前面,而正面   整数应该在后面。也不应该相对位置   改变。   例如。 -1 1 3 -2 2 ans:-1 -2 1 3 2.

我的Java代码(翻译自Wikipedia's pseudocode

package ThreewayPartition;

import java.util.Arrays;

public class ThreewayPartition {
    public void sort(int[] input, int mid) {
        int i=0;
        int j=0;
        int n = input.length - 1;

        while (j <= n) {
            if (input[j] < mid) {
                swap(input, i, j);
                i++;
                j++;
            } else if (input[j] > mid) {
                swap(input, j, n);
                n--;
            } else {
                j++;
            }
        }
    }

    private void swap(int[] arr, int j, int k) {
        int tmp = arr[j];
        arr[j] = arr[k];
        arr[k] = tmp;
    }

    public static void main(String[] args) {
        int[] input = {-1, 1, 3, -2, 2};
        ThreewayPartition twp = new ThreewayPartition();
        twp.sort(input, 0);
        System.out.println(Arrays.toString(input));
    }
}

我得到此输出:[-1, -2, 3, 2, 1]而不是[-1, -2, 1, 3, 2]

3 个答案:

答案 0 :(得分:0)

Your swap() method is swapping elements, not shifting.

您可以修改排序方法,如下所示 -

public void sort(int[] input, int mid) {
    int n = input.length - 1;
    int i=0;
    int tmpvar;
    while (n >= i) {
        if(input[n] < mid) {
            tmpvar = input[n];
            System.arraycopy(input, 0, input, 1, n);
            input[0] = tmpvar;
            i++;
        } else {
            n--;
        }
    }
}

答案 1 :(得分:0)

可能实施没有任何问题 - 只是荷兰国旗原地分区不稳定

答案 2 :(得分:0)

我查看了Wikipedia's pseudocode,发现midsort()的使用不正确。它应该用作值,即input[mid]

话虽如此,荷兰国旗算法不是stable,并且不能满足问题中的约束条件:

相对位置不应更改

但是,重要的是要提到该问题是DNF算法的一种变体。

因此,您正在寻找以下几方面的内容:

import java.util.Arrays;

public class ThreewayPartition{

    public static void sort(int[] A, int mid) {
        int startIndex = 0;

        for (int i = 0; i < A.length; i++) {
            if (A[i] <= mid) {
                int temp = A[i];
                for (int j = i; j > startIndex; j--) {
                    A[j] = A[j-1];
                }
                A[startIndex] = temp;

                if (temp < mid) startIndex++;
            }
        }
    }

    public static void main(String[] args) {
        int[] input = {-1, 1, 3, -2, 2};
        ThreewayPartition twp = new ThreewayPartition();
        twp.sort(input, 0);
        System.out.println(Arrays.toString(input));  // [-1, -2, 1, 3, 2]
    }
}

请注意,代码的时间复杂度为O(n*n)

更高效,更复杂的时间O(n),并且更易于理解:

import java.util.Arrays;

public class ThreewayPartition{

    public static void sort(int[] A, int mid) {

        for (int i = A.length - 1; i > 0; i--) {
            if (A[i] <= mid && A[i - 1] > mid) {
                swap(A, i, i-1);
            }
        }
    }

    private static void swap(int[] arr, int j, int k) {
        int tmp = arr[j];
        arr[j] = arr[k];
        arr[k] = tmp;
    }

    public static void main(String[] args) {
        int[] input = {-1, 1, 3, -2, 2};
        ThreewayPartition twp = new ThreewayPartition();
        twp.sort(input, 0);
        System.out.println(Arrays.toString(input));  // [-1, -2, 1, 3, 2]
    }
}