【问题标题】:Randomized Hoare Partition - Wrong partition on certain indices随机霍尔分区 - 某些索引上的分区错误
【发布时间】:2015-04-07 01:43:02
【问题描述】:

我确实尝试了所有方法,尝试了所有解决方案,但仍然无法正常工作。似乎 Hoare 分区仅在某些情况下有效,但有时我什至不明白它在做什么。 是的,我知道算法是如何工作的,但是实施明智吗?老实说,我不知道它是如何尝试分区的。所以,这是我的测试数组:

2, 30, 1, 99, 46, 33, 48, 67, 23, 76

我首先尝试实现经典算法:

private int hoarePartition(int l, int r) {
    int pivot = array[l];
    while (true) {
        int i = l - 1, j = r + 1;
        do {
            --j;
        } while (array[j] > pivot);

        do {
            ++i;
        } while (array[i] < pivot);

        if (i < j) {
            int temp = array[i];
            array[i] = array[j];
            array[j] = temp;
        } else {
            System.out.println(Arrays.toString(array));
            return j;
        }
    }
}

private int randomizedPartition(int l, int r) {
    int pivot = generator.nextInt(r - l + 1);

    int temp = array[l];
    array[l] = array[pivot];
    array[pivot] = temp;

    return hoarePartition(l, r);
}

Test cases: [2, 30, 1, 99, 46, 33, 48, 67, 23, 76]

Random Pivot | Partitioned Array                      | Status
0 - [  2 ]     [1, 2, 30, 99, 46, 33, 48, 67, 23, 76]   OK
1 - [ 30 ]     [23, 2, 1, 30, 46, 33, 48, 67, 99, 76]   OK
2 - [  1 ]     [1, 30, 2, 99, 46, 33, 48, 67, 23, 76]   OK
3 - [ 99 ]     [76, 30, 1, 2, 46, 33, 48, 67, 23, 99]   OK
4 - [ 46 ]     [23, 30, 1, 33, 2, 46, 48, 67, 99, 76]   OK
5 - [ 33 ]     [23, 30, 1, 2, 33, 46, 48, 67, 99, 76]   OK
6 - [ 48 ]     [23, 30, 1, 2, 46, 33, 48, 67, 99, 76]   OK
7 - [ 67 ]     [23, 30, 1, 2, 46, 33, 48, 67, 99, 76]   OK
8 - [ 23 ]     [2, 1, 23, 99, 46, 33, 48, 67, 30, 76]   OK
9 - [ 76 ]     [2, 30, 1, 23, 46, 33, 48, 67, 76, 99]   OK

随机枢轴选择应该是 (r - l + 1)。有了这个修改,它终于可以工作了。

【问题讨论】:

  • p 代表枢轴,r 代表什么?你是如何选择支点的?
  • 我修改了代码,使其更具可读性。

标签: java algorithm


【解决方案1】:

你生成一个不必在 [p,q] 中的数字:

int i = (p + generator.nextInt(q)) % (q - p);

i 生成的数字在[0,q-p] 范围内,例如p=6,q=10 显然是错误的

你要找的是:

int i = (p + generator.nextInt(q-p+1)); //assuming q>p here

这将在[p+0,p+q-p] = [p,q]中生成一个随机数


附带说明一下,使用l,r 代替p,q 会稍微更具可读性,并且在命名变量时尽量保持一致(两种方法中的q/r 作用相同,没有理由两个不同的名称)

【讨论】:

  • (q - p + 1) 是准确的。请更新你的答案,我会接受它,因为你把我扔到了正确的方向。
  • @Wrath 这取决于你是要独占还是包容,我假设是 q 独占,但这也可以。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-04
  • 1970-01-01
  • 2014-12-30
  • 2016-04-15
  • 2012-12-09
  • 2017-03-15
相关资源
最近更新 更多