简体   繁体   English

从AVL树获得中位数?

[英]Get median from AVL tree?

If you have an AVL tree, what's the best way to get the median from it? 如果您有AVL树,从中获取中值的最佳方法是什么? The median would be defined as the element with index ceil(n/2) (index starts with 1) in the sorted list. 中位数将定义为排序列表中索引为ceil(n / 2)(索引以1开头)的元素。

So if the list was 所以如果清单是

1 3 5 7 8

the median is 5. If the list was 中位数是5。如果列表是

1 3 5 7 8 10 1 3 5 7 8 10

the median is 5. 中位数是5。

If you can augment the tree, I think it's best to let each node know the size (number of nodes) of the subtree, (ie 1 + left.size + right.size). 如果可以扩充树,我认为最好让每个节点知道子树的大小(节点数)(即1 + left.size + right.size)。 Using this, the best way I can think of makes median searching O(lg n) time because you can traverse by comparing indexes. 使用此方法,我可以想到的最好方法是使中值搜索时间为O(lg n),因为您可以通过比较索引进行遍历。

Is there a better way? 有没有更好的办法?

Augmenting the AVL tree to store subtree sizes is generally the best approach here if you need to optimize over median queries. 如果需要对中位数查询进行优化,则增强AVL树以存储子树大小通常是此处的最佳方法。 It takes time O(log n), which is pretty fast. 这需要时间O(log n),这非常快。

If you'll be computing the median a huge number of times, you could potentially use an augmented tree and also cache the median value so that you can read it in time O(1). 如果要计算中位数很多次,则可能使用增强树并缓存中位数,以便您可以在O(1)时间读取它。 Each time you do an insertion or deletion, you might need to recompute the median in time O(log n), which will slow things down a bit but not impact the asymptotic costs. 每次执行插入或删除操作时,您可能需要重新计算时间O(log n)的中位数,这将使速度变慢但不影响渐近成本。

Another option would be to thread a doubly-linked list through the nodes in the tree so that you can navigate from a node to its successor or predecessor in constant time. 另一种选择是通过树中的节点穿插双向链接列表,以便您可以在恒定时间内从节点导航到其后继或前任。 If you do that, then you can store a pointer to the median element, and then on an insertion or a deletion, move the pointer to the left or to the right as appropriate. 如果这样做,则可以存储指向中位数元素的指针,然后在插入或删除时将指针适当地向左或向右移动。 If you delete the median itself, you can just move the pointer left or right as you'd like. 如果删除中间值本身,则可以根据需要向左或向右移动指针。 This doesn't require any augmentation and might be a bit faster, but it adds two extra pointers into each node. 这不需要任何扩充,并且可能会更快一些,但是会在每个节点中添加两个额外的指针。

Hope this helps! 希望这可以帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM