如何删除具有 O(1) 额外内存的二叉树?

Posted

技术标签:

【中文标题】如何删除具有 O(1) 额外内存的二叉树?【英文标题】:How can I delete a binary tree with O(1) additional memory? 【发布时间】:2021-12-15 01:14:52 【问题描述】:

我想知道是否可以在不使用递归或堆栈的情况下删除具有 O(1) 额外内存的二叉树。

我已经设法编写了简单的递归后序遍历解决方案(它使用堆栈内存):

void deleteTreeRec(Node *root)

   if (root == NULL) return;
   deleteTreeRec(root->left);
   deleteTreeRec(root->right);
   cout << "Deleting node " << root->data << endl;
   delete root;

我听说这可以使用(有序)Morris 遍历来实现,这似乎是错误的,或者至少违反直觉,因为据我所知,树删除需要以后序方式遍历(从删除两个子树,然后才删除根)。但是,我还没有找到解决方案的任何详细描述/伪代码,因此我在这里碰碰运气。

如果有人能对这个问题有所了解,将不胜感激。谢谢!

【问题讨论】:

【参考方案1】:

在删除过程中,二叉树的现有节点可以用作单链表:总是使用left“链接”的节点被视为链表。

要删除所有节点,您只需重复以下步骤:

    找到“链表”的尾部 如果right不为空,则将其移至“列表”的末尾 将指针存储在“列表”中的下一个元素临时 用临时性替换旧的头部,如果“列表”不为空,则重复

从前一个尾部开始搜索新尾部会导致算法在O(n) 中运行,其中n 是二叉树中的节点数。

void deleteTree(Node* root)

    Node* tail = root;
    while (root != nullptr)
    
        // update tail
        while (tail->left != nullptr)
        
            tail = tail->left;
        

        // move right to the end of the "list"
        // needs to happen before retrieving next, since the node may only have a right subtree
        tail->left = root->right;

        // need to retrieve the data about the next
        Node* next = root->left;

        delete root;

        root = next;
    

【讨论】:

以上是关于如何删除具有 O(1) 额外内存的二叉树?的主要内容,如果未能解决你的问题,请参考以下文章

数据结构之堆

堆(插入删除)

二叉搜索树中删除的时间复杂度

AVL树的插入与删除

数据结构 第5章 树的二叉树 单元小结遍历二叉树和线索二叉树

数据结构--堆