【问题标题】:Why choose a random pivot in quicksort为什么在快速排序中选择随机枢轴
【发布时间】:2015-05-01 02:40:12
【问题描述】:
因此,随机选择枢轴在最坏情况下运行O(n 2 sup>),但选择枢轴作为最小值和列表的最大值的平均值时,您可以获得最坏的情况o (n log n)。

当然,每次递归都会增加 2*O(n),因为要找到最小值和最大值,而不是随机生成器的常数 O(1)。将其实现为枢轴时,您会得到在递归树的叶子上排序的列表,而不是在标准算法中,元素从根到叶子进行排序。

当实现而不是将枢轴作为列表中的一个值时,它只是一个与之相比的数字,因此这不是标准的快速排序,但我的问题仍然适用。

下面是我写得不好的伪代码:

func sort(List n):
    if n.length < 2
     return n;
    min = n.minValue
    max = n.maxValue
    avg = (min+max) /2 
    List left = list of elements in n less than avg
    List right = list of elements in n greater than avg
    sort(left)
    sort(right)

【问题讨论】:

  • 对英语不好的朋友感到抱歉
  • 恐怕您需要重新表述问题的主体。第一段描述了随机和真实中值快速排序的工作原理。第二段似乎包含你的实际问题,但它是不可理解的。您能否尝试澄清您在第二段中的要求?
  • 您的问题是什么?你的问题是我们为什么不使用像你的伪代码这样的东西而不是随机快速排序?
  • 从您的措辞方式来看,听起来您是在说随机枢轴查看列表中的所有值,并从中选择一个随机值。但是枢轴只是列表中的一个随机位置,不需要 O(n^2) 来计算。
  • 您的问题是基于错误的前提。 "When the pivot is chosen as the average of min value and max value of the list you get a worst case O(n log n)" is simply untrue.你得到 O(n log n) 的 平均 行为,但你得到它的时间要多得多。仍然存在行为为 O(n^2) 的退化案例。 某些枢轴选择的问题是退化案例之一是已经排序的案例,这很常见。而且没有 '2*O(n)' 这样的东西。

标签: algorithm sorting quicksort


【解决方案1】:

当列表包含以下元素时,如果您选择最小值和最大值的平均值作为枢轴,则您的算法会受到 O(n2) 的影响:

1, 3, 7, 15, 31, 63, ..., 2n-1

您会发现,对于您的算法的每一次通过,right 部分始终只有 1 个元素。

【讨论】:

    【解决方案2】:

    三件事:

    1. 您可以在一次遍历列表中获得最大值和最小值,因此实际上我们为每次遍历添加 1*O(n)。不过……

    2. 最大值和最小值的平均值不能保证 O(nlog(n)),因为最大值和最小值的平均值不一定是中值。如果您有一个已经排序的列表(1,10,100,1000,10000),这实际上会给出 O(n^2) 的解决方案,这对于已经排序的列表来说非常糟糕(并且很有可能发生)。

    3. 从统计上来说,选择一个随机枢轴可能会给您带来接近中位数的结果。从列表中取一个随机数,50% 的时间这个数字在列表的中间 50%,这意味着在最坏的情况下,它有 75% 的列表在一边,25% 在另一边。显然,当我们选择更接近真实中值时,性能会更好。

    【讨论】:

      猜你喜欢
      • 2018-11-14
      • 2010-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-31
      • 2019-11-23
      相关资源
      最近更新 更多