질문을 올바르게 이해하면 주어진 노드의 밸런스 요소를 유지하는 방법을 알고 싶습니다. 트랙을 유지하는 가장 좋은 방법은 트리에서 "삽입"을 수행하는 것입니다. 새 노드가 "현재"노드의 왼쪽 또는 오른쪽으로 이동하는지 여부를 알기 때문입니다. 왼쪽으로 갈 때 균형을 감소시키고 오른쪽으로 갈 때 균형을 증가시킵니다. 아이디어는 "삽입"방법을 종료하기 전에 트리를 이미 균형있게 유지하는 것입니다.
내가 본 다른 접근법은 "삽입"중에 균형 조정을 수행하지 않는 것입니다. BST 에서처럼 삽입하면됩니다. 삽입 후에는 각 노드에서 왼쪽 하위 트리와 오른쪽 하위 트리 높이를 얻고 포인터를 다시 시작하는 균형 조정 작업을 시작합니다. 이것은 높이를 찾는 모든 노드에 대해 O (logn)를 발생시키고 모든 노드에 대해이를 수행하므로 n * O (logn)가되므로 좋은 접근 방법은 아닙니다.
나는 삽입 할 때마다 나무 균형을 유지하고 삽입하는 동안 별도로 높이를 계산하지 않는 "삽입"방법을 게시하고 있습니다. 도움이되는지보기 :
Node*
AVL::insert(Node* node, int key, int value)
{
if(node == NULL)
node = new Node(key, value);
else if (key <= node->key)
{
node->balance--;
node->left = insert(node->left, key, value);
}
else if (key > node->key)
{
node->balance++;
node->right = insert(node->right, key, value);
}
// Right Tree Heavy
if (node->balance == 2)
{
// Left tree unbalanced
if (node->right && node->right->balance == 1)
{
// LL
node = singleLeftRotation(node);
node->balance = 0;
node->left->balance = 0;
}
if (node->right && node->right->balance == -1)
{
// LR
int nodeRLBalance = node->right->left->balance;
node = doubleLeftRotation(node);
node->balance = 0;
node->left->balance = nodeRLBalance == 1 ? -1 : 0;
node->right->balance = nodeRLBalance == -1 ? 1 : 0;
}
}
// Left Tree Heavy
if (node->balance == -2)
{
// Right tree unbalanced
if (node->left && node->left->balance == -1)
{
// RR
node = singleRightRotation(node);
node->balance = 0;
node->right->balance = 0;
}
if (node->left && node->left->balance == 1)
{
// RL
int nodeLRBalance = node->left->right->balance;
node = doubleRightRotation(node);
node->balance = 0;
node->left->balance = nodeLRBalance == 1 ? -1 : 0;
node->right->balance = nodeLRBalance == -1 ? 1 : 0;
}
}
return node;
}
요인과 일치하는 것을 볼 수있다 , 나는 나무의 어떤 노드에 대해서도 그것을 알 수 없다. – user1861967
내가 톱 3 if-else 조건을 참조하십시오. 그것은 내가 균형 요소를 추적하는 곳입니다. 미안 당신이 묻고있는 것을 이해하지 못한다면. –
트리의 균형 계수/높이를 수동으로 계산하는 방법을 이해하려고 노력 중입니다 ... 코드를 작성하지 마십시오. – user1861967