看不懂快速选择算法

Posted

技术标签:

【中文标题】看不懂快速选择算法【英文标题】:Cant understand Quick Select Algorithm 【发布时间】:2014-03-16 07:02:56 【问题描述】:

我在理解快速选择算法时遇到了问题。我知道它基于快速排序算法(我很熟悉),它可以为您提供所需的结果,可能会使数组的一部分未排序。现在这是我遇到困难的地方。问题是从数组中找到第二小的元素:

int a[4] = 1,3,5,2 ;

现在假设我们随机选择枢轴然后根据this post我们有以下条件:

k == pivot。那么你已经找到了第 k 个最小的了。这是因为分区的工作方式。正好有 k - 1 个元素小于第 k 个元素。

k < pivot。那么第k个最小的在pivot的左边。

k > pivot。然后第 k 个最小的在枢轴的右侧。要找到它,您实际上必须找到右侧的 k-pivot 最小数字。

如果有人能解释k==pivot 如何意味着我们找到了第 k 个(在我的例子中是第二个最小的元素),我将不胜感激。此外,如果它的k < pivot 我们是否对枢轴左侧重复该过程?

【问题讨论】:

【参考方案1】:

如果 k = pivot,则 pivot 左侧将有 k-1 个项目。由于分区,这些中的每一个都小于枢轴项。此外,由于分区,右侧的每个项目都大于枢轴项目。因此,枢轴项目必须是第 k 个最大的。有意义吗?

【讨论】:

【参考方案2】:

是的,当 pivok == k 时,您在枢轴左侧有k-1 元素小于 比枢轴,所以您找到了数组中的k-th 最小数字,即枢轴, 但是如果 k < pivot ,在数组的左侧搜索,因为枢轴 > 第 k 个最小元素,否则枢轴 数组的第 k 个最小元素,所以在右侧搜索以增加枢轴. 来自wikipedia:

// Returns the n-th smallest element of list within left..right inclusive (i.e. n is zero-based).
  function select(list, left, right, n)
     if left = right        // If the list contains only one element
         return list[left]  // Return that element
     pivotIndex  := ...     // select a pivotIndex between left and right, e.g. left + Math.floor(Math.random() * (right - left + 1))
     pivotIndex  := partition(list, left, right, pivotIndex)
     // The pivot is in its final sorted position
     if n = pivotIndex
         return list[n]
     else if n < pivotIndex
         return select(list, left, pivotIndex - 1, n)
     else
         return select(list, pivotIndex + 1, right, n)

希望这会有所帮助!

【讨论】:

以上是关于看不懂快速选择算法的主要内容,如果未能解决你的问题,请参考以下文章

不要再问我贪心算法了!看不懂找我要红包

c语言中算每月第一天是周几的算法看不懂,请大神指教

js算法初窥01(排序算法01-冒泡选择插入)

不懂算法的程序员不是好工程师--选择排序

不懂算法的程序员不是好工程师--选择排序

看不懂的算法系列