Bucket Sort近乎完美的分布模型

时间:2015-01-28 08:38:38

标签: algorithm sorting bucket-sort

我试图理解用于桶排序的算法,并且我发现如果没有正确的分布模型,我们可以获得O(n ^ 2)的复杂度。相当多的网站的桶数等于数组的大小(比如说' n')并使用算法

std::vector<float> bucket[n];
for (int i = 0; i<n; i++){
  bucket[(array[i]*n)/(MAX_ELEMENT_IN_INPUT_ARRAY+1)].push_back(array[i]);
}

我知道整数可以是随机的,并且没有完美的散列算法,但我不太了解上述算法如何将元素分配到各自的桶中。我是否错过了一个直截了当的逻辑?

1 个答案:

答案 0 :(得分:1)

以上代码保证均匀分布。例如,假设您有一个由n个元素组成的输入数组,数字为1,2,4,8,16,32,...,2 n-1 。现在,让我们考虑一下这些元素的最终结果。让我们选择一个元素,比如2 k 。其桶指数由

给出
  

2 k ·n /(2 n-1 + 1)

这里引起警报的原因是1 /(2 n - 1)与n相比是一个非常非常小的数字。因此,我们预计大部分元素将会被分配到非常低的桶数中,并且我们的分散性会很差。

让我们在1,2,4,8,16,32,64,128上尝试一下。我们将总共有8个桶。元素映射如下:

  • 1被放入存储桶1 * 8 / 129 = 8 / 129 = 0
  • 2被放入存储桶2 * 8 / 129 = 16 / 129 = 0
  • 4被放入存储桶4 * 8 / 129 = 32 / 129 = 0
  • 8被放入存储桶8 * 8 / 129 = 64 / 129 = 0
  • 16被放入存储桶16 * 8 / 129 = 128 / 129 = 0
  • 32被放入存储桶32 * 8 / 129 = 256 / 129 = 1
  • 64被放入存储桶64 * 8 / 129 = 512 / 129 = 3
  • 128被放入存储桶128 * 8 / 129 = 1024 / 129 = 7

正如您所看到的,这里的八个元素中有五个被放入了存储桶0中,并且大多数存储桶都没有使用。

更一般地说,如果你有这个序列的n个元素,那么只会使用桶n - 1(n - 1) / 2(n - 1) / 4(n - 1) / 8等。这种形式只有大约log n桶,这意味着关于n - log n个元素将被丢弃到桶0中,并且只有大约log n个元素将存在于其他桶中。

据我所知,没有一个公式可以为您提供良好的分配。如果你假设数字在一个区间内均匀分布,那么这里给出的公式很有效,正如你所看到的,如果你给出指数分布的数字,你最终会得到一个非常糟糕的最坏情况行为。