将给定的二叉树转换为双倍链表

Convert A Given Binary Tree To Doubly Linked List

提问人:Yash Meshram 提问时间:7/10/2022 最后编辑:Yash Meshram 更新时间:7/12/2022 访问量:122

问:

问题陈述是:

给定一个二叉树,将这个二叉树转换为双向链表。 二叉树 (BT) 是一种数据结构,其中每个节点最多有两个子节点。 双向链表包含上一个指针,以及下一个指针和数据。 双重链表中节点的顺序必须与给定二叉树的顺序相同。 应通过将下一个指针作为右指针,将前一个指针作为左指针来返回双向链表。

您需要返回双重链表的头部。

例如:

    4
   / \
  2   5
 / \
1   3

双链表为:1 2 3 4 5

我的代码是:

class BinaryTreeNode 
{
public :
    T data;
    BinaryTreeNode<T> *left;
    BinaryTreeNode<T> *right;

    BinaryTreeNode(T data) {
        this -> data = data;
        left = NULL;
        right = NULL;
    }
};

void inorder(BinaryTreeNode<int>* root,BinaryTreeNode<int>* &prev,BinaryTreeNode<int>* &nroot){
    if(!root) return;
    
    inorder(root->left,prev,nroot);
    if(prev == NULL) nroot=root;
    else{
        root->left = prev;
        prev->right=root;
    }
    prev=root;
    inorder(root->right,prev,nroot);
}

BinaryTreeNode<int>* BTtoDLL(BinaryTreeNode<int>* root) {
    BinaryTreeNode<int>* prev=NULL;
    BinaryTreeNode<int>* nroot=NULL;
    inorder(root,prev,nroot); 
    return nroot;
}

我对此表示怀疑. 指针适用于按值传递,在按引用传递时不起作用。rootroot

当 root 通过引用传递时,它不起作用。

void inorder(BinaryTreeNode<int>*& root,BinaryTreeNode<int>*& prev,BinaryTreeNode<int>* &nroot){
    if(!root) return;
    
    inorder(root->left,prev,nroot);
    if(prev == NULL) nroot=root;
    else{
        root->left = prev;
        prev->right=root;
    }
    prev=root;
    inorder(root->right,prev,nroot);
}

我如何知道哪个变量应该通过引用传递,哪个变量应该通过指针的值传递?

指针 binary-tree pass-by-value

评论

0赞 Pepijn Kramer 7/10/2022
在课程中查找(左)深度优先搜索。问问你的老师,在你完成数据结构作业后,他会告诉你 STL 中的数据结构(比如 std::list),因为这些将是你将来实际使用的数据结构。
0赞 trincot 7/11/2022
请更新您的问题,这样它就不是最初不起作用,现在起作用的历史,但另一件事仍然是一个疑问。从你问题的一开始就专注于当前的问题。删除已修复的历史记录。

答:

0赞 mitch_ 7/10/2022 #1

乍一看,一个问题是 API 本身。您正在分配 ;要了解为什么这是一个问题,请考虑以下更简单的示例:inordernroot = root

void set_x(int *x, int *y)
{
  x = y;
}

请记住,指针实际上只是内存地址。因此,赋值说,“替换包含的内存地址,并将其设置为包含的任何内容”。在任何阶段,您都不会实际更改内存地址值。x = yxy

现在,再次考虑,这里你只是给局部变量一个新的内存地址,但没有更新任何内容。因此,在您的呼叫端,您为地址提供它,它从不使用它,也从不设置它。因此,永远不会看到 .nroot = rootBTtoDLLnullptrBTtoDLLnroot

评论

0赞 Yash Meshram 7/10/2022
嘿,你的意思是说当我传递 prev 和 nroot 的值时,它们的值在 BTtoDLL 函数中没有更改。因此,我需要通过引用传递这些值。
0赞 Yash Meshram 7/10/2022
我需要通过引用传递指针“prev”和“nroot”。现在我对“根”指针还有另一个疑问。“根”指针适用于按值传递。但是当“root”通过引用传递时,它就不起作用了。我如何知道哪个变量应该通过引用传递,哪个变量应该通过指针的值传递?
0赞 mitch_ 7/11/2022
是的,您可以通过引用来获取这些值,但在这件事上我会考虑使用替代 API,因为处理各种外指针可能有点难以推理。根据实现的要求,更好的选择是让 which 按顺序访问每个节点,并根据该值调用函数。这样,您可以以更具声明性的方式按值顺序重构树。BinaryTreeNode<T>::traverse(std::function<void(T)>)
0赞 mitch_ 7/11/2022
我通常会在读取值时经过,但按值传递,并在我打算改变值时经过会很昂贵。在第二个示例中,由于您采用非常量引用,因此您对它所做的任何更改也会影响调用站点的值,因此您可以改为按值或按其复制。const T&T&rootconst &