我需要一种算法来选择 k 最大值或最小值。值将是整数。我的导师告诉我使用修改的分区算法来找到 k 最大或最小值。有什么想法吗?
答案 0 :(得分:4)
以下是quickselect算法的说明。我假设你想要找到 k 最小的值。
获取数组的第一个元素。这将是你的支点。跟踪其位置。
根据此数据透视表对数组进行分区。小于枢轴的元素在阵列中的枢轴之前移动;在你的支点之后更大。 (此步骤将移动您的轴。跟踪其在阵列中的位置。)
您现在知道您的支点大于pivot_position
个元素数。因此,您的数据透视表是(pivot_position + 1
)最小元素。
如果 k 等于pivot_position + 1
,那么您已找到 k 的最小值。恭喜,请将pivot_position
作为该值在数组中的位置。
如果 k 小于pivot_position + 1
,您需要的某些值小于您的支点。在您的轴之前查看数组中 k 最小值的部分。
如果 k 大于pivot_position + 1
,您需要的某些值大于您的支点。在您的轴之后查看数组中* k - (pivot_position
+ 1)*最小值的部分(因为该部分数组排除了(pivot_position
+ 1)最小值)。
由于你正在使用C ++,你应该按如下方式实现你的功能:
int select(int *array, int left, int right, int k);
int partition(int *array, int left, int right, int pivot_position);
select
获取您的数组,左右边界和 k 。澄清一下,array[left]
将是第一个元素; array[right]
将是最后一个; right - left + 1
将是数组的长度。 select
返回 k 最小元素的位置。
partition
获取数组,左右边界以及数据透视的起始位置。每次只传递0 pivot_position
是安全的,这意味着你想要使用数组中的第一个元素作为数据透视表。 (在一个名为randomized quickselect的变体中,您选择一个随机pivot_position
。)partition
在您完成移动后返回枢轴的位置。
答案 1 :(得分:1)
STL有一个partial_sort
函数,它会对序列的前k个项进行排序,并允许您通过简单的查找来获取该项。
换句话说,寻找std::partial_sort
,其余的将是显而易见的。
STL中还有一个nth_element
函数。我相信你可以弄清楚如何使用它。