我有一个问题,理解快速选择算法。我知道它是基于快速排序算法(我很熟悉),它给你所需的结果,可能会留下数组的一部分未排序。这就是我遇到困难的地方。问题是找出数组中第二小的元素也就是
int a[4] = {1,3,5,2} ;
现在假设我们随机选择pivot,那么根据这篇文章,我们有以下条件:
k == pivot
。那么你已经找到了第k个最小值。这是因为分区的工作方式。 有k - 1个元素小于第k个元素。k < pivot
。k > pivot
。第k个最小的在主元的右边。要找到它,你必须找到k-主元最小值
如果有人能解释k==pivot
意味着我们已经找到了第k(在我的情况下是第二小的元素),我会很感激。如果它是k < pivot
,我们是否对左侧的枢轴重复此过程?
如果k = pivot,则pivot左侧将有k-1个项。多亏了分划,每一项都小于主项。而且,由于分区,右边的每一项都大于主项。因此主元素一定是第k大的。有道理吗?
是的,当pivok == k
时,你在枢轴左侧有k-1
元素小于,所以你找到了数组中k-th
最小的元素,即枢轴,但如果k < pivot
,在数组的左侧搜索,因为pivot >第k个最小的元素,否则pivot <第k个最小的元素,所以在数组的右侧搜索以增加枢轴。
来自维基百科:
// 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)