📜  锦标赛树(优胜者树)和二进制堆

📅  最后修改于: 2021-04-17 11:57:39             🧑  作者: Mango

给定一个由N个玩家组成的团队。要找到第二好的玩家,需要多少个最低限度的游戏?

我们可以使用基于锦标赛树(二进制堆)的对手自变量。

锦标赛树是最小(最大)堆的一种形式,是完整的二叉树。每个外部节点代表一个参与者,内部节点代表赢家。在锦标赛树中,每个内部节点包含一个获胜者,每个叶子节点包含一个参与者。

带有N个叶(外部)节点的二叉树中将有N – 1个内部节点。有关详细信息,请参见此帖子(将n = 2放入该帖子中给出的方程式中)。

显然,要在N个玩家中选择最佳玩家,则要淘汰(N – 1)个玩家,即,我们最少需要(N – 1)个游戏(比较)。从数学上讲,我们可以证明这一点。在二叉树中,I = E – 1,其中I是内部节点的数量,E是外部节点的数量。这意味着要找到数组的最大或最小元素,我们需要N – 1(内部节点)比较。

次优球员

最佳球员选择过程中探索的信息可用于最大程度地减少追踪次佳球员的比较次数。例如,我们可以在(N + log 2 N – 2)个比较中选择第二好的球员。

下图显示了锦标赛树(优胜者树)作为最大堆。请注意,失败者树的概念是不同的。

上面的树包含4个代表玩家的叶子节点,并具有3个级别0、1和2。最初在级别2进行2个游戏,一个在5和3之间,另一个在7和8之间。在下一步骤中,又玩了一个游戏在5到8之间进行,以得出最终的获胜者。总体而言,我们需要进行3个比较。对于第二名的玩家,我们需要跟踪最终获奖者参加的候选人,从而使第二名的玩家达到7名。

排序数组的中位数

锦标赛树可以有效地用于查找排序数组的中位数。假设给定M个大小为L的排序数组(为简单起见)。我们可以将所有这些排序后的数组附加到锦标赛树上,每片叶子一个数组。我们需要一棵高度为CEIL(log 2 M)的树来拥有至少M个外部节点。

考虑一个例子。给定3个(M = 3)排序的最大大小为5个元素的整数数组。

{ 2, 5, 7, 11, 15 } ---- Array1
{1, 3, 4} ---- Array2
{6, 8, 12, 13, 14} ---- Array3

比赛树的高度应该是多少?我们需要构建一个高度为2 3。= 1.585 = 2的比赛树,四舍五入到下一个整数。高度为2的二叉树将有4个叶子,我们可以将数组连接到其上,如下图所示。

第一次锦标赛后,树显示如下,

我们可以观察到获胜者来自Array2。因此,来自Array2的下一个元素将潜入,游戏将沿着上一个锦标赛的获胜者路径进行。

请注意,无穷大用作哨兵元素。根据节点中保留的数据,我们可以选择前哨字符。例如,我们通常将指针存储在节点中而不是键中,因此NULL可以用作哨兵。如果有任何数组耗尽,我们将用哨兵填充相应的叶子和即将到来的内部节点。

在第二次锦标赛之后,树显示如下,

下一个获胜者来自Array1,因此Array1数组的下一个元素(为5)将进入下一轮比赛,并且下一个锦标赛沿2的路径进行。

比赛可以继续进行,直到获得中位数(5 + 3 + 5)/ 2 =第7个元素。请注意,甚至还有更好的算法来查找排序数组的并集中位数,有关详细信息,请参见下面给出的相关链接。

通常,使用M个大小为L 1的排序列表,L 2 …L m需要O((L 1 + L 2 +…+ L m )* logM)的时间复杂度来合并所有数组,以及O(m * logM)找到中位数的时间,其中m是中位数位置。

从十亿个未排序元素中选择最小的一百万个元素:

作为一个简单的解决方案,我们可以对十亿个数字进行排序,然后选择前一百万个数字。

在有限的内存系统上,排序十亿个元素并选择前一百万个元素似乎是不切实际的。我们可以使用锦标赛树方法。在任何时候都只有树的元素在内存中。

将大型阵列(可能存储在磁盘上)拆分成较小的阵列,每个阵列的大小为一百万(甚至可以由计算机分类的较小的阵列)。对这1000个小型阵列进行排序,并将它们作为单独的文件存储在磁盘上。构造一个可以包含至少1000个叶子节点的锦标赛树(由于2 9 <1000 <2 10 ,树的高度为10 ,如果单个文件的大小更小,我们将需要更多的叶子节点)。每个叶节点都有一个引擎,该引擎从存储在磁盘上的排序文件中选择下一个元素。我们可以玩锦标赛树游戏来提取前一百万个元素。

总成本=整理1000个列表,每个列表一百万个+树木建造+锦标赛

执行
我们需要以自下而上的方式构建树。所有叶子节点都首先填充。从树的最左端开始并沿宽度填充(即,从2 k-1到2 k – 1,其中k是树的深度)并玩游戏。经过少量实例练习之后,编写代码将变得很容易。下面的代码讨论了实现

使用最小比较的第二个最小元素

相关文章
查找数组中的最小和第二个最小元素。
使用最小比较的第二个最小元素