【问题标题】:Near perfect distribution model for Bucket Sort桶排序的近乎完美的分布模型
【发布时间】:2015-01-28 08:38:38
【问题描述】:

我试图理解桶排序的算法,我突然想到,如果没有正确的分布模型,我们可以获得 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]);
}

我知道整数可以是随机的,并且没有完美的散列算法,但我不太明白上述算法如何将元素平均分配到各自的桶中。有没有我遗漏的直截了当的逻辑?

【问题讨论】:

  • 码snap代表均匀分布,根据这个假设,x=array[i]/(MAX_ELEMENT_IN_INPUT_ARRAY+1)是均匀分布x~U[0,1)(含零,不含1)。因此,n*x 均匀分布在[0,n)

标签: algorithm sorting bucket-sort


【解决方案1】:

上面的代码保证均匀分布。例如,假设您有一个由 n 个元素组成的输入数组,这些元素分别是数字 1、2、4、8、16、32、...、2n-1。现在,让我们考虑一下这些元素将在哪里结束。让我们选择一个元素,比如 2k。它的桶索引由下式给出

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

这里引起警报的原因是 1 / (2n - 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

如您所见,这里的 8 个元素中有 5 个被丢弃到了 0 号桶中,并且大部分桶都没有使用。

更一般地说,如果您有 n 个具有此序列的元素,那么只有桶 n - 1(n - 1) / 2(n - 1) / 4(n - 1) / 8 等会被使用。这种形式的桶只有约 log n 个,这意味着约 n - log n 个元素将被放入桶 0 中,只有约 log n 个元素将在其他桶中。

据我所知,没有任何一种公式可以始终为您提供良好的分布。如果您假设数字在一个区间内均匀分布,则此处给出的公式效果很好,并且如您所见,如果您给出指数分布的数字,您最终会得到一个非常糟糕的最坏情况行为。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-02
    • 2015-07-24
    • 1970-01-01
    • 1970-01-01
    • 2013-03-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多