为什么我们要为avl树实现返回一个指向节点的指针,而不是void函数

Why do we return a pointer to a node instead of void function for avl tree implementation?

本文关键字:指针 节点 函数 void 一个 avl 我们 实现 返回 为什么      更新时间:2023-10-16

好吧,所以我似乎有点迷路了。我正在尝试将数据插入树中,当检查平衡和是否旋转时,我默认通过根进行检查。当我在线查看示例时,我发现我们也可以沿着树中的其他节点进行旋转。我们如何确定使用哪个节点来平衡树,以及如何到达所述节点?我还看到,人们使用节点指针返回类型,而不是使用void函数来实现插入和旋转函数。这样做的目的是什么?我知道答案可能非常明显,我只是迷路了。

struct TNode{
int data;
TNode* left;
TNode* right;
};
class Tree{
public:
TNode* root;
public:
Tree()
{root = nullptr;}
int height(TNode* node);
int balanceFactor(TNode* node);
bool isBalance(TNode* node)
{return balanceFactor(node)<-1 && balanceFactor(node)>1?true:false;}
void avlInsert(int key);
void LLRotation(TNode* node);
};
int Tree::height(TNode* node){
int l = 0;
int r = 0;
if(!node->left && !node->right)
return 0;
if(node->left)
l = height(node->left) + 1;
if(node->right)
r = height(node->right) + 1;
return l > r ? l : r;
}
int Tree::balanceFactor(TNode *node){
if(node->left && node->right)
return height(node->left) - height(node->right);
else if(node->left && !node->right)
return height(node);
else
return -1 * height(node);
}
void Tree::LLRotation(TNode *node){
TNode* nl = node->left;
node->left = nl->right;
nl->right = node;
if(root == node)
root = nl;
}
void Tree::avlInsert(int key){
TNode* trav;
TNode* follow;
TNode* node = new TNode;
node->data = key;
node->left = nullptr;
node->right = nullptr;
if (!root)
root = node;
else{
trav = root;
while (trav){
if (key < trav->data){
follow = trav;
trav = trav->left;
}
else{
follow = trav;
trav = trav->right;
}
}
if(key < follow->data)
follow->left = node;
else
follow->right = node;
}
if (balanceFactor(root) == 2 && balanceFactor(root->left) == 1)
LLRotation(root);
}

这实际上取决于您的实现——有些人希望返回一个节点,使用void函数不会对结果有太大改变。对于插入函数,你只需要在插入节点后进行检查,这样你就可以继续插入该节点,而不是旋转它。请注意,只有当你有一个AVL树开始时,这个函数才会起作用。此外,您的代码不正确,如下所示:

if (balanceFactor(root) == 2 && balanceFactor(root->left) == 1)
LLRotation(root);

这不是检查插入的方式。。。。这是删除的,伙计,我想你搞混了。通常在插入时,你会检查balanceFactor是否在1和-1之间,所以如果你得到2,那么在你的情况下,它是一棵左重树,因为它是左右的,这意味着你应该进行右旋转。。。。。。。。伙计。。。。。。

int l = 0;
int r = 0;
if(!node->left && !node->right)
return 0;
if(node->left)
l = height(node->left) + 1;
if(node->right)
r = height(node->right) + 1;
return l > r ? l : r;

高度功能,效率极低。。。相反,将高度定义为节点的变量,然后在每次插入、删除后对其进行修改。