C++ 从具有父指针、左子树和右子树高度的树中删除
我在从二叉树中删除节点时遇到了一个问题,即每个节点都保持左、右子树的高度以及指向父节点的指针。 我想可以吗? 我得到了错误的高度和错误的父指针,以及我错过了一些树的一部分,而删除。 我应该如何更改删除和链接功能C++ 从具有父指针、左子树和右子树高度的树中删除,c++,data-structures,tree,C++,Data Structures,Tree,我在从二叉树中删除节点时遇到了一个问题,即每个节点都保持左、右子树的高度以及指向父节点的指针。 我想可以吗? 我得到了错误的高度和错误的父指针,以及我错过了一些树的一部分,而删除。 我应该如何更改删除和链接功能 #include <iostream> #include <algorithm> struct Node { int data; Node* parent; Node* leftChild; Node* rightChild;
#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;
}
#包括
#include节点删除代码中存在多个问题,到目前为止,我只知道第一次删除有什么问题(8)。我不明白为什么变量max
被引入了SubtractHeights()
,起作用的是类似于AddHeights()
中的代码。如果条件
parent->leftHeight leftHeightrighthheight
和parent->righthheight righthheightleftHeight
,第一次删除似乎可以正常工作。其他2例的行为似乎没有因此而改变
当/如果您响应时,我将尝试找出其余部分…代码可以按原样编译很好。main()太长,而且没有迹象表明您得到的第一个错误结果是什么,这就不太好了。你认为前两次移除(8,10)可以吗?第三个显然是错的……不,他们不好。您可以在控制台中看到,当打印DisplayTreeInoder时,指向父项和高度的指针被弄乱了。主要功能是在每次插入/删除后打印树的状态。前两次删除应该是可以的,因为这些节点是在树中添加的,但它们不是,因为高度是错误的。是的,我可以看到控制台输出,但在添加了所有元素后,其中有很多行,因此需要一些时间来了解树的实际外观。请继续关注,我将在几个小时后了解发生了什么…在SubtractHeights()
中max
变量背后的动机是什么?为什么而在父级->XXheight上中断?好吧,只有当新高度低于原来的高度时,我们才应该更新高度。例如,左子树是3,右子树是2。我们已经从左子树中删除了一个节点,所以它应该是2。但它也应该导致更新父级,因为总高度不再是3,而是2,并将更改传播到整个树的根。那个么我现在应该做什么呢?如果移除右节点有两个节点的节点,则尚未解决此问题。我写的对你有意义吗?