从具有父指针和左子树和右子树高度的树中删除

Removal from tree with parent pointer and left subtree and right subtree height

本文关键字:删除 高度 指针      更新时间:2023-10-16

我有一个问题,从二叉树中删除节点,每个节点保持左右子树的高度和指向父级的指针。 我想添加可以吗? 我得到了错误的高度和错误的父指针,并且在移除时我错过了树的某些部分。 我应该如何更改我的删除和链接功能?

#include <iostream>
#include <algorithm>
struct Node 
{
int data;
Node* parent;
Node* leftChild;
Node* rightChild;
int leftHeight;
int rightHeight;
};
void DisplayTreeInOrder(struct Node* root)
{
if (root != nullptr)
{
DisplayTreeInOrder(root->leftChild);
printf("Node : %d, ", root->data);
printf(" Height left : %d, ", root->leftHeight);
printf(" Height right : %d, ", root->rightHeight);
if (root->parent == NULL)
{
printf("Parent : NULL n");
}
else
{
printf("Parent : %d n", root->parent->data);
}
DisplayTreeInOrder(root->rightChild);
}
}
Node* CreateNode(int data, Node* parent = nullptr)
{
struct Node* newNode = new Node();
newNode->data = data;
newNode->parent = parent;
newNode->leftChild = nullptr;
newNode->rightChild = nullptr;
newNode->leftHeight = 0;
newNode->rightHeight = 0;
return newNode;
}
void AddHeights(Node* newNode) 
{
Node* parent = newNode->parent;
while (parent != nullptr)
{
if (parent->leftChild == newNode)
{
parent->leftHeight++;
if (parent->leftHeight <= parent->rightHeight)
{
break;
}
newNode = parent;
parent = parent->parent;
}
else
{
parent->rightHeight++;
if (parent->rightHeight <= parent->leftHeight)
{
break;
}
newNode = parent;
parent = parent->parent;
}
}
}
Node* AddToTree(Node* root, int data)
{
if (root == nullptr)
{
return CreateNode(data, nullptr);
}
Node* temp = root;
while (true)
{
if (data < temp->data)
{
if (temp->leftChild == nullptr)
{
Node* newNode = CreateNode(data, temp);
temp->leftChild = newNode;
AddHeights(newNode);
break;
}
else
{
temp = temp->leftChild;
}
}
else if (data > temp->data)
{
if (temp->rightChild == nullptr)
{
Node* newNode = CreateNode(data, temp);
temp->rightChild = newNode;
AddHeights(newNode);
break;
}
else
{
temp = temp->rightChild;
}
}
else
{
break;
}
}
return root;
}
Node* FindNode(struct Node* root, int dataToFind)
{
while (root != nullptr)
{
if (dataToFind > root->data)
{
root = root->rightChild;
}
else if (dataToFind < root->data)
{
root = root->leftChild;
}
else
{
return root;
}
}
return nullptr;
}
Node* minValueNode(struct Node* node)
{
Node* current = node;
while (current && current->leftChild != nullptr)
{
current = current->leftChild;
}
return current;
}
void SubtractHeights(Node* newNode)
{
Node* parent = newNode->parent;
int max = std::max(parent->leftHeight, parent->rightHeight);
while (parent != nullptr)
{
if (parent->leftChild == newNode)
{
parent->leftHeight--;
if (parent->leftHeight <= max)
{
break;
}
newNode = parent;
parent = parent->parent;
}
else
{
parent->rightHeight--;
if (parent->rightHeight <= max)
{
break;
}
newNode = parent;
parent = parent->parent;
}
}
}
void UnlinkChildFromParent(Node* node) 
{
Node* parent = node->parent;
if (parent == nullptr) 
{
return;
}
if (node == parent->leftChild)
{
parent->leftChild = nullptr;
}
else 
{
parent->rightChild = nullptr;
}
}
Node* RemoveFromTree(Node *root, int value)
{
if (root == nullptr)
{
return root;
}
Node* nodeToRemove = FindNode(root, value);
if (nodeToRemove == nullptr)
{
return root;
}
else
{
if ((nodeToRemove->leftChild == nullptr) || (nodeToRemove->rightChild == nullptr))
{
Node* temp = nodeToRemove->leftChild ? nodeToRemove->leftChild : nodeToRemove->rightChild;
if (temp == nullptr)
{
temp = nodeToRemove;
SubtractHeights(nodeToRemove);
UnlinkChildFromParent(nodeToRemove);
nodeToRemove = nullptr;
}
else
{
Node* parentOfNodeToRemove = nodeToRemove->parent;
*nodeToRemove = *temp;
SubtractHeights(nodeToRemove);
UnlinkChildFromParent(nodeToRemove);
}
delete temp;
}
else
{
Node* temp = minValueNode(nodeToRemove->rightChild);
nodeToRemove->data = temp->data;
nodeToRemove->rightChild = RemoveFromTree(nodeToRemove->rightChild, temp->data);
}
}
return root;
}
int main()
{
Node *ptrToTree = nullptr;
ptrToTree = AddToTree(ptrToTree, 45);
AddToTree(ptrToTree, 46);
DisplayTreeInOrder(ptrToTree);
std::cout << std::endl;
AddToTree(ptrToTree, 47);
DisplayTreeInOrder(ptrToTree);
std::cout << std::endl;
AddToTree(ptrToTree, 44);
DisplayTreeInOrder(ptrToTree);
std::cout << std::endl;
AddToTree(ptrToTree, 10);
DisplayTreeInOrder(ptrToTree);
std::cout << std::endl;
AddToTree(ptrToTree, 11);
DisplayTreeInOrder(ptrToTree);
std::cout << std::endl;
AddToTree(ptrToTree, 12);
DisplayTreeInOrder(ptrToTree);
std::cout << std::endl;
AddToTree(ptrToTree, 13);
DisplayTreeInOrder(ptrToTree);
std::cout << std::endl;
AddToTree(ptrToTree, 14);
DisplayTreeInOrder(ptrToTree);
std::cout << std::endl;
AddToTree(ptrToTree, 19);
DisplayTreeInOrder(ptrToTree);
std::cout << std::endl;
AddToTree(ptrToTree, 66);
DisplayTreeInOrder(ptrToTree);
std::cout << std::endl;
AddToTree(ptrToTree, 100);
DisplayTreeInOrder(ptrToTree);
std::cout << std::endl;
AddToTree(ptrToTree, 9);
DisplayTreeInOrder(ptrToTree);
std::cout << std::endl;
AddToTree(ptrToTree, 48);
DisplayTreeInOrder(ptrToTree);
std::cout << std::endl;
AddToTree(ptrToTree, 8);
DisplayTreeInOrder(ptrToTree);
std::cout << std::endl;
AddToTree(ptrToTree, 8);
DisplayTreeInOrder(ptrToTree);
std::cout << std::endl;
RemoveFromTree(ptrToTree, 8);
DisplayTreeInOrder(ptrToTree);
std::cout << std::endl;
RemoveFromTree(ptrToTree, 10);
DisplayTreeInOrder(ptrToTree);
std::cout << std::endl;
RemoveFromTree(ptrToTree, 11);
DisplayTreeInOrder(ptrToTree);
std::cout << std::endl;
}

树的外观和执行的操作

节点删除代码中存在多个问题,到目前为止,我只弄清楚了第一次删除的问题(8(。我不明白为什么变量max被引入SubtractHeights(),有效的是类似于AddHeights()中的代码。如果条件parent->leftHeight <= max第 55 行更改为parent->leftHeight < parent->rightHeight,第 65 行的parent->rightHeight <= max更改为parent->rightHeight < parent->leftHeight,第一次删除似乎工作正常。其他 2 种情况的行为似乎并没有因此而改变。

当您回应时,我会尝试弄清楚其余的...