提问人:Yash Meshram 提问时间:7/10/2022 最后编辑:Yash Meshram 更新时间:7/12/2022 访问量:122
将给定的二叉树转换为双倍链表
Convert A Given Binary Tree To Doubly Linked List
问:
问题陈述是:
给定一个二叉树,将这个二叉树转换为双向链表。 二叉树 (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;
}
我对此表示怀疑.
指针适用于按值传递,在按引用传递时不起作用。root
root
当 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);
}
我如何知道哪个变量应该通过引用传递,哪个变量应该通过指针的值传递?
答:
0赞
mitch_
7/10/2022
#1
乍一看,一个问题是 API 本身。您正在分配 ;要了解为什么这是一个问题,请考虑以下更简单的示例:inorder
nroot = root
void set_x(int *x, int *y)
{
x = y;
}
请记住,指针实际上只是内存地址。因此,赋值说,“替换包含的内存地址,并将其设置为包含的任何内容”。在任何阶段,您都不会实际更改内存地址的值。x = y
x
y
现在,再次考虑,这里你只是给局部变量一个新的内存地址,但没有更新任何内容。因此,在您的呼叫端,您为地址提供它,它从不使用它,也从不设置它。因此,永远不会看到 .nroot = root
BTtoDLL
nullptr
BTtoDLL
nroot
评论
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&
root
const &
评论