当前位置: 首页 > 知识库问答 >
问题:

ASAN:将二叉树扁平化为链表时的堆使用

吕霄
2023-03-14

是什么导致了错误?

下面是我的代码:

class Solution {
public:
    void flat_tree(TreeNode* pre, TreeNode* root, stack<TreeNode*>& s){ 
        if(root == NULL){
            if(s.empty()) return;
            else{
                TreeNode* newroot = s.top();  
                s.pop();
                pre->right = newroot;
                flat_tree(pre, newroot,s);
            }
        }else{
            if(root->left == NULL) {
                flat_tree(root, root->right, s); 
            }else if(root->right == NULL){
                root->right = root->left;
                flat_tree(root, root->right, s); 
            }else{
                TreeNode* right = root->right;
                root->right = root->left;
                s.push(right);
                flat_tree(root, root->right, s); 
            }
        }
    }   

    void flatten(TreeNode* root) {
        stack<TreeNode*> s;
        flat_tree(NULL ,root,s);  
    }
};

共有1个答案

漆雕修德
2023-03-14

这很接近。在将左节点指针的子节点移到根的右侧后,需要将左节点指针置空,以防止当测试套件跟随指向同一内存位置的两个指针时发生的双空闲堆损坏。

以下是工作代码:

void flat_tree(TreeNode* pre, TreeNode* root, stack<TreeNode*>& s){ 
    if(root == NULL){
        if(s.empty()) return;
        else{
            TreeNode* newroot = s.top();  
            s.pop();
            pre->right = newroot;
            flat_tree(pre, newroot,s);
        }
    }else{
        if(root->left == NULL) {
            flat_tree(root, root->right, s); 
        }else if(root->right == NULL){
            root->right = root->left;
            root->left = NULL; /* set the left pointer to null */
            flat_tree(root, root->right, s); 
        }else{
            TreeNode* right = root->right;
            root->right = root->left;
            root->left = NULL; /* do the same here */
            s.push(right);
            flat_tree(root, root->right, s); 
        }
    }
}   

我还建议重新组织分支以避免重复的逻辑:

void flat_tree(TreeNode* pre, TreeNode* root, stack<TreeNode*>& s) { 
    if (root) { 
        if (root->right) {
            s.push(root->right);
        }

        root->right = root->left;
        root->left = NULL;
        flat_tree(root, root->right, s); 
    }
    else if (!s.empty()) {
        pre->right = s.top();
        s.pop();
        flat_tree(pre, pre->right, s);
    }
}
 类似资料:
  • 我正在研究一种递归算法,将二叉树扁平化为单链表。问题陈述: 我写了下面的递归代码,它根本不起作用(返回错误的答案),但我不能从概念上理解为什么不起作用。从根开始,我们拉平根。左根和右根。如果root.left存在,那么root.next(在本例中是root.right)将指向扁平化的left列表。然后,左列表指向右列表的开始。这将沿着树递归地继续下去。 这在概念上有问题吗?我尝试在预序遍历之后对它

  • 给定一棵二叉树,将其展平为就地的链表。 例如,给定以下树: 被压扁的树应该是这样的: 我对其他解决方案很感兴趣,但我想问,为什么在运行代码时,输出只与输入树匹配。

  • 我如何转换使用以下代码,我的二叉树到一个简单的链表。这也许可以用递归来完成。 因此,如果根为NULL,也就是,如果函数没有收到有效的指针,则返回错误消息。 如果根是叶,这是,如果左子节点和右子节点都为NULL,您必须将其添加到叶节点列表中。

  • 这就是我到目前为止的代码(由于递归方面的困难,这并不是太多) 几乎只是将头部指针设置为中间信息(4)

  • 如果水平顺序遍历优于rest遍历,那么在二叉搜索树中学习它们有什么用呢? 与顺序遍历和前序遍历相比,级别顺序遍历似乎更容易获取信息。

  • 我正在尝试将二叉查找树展平为单链表。 二进制搜索树: 扁平化单边链表: 我似乎不知道为什么。 我有一个树节点的结构: 我有一个创建和分配内存到树节点的功能: 我有一个列表节点的结构: 我有一个创建列表节点的函数: 我有工作函数来创建二叉搜索树,插入值,等等,但现在我需要创建一个函数来将树展平为列表。 我只是想不出如何将它展平到一个单链表。我见过很多其他的帖子和网站讨论将二叉搜索树转换为双链表或循环