我有一个AVL树,我想在其中返回O(1)中的中间元素
我知道每次插入新元素时都可以保存指向它的指针而不更改插入的运行时间(通过保存子树的大小并遍历直到找到第n / 2尺寸子树)。
但我想知道我是否可以使用这样一个事实:在每次插入中,中间位置“向右”移动,而在每次删除时,中位数都“向左”移动。
以更一般的方式:如何使用前任和后继跟踪AVL树中的第i个元素?
答案 0 :(得分:1)
给定AVL(自平衡二分搜索树),找到中位数。记住,即使树是平衡的,你也不能只取根元素,因为即使树平衡,你也不知道中位数是否是左或右儿子的根元素。用于找到AVL中值的迭代算法。此算法基于每个AVL树的属性,您可以使用顺序遍历获取包含此树的元素的已排序集合。使用此属性,我们可以获取已排序的节点集合,然后查找中位数。该算法的复杂度顺序是时间和空间项中的O(N),其中N是树中节点的数量。
public class AvlTreeMedian {
BinaryTreeInOrder binaryTreeInOrder;
public AvlTreeMedian() {
this.binaryTreeInOrder = new BinaryTreeInOrder();
}
public double find(BinaryNode<Integer> root) {
if (root == null) {
throw new IllegalArgumentException("You can't pass a null binary tree to this method.");
}
List<BinaryNode<Integer>> sortedElements = binaryTreeInOrder.getIterative(root);
double median = 0;
if (sortedElements.size() % 2 == 0) {
median = (sortedElements.get(sortedElements.size() / 2).getData() + sortedElements.get(
sortedElements.size() / 2 - 1).getData()) / 2;
} else {
median = sortedElements.get(sortedElements.size() / 2).getData();
}
return median;
}
}