我在C中编写一个AVL树,每个节点都记录其高度和平衡因子。我在进行旋转时遇到了奇怪的错误。我的重新平衡功能爬上树,直到它找到根节点或不平衡节点,然后检查平衡因子以确定它需要执行哪些旋转。旋转函数接受双指针并重新分配它们给出的解除引用的节点。但是,这似乎不起作用,所以为了好的措施,我还使函数返回占用原始节点位置的节点。这似乎也不起作用,我不明白。在第164和171行,我明确地将节点的子节点分配给旋转函数的返回值(这是它的新节点。)
我的轮换功能:
Node *rotateRight(Node **root) {
Node *node = *root;
Node *pivot = node->left; //pivot will become the new root
if(node->parent) {
Node *g = node->parent;
pivot->parent = node->parent;
if(pivot->datum < g->datum) g->left = pivot;
else g->right = pivot;
} else
pivot->parent = NULL;
node->parent = node->left;
node->left = pivot->right? pivot->right : NULL;
pivot->right = node;
*root = node->parent;
return pivot;
}
Node *rotateLeft(Node **root) {
Node *node = *root;
Node *pivot = node->right;
if(node->parent) {
Node *g = node->parent;
pivot->parent = node->parent;
if(pivot->datum < g->datum) g->left = pivot;
else g->right = pivot;
} else
pivot->parent = NULL;
node->parent = pivot;
node->right = pivot->left? pivot->left : NULL;
pivot->left = node;
*root = node->parent;
return pivot;
}
我的重新平衡功能(回溯只找到树的根):
Node *rebalance(Node **node) {
if(-1 <= (*node)->bal && (*node)->bal <= 1) { //current node is balanced, we can ascend and check the next node
if((*node)->parent) rebalance(&((*node)->parent));
return retrace(*node);
}
if((*node)->bal == 2) {
if((*node)->left->bal == 1) { //left left
puts("ll");
rotateRight(node);
return retrace(*node);
} else { //left right
puts("lr");
(*node)->left = rotateLeft(&((*node)->left));
rotateRight(node);
return retrace(*node);
}
} else {
if((*node)->right->bal == 1) { //right left
puts("rl");
(*node)->right = rotateRight(&((*node)->right));
rotateLeft(node);
return retrace(*node);
} else { //right right
puts("rr");
rotateLeft(node);
}
}
}