C++ 最大堆中第三小元素的索引
如何在1到n个不同元素的最大堆中找到第三小元素的可能索引? 我知道最小的元素会在叶子上的任何地方出现。 如果n大于3,则第二个最小值将介于n/2到n之间C++ 最大堆中第三小元素的索引,c++,algorithm,sorting,heapsort,C++,Algorithm,Sorting,Heapsort,如何在1到n个不同元素的最大堆中找到第三小元素的可能索引? 我知道最小的元素会在叶子上的任何地方出现。 如果n大于3,则第二个最小值将介于n/2到n之间 但我不知道第三个最小的计算。有什么建议吗?第三小元素最多有两个子元素,这意味着它的子元素(ren)是叶子,或者是叶子。(为了证明这一点,您还必须证明只有一个子元素的元素不可能有一个非叶作为子元素。简单但乏味。) 正如您几乎注意到的,树叶的索引范围在[地板(n/2)+1,n]之间。如果n/2是一个整数,那么该元素正好有一个子元素(这是一个叶子),
但我不知道第三个最小的计算。有什么建议吗?第三小元素最多有两个子元素,这意味着它的子元素(ren)是叶子,或者是叶子。(为了证明这一点,您还必须证明只有一个子元素的元素不可能有一个非叶作为子元素。简单但乏味。) 正如您几乎注意到的,树叶的索引范围在
[地板(n/2)+1,n]
之间。如果n/2
是一个整数,那么该元素正好有一个子元素(这是一个叶子),因此加上它就给出了可能包含第二大元素的索引范围
第一个子元素在叶范围[floor(n/2)+1,n]
中的元素最多有两个子元素,并且没有非叶子元素。该范围与[ceil(n/2),n]范围相邻,两个范围的并集为第三大元素提供了所有可能的位置
位于i
的元素的第一个子元素具有索引2i
,因此其第一个子元素至少为floor(n/2)+1
的第一个元素为floor(n/4)+1
因此,可以找到第三大元素的可能索引是范围:[floor(n/4)+1,n]
这是另一种方法。在索引
i
处取一些元素。其直接子代为2i
和2i+1
;它的孙子是4i,4i+1,4i+2,4i+3
,一般来说,它在k
级别的后代是2ki,2ki+1,…,2ki+2ki-1
;总之,[2ki,…,2k(i+1)-1]
。当然,这些范围是不重叠的(事实上,除非i
是1
,否则它们甚至不是连续的)。因此,如果i
在k
级别上至少有一个子体,那么它也为所有k'
拥有一套完整的子体,其中有2k-2
综上所述,我们可以得出以下结论:
- 如果
,则n≥ 2ki和n<2k(i+1)
具有:i
在低于2ki-2
k
在n-2ki+1
级别的子体k
- 总计:
n-1
- 如果
,则n≥ 2k(i+1)和n<2k+1i
具有:i
- 精确地
2k+1-1
- 精确地
粗略地说,这意味着在堆的底层数组的第一个
1/2k
部分中找不到最后的2k
元素 在true中,如果我正确地调用数据结构,最小的(n+1)/2个节点将是leave。因此,第三个最小值将是这些节点之一或其中一个节点的直接父节点。即使假设堆已经完全构建,我也无法理解一个能够在O(1)时间内提取该值的封闭形式算法。我也得到了相同的解决方案…得出了最后的结论,即第I(th)个最小元素的索引公式将是[n/(2^(I-1))]到n。感谢您的帮助:)它更像是“第2^i(th)个最小元素的索引”。请参见编辑。(不完整,但如果我不能及时回复,您可能可以自己完成。)