📅  最后修改于: 2023-12-03 15:26:09.468000             🧑  作者: Mango
平衡二叉搜索树也被称为 AVL 树,是一种既能支持快速查找又能支持动态数据集合的数据结构。它可以在 O(log n) 的时间内进行插入、查找和删除操作。问题7是指在 AVL 树中,查找节点的前驱和后继。
假设 AVL 树中存在节点 x,我们希望查找它的前驱和后继。
前驱:在 AVL 树中,比 x 小的最大节点称为 x 的前驱,如果不存在比 x 小的节点,则 x 没有前驱。
后继:在 AVL 树中,比 x 大的最小节点称为 x 的后继,如果不存在比 x 大的节点,则 x 没有后继。
对于每个节点,我们可以保存它的前驱和后继节点信息。当插入或删除一个节点时,我们可以更新它的前驱和后继节点信息。
要查找 x 的前驱,我们可以进行以下操作:
要查找 x 的后继,我们可以进行以下操作:
下面是 C++ 实现的代码片段,其中 Node 类表示 AVL 树的节点:
class Node {
public:
int val, height;
Node *left, *right, *pre, *suc;
Node(int val) {
this->val = val;
this->height = 1;
this->left = this->right = NULL;
this->pre = this->suc = NULL;
}
};
// 更新节点的前驱和后继信息
void updatePreSuc(Node* root) {
if (!root) return;
// 更新右子树的最小节点为节点的后继
if (root->right) {
Node* p = root->right;
while (p->left) p = p->left;
root->suc = p;
}
// 更新左子树的最大节点为节点的前驱
if (root->left) {
Node* p = root->left;
while (p->right) p = p->right;
root->pre = p;
}
// 递归更新子节点的前驱和后继信息
updatePreSuc(root->left);
updatePreSuc(root->right);
}
在节点插入或删除的时候,我们可以使用上述代码来更新前驱和后继节点信息。在查找前驱或后继节点时,我们可以沿着 AVL 树的左右子树递归查找。如果节点的左子树非空,则一定能找到前驱节点;如果右子树非空,则一定能找到后继节点。如果左右子树都为空,我们需要向上递归查找祖先节点。