创建部分排序的数组

时间:2017-08-05 16:46:35

标签: arrays algorithm

我正在通过Sedgewick和Wayne的算法,第4版。(这不是作业。)

其中一个练习(2.1.37)是编写一个生成部分排序数组的客户端,其中所有条目都在数组中最终位置的10个位置内。

我的进展如下:

如果我们想将数字0到N放在数组[a[0], a[1], ... a[N]],中,那么我们首先将0放在从0到10(包括0和10)的随机索引中。然后,我们将1放在从0到11等随机未占用的索引中,11从1到21的未占用索引中等等。很明显,直到N-10,所有条目将至少有一个未占用的位置但是,我无法看到这是否适用于最后10个条目,因为它们的所有可用位置都可以假设已被前面的数字填满。

我的推理是否正确?我的算法是否有效,我无法证明它,或者它失败了吗?如果它失败了,那么正确的方法是什么?

1 个答案:

答案 0 :(得分:0)

你是对的 - 它可能不起作用。

有几种方法可以解决这个问题,但我要尝试的第一件事就是修改Fisher–Yates shuffle,例如

之类的东西
int[] fuzzyRange(int size, int fuzz, Random rng) {
    int[] arr = IntStream.range(0, size).toArray();
    for (int i = 0; i < size; i++) {
        // Normal Fisher-Yates would pick a random index in [i, arr.length) for
        // swapping. This instead picks a random index in [i, i+fuzz] where both
        // swapped elements stay within fuzz of their starting indices.
        int j = i, n = 1;
        for (int k = i + 1; k < arr.length && k < i + fuzz; k++) {
                if (k - fuzz <= arr[i] && arr[i] <= k + fuzz &&
                    i - fuzz <= arr[k] && arr[k] <= i + fuzz &&
                    rng.nextInt(++n) == 0) {
                    j = k;
                }
        }
        if (i != j) {
            int tmp = arr[i];
            arr[i] = arr[j];
            arr[j] = tmp;
        }
    }
    return arr;
}

(未测试)。不过,我不确定这是否会以相同的概率产生所有合法的紊乱。