简单的AVL树删除有时只能工作

时间:2013-04-02 20:26:17

标签: c++ pointers tree avl-tree

我正在研究一个AVL树。似乎我的删除只在某些时候正常工作。我建了一个看起来像这样的树

          f
        /   \
       e     j
      /    /   \
     a    h     s

f e h s j a的顺序插入。我知道它在插入和平衡方面正常工作。

当我删除ajhse时,一切正常。如果我删除f,则会将f替换为h,这是正确的,但我丢失了js

这是第一个被调用的函数。

    void remove(const ItemType& item)
    {
        if(root == NULL)
            return;
        else
        {
            remove(root, item);
        }
    };

第一个函数调用此函数以递归方式找到正确的节点。

    void remove(Node<ItemType>* & node, const ItemType& item)
    {
        if(item > node->item)
        {
            if (node->rightChild == NULL)
            {
                return; // there is nothing here to remove
            }
            else
            {
                // recurse to next node
                remove(node->rightChild, item);
            }
        }
        else if (item < node->item)
        {
            if (node->leftChild == NULL)
            {
                return; // there is nothing here to remove
            }
            else
            {
                // recurse to next node
                remove(node->leftChild, item);
            }
        }
        else if (node->item == item)
        {
            remove(node);
        }

        if (node != NULL)
            node->updateHeight();
    };

这是要调用的最后一个函数。这是删除和掉期的地方。

    void remove(Node<ItemType>* & node)
    {
        if (node->rightChild == NULL && node->leftChild == NULL)
        {
            delete node;
            node = NULL;
        }
        else if (node->rightChild == NULL)
        {
            Node<ItemType>* temp = node;
            node = node->leftChild;
            delete temp;
        }
        else
        {
            Node<ItemType>* & temp = node->rightChild;
            while (temp->leftChild != NULL)
                temp = temp->leftChild;

            node->item = temp->item;
            delete temp;
            temp = NULL;
        }

        if(node != NULL)
            node->initializeHeight();
    };

我想知道它是否与行

有关
            Node<ItemType>* & temp = node->rightChild;
            while (temp->leftChild != NULL)
                temp = temp->leftChild;

            node->item = temp->item;
            delete temp;
            temp = NULL;

并且temp指针正在我不熟悉的行为中运行,或者我的整个实现是错误的。我知道丢失的节点在某处,因为我的内存泄漏显示我丢失的那两个节点永远不会被删除。

1 个答案:

答案 0 :(得分:2)

  

我想知道它是否与行

有关

是。 Node<ItemType>* & temp = node->rightChild;tempnode->rightChild的别名。因此,while循环会修改node->rightChild,并且您将丢失原始右侧孩子的句柄。

取一个普通的指针,然后沿着右边的子树向下走,直到你找到它最小的成员的父节点。然后获取最小成员的值,将其复制到node->item,并删除父级的左子。