Ответ 1
Вы можете измерить height
ветки в заданной точке, чтобы рассчитать дисбаланс
(помните, что разница в высоте (уровнях) >= 2 означает, что ваше дерево не сбалансировано)
int Tree::Height(TreeNode *node){
int left, right;
if(node==NULL)
return 0;
left = Height(node->left);
right = Height(node->right);
if(left > right)
return left+1;
else
return right+1;
}
В зависимости от неровности вы можете повернуть по мере необходимости
void Tree::rotateLeftOnce(TreeNode*& node){
TreeNode *otherNode;
otherNode = node->left;
node->left = otherNode->right;
otherNode->right = node;
node = otherNode;
}
void Tree::rotateLeftTwice(TreeNode*& node){
rotateRightOnce(node->left);
rotateLeftOnce(node);
}
void Tree::rotateRightOnce(TreeNode*& node){
TreeNode *otherNode;
otherNode = node->right;
node->right = otherNode->left;
otherNode->left = node;
node = otherNode;
}
void Tree::rotateRightTwice(TreeNode*& node){
rotateLeftOnce(node->right);
rotateRightOnce(node);
}
Теперь, когда мы знаем, как вращаться, скажем, вы хотите вставить значение в дереве... Сначала мы проверяем, пусто ли дерево или нет
TreeNode* Tree::insert(int d){
if(isEmpty()){
return (root = new TreeNode(d)); //Is empty when root = null
}
else
return insert(root, d); //step-into the tree and place "d"
}
Когда дерево не пустое, мы используем рекурсия, чтобы пересечь дерево и добраться туда, где нужно
TreeNode* Tree::insert(TreeNode*& node, int d_IN){
if(node == NULL) // (1) If we are at the end of the tree place the value
node = new TreeNode(d_IN);
else if(d_IN < node->d_stored){ //(2) otherwise go left if smaller
insert(node->left, d_IN);
if(Height(node->left) - Height(node->right) == 2){
if(d_IN < node->left->d_stored)
rotateLeftOnce(node);
else
rotateLeftTwice(node);
}
}
else if(d_IN > node->d_stored){ // (3) otherwise go right if bigger
insert(node->right, d_IN);
if(Height(node->right) - Height(node->left) == 2){
if(d_IN > node->right->d_stored)
rotateRightOnce(node);
else
rotateRightTwice(node);
}
}
return node;
}
Вы всегда должны проверять баланс (и при необходимости делать поворот) при изменении дерева, не ожидая конца, пока дерево не станет беспорядочным, чтобы сбалансировать его. Это просто усложняет ситуацию...
UPDATE
В вашей реализации есть ошибка, в приведенном ниже коде вы неверно проверяете, не деформировано ли дерево. Вам нужно проверить, равна ли высота 2 (поэтому дисбаланс). В результате код ниже...
if (height(current->lchild) - height(current->rchild)) { ...
if (height(current->rchild) - height(current->lchild)) {...
Должен стать...
if (height(current->lchild) - height(current->rchild) == 2) { ...
if (height(current->rchild) - height(current->lchild) == 2) {...
Некоторые ресурсы