我们怎样才能找到数组中最重要的元素?

时间:2010-06-26 14:45:21

标签: c algorithm

使用数据结构自平衡二分查找树查找数组中第n个最小/最大元素的算法..

阅读帖子:Find kth smallest element in a binary search tree in Optimum way。但正确的答案并不清楚,因为我无法弄清楚正确的答案,我拿了一个例子......请多说明一点......

7 个答案:

答案 0 :(得分:13)

C.A.R。 Hoare的select算法就是为了这个目的而设计的。它在[预期]线性时间内执行,具有对数额外存储。

编辑:排序的明显替代方案,然后选择正确的元素具有O(N log N)复杂度而不是O(N)。以排序顺序存储i个最大元素需要O(i)辅助存储,并且大致为O(N * i log i)复杂度。如果i已知先验非常小(例如1或2),则此可以获胜。对于更一般的用途,select通常更好。

Edit2:offhand,我没有很好的参考,但在previous answer中描述了这个想法。

答案 1 :(得分:2)

首先对数组进行降序排序,然后取i个元素。

答案 2 :(得分:0)

创建一个排序数据结构来保存i个元素,并将初始计数设置为0。

处理源数组中的每个元素,将其添加到该新结构,直到新结构已满。

然后处理源数组的其余部分。对于每个大于排序数据结构中最小值的结构,从该结构中删除最小值并将新结构放入。

处理完源数组中的所有元素后,您的结构将保留i个最大元素。只需抓住最后一个,你就拥有了i'最伟大的元素。

瞧!

或者,对其进行排序,然后直接抓取i'元素。

答案 3 :(得分:0)

对于具有非常低插入和低delete_min成本的堆来说,这是一个合适的任务。例如。 pairing heaps。它将具有最坏的情况O(n * log(n))性能。但是,由于实现起来非常重要,最好先在别处selection algorithms进行检查。

答案 4 :(得分:0)

您的任务有多种策略可供选择(如果您不首先关注自平衡树)。

通常是权衡速度/记忆。大多数算法都需要修改阵列或O(N)额外存储。

具有自平衡树的解决方案属于后一类,但这不是正确的选择。问题是构建树本身需要O(N*log N),这将主导后面的搜索术语,最终复杂度为O(N*log N)。因此,您不仅仅是简单地对数组进行排序并使用复杂的数据结构......

一般来说,问题在很大程度上取决于与i相关的N的大小。如果你想一分钟,对于i == 1它是微不足道的吗?它被称为找到最大值。

嗯,同样的策略显然适用于线性时间内i == 2(携带2个最大元素)。而且它也是平凡对称的:即如果你需要找到第N-1个元素,那么只需携带2个最小元素。

然而,当i约为N / 2或N / 4时,它会失去效率。携带i个最大元素则意味着对大小为i的数组进行排序...因此我们会回到N*log N墙上。

Jerry Coffin指出了一个简单的解决方案,适用于这种情况。以下是Wikipedia的参考资料。完整的文章还描述了中位数中位数方法:它更可靠,但涉及更多工作,因此通常较慢。

答案 5 :(得分:0)

Create an empty list L

For each element x in the original list,

    add x in sorted position to L
    if L has more than i elements, 
        pop the smallest one off L

if List2 has i elements, 
    return the i-th element, 
else 
    return failure

这应该取O(N(log(i)))。如果假设i是常数,则它是O(N)。

答案 6 :(得分:0)

从元素构建堆并调用MIN i次。