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,并将更改传播到整个树的根。那个么我现在应该做什么呢?如果移除右节点有两个节点的节点,则尚未解决此问题。我写的对你有意义吗?