我的树节点定义为:
class Node{
int data;
Node left,right;
Node(int d)
{
data=d;
left=null;
right=null;
}
}
我正在编写用于从二叉树构造双链表(nodes in which should be in the inorder traversal of the given tree)
的代码。
我的问题是第二种方法如何工作。我没有得到它。我想知道它的工作原理(我根据其他一些示例对method-2进行了编码)
我已经通过两种方式进行了尝试:
1)使用静态变量prev(用于维护上一个节点)
2)不使用它(使用过一个类)
方法1如下:
//method-1
static Node previous=null,head=null;
Node Btree2DLL(Node n) /
{
if(n==null)
return n;
Btree2DLL(n.left);
if(previous==null)
{
head=n;
}
else
{
previous.right=n;
n.left=previous;
}
previous=n;
Btree2DLL(n.right);
return head;
}
方法2如下:
//method-2
class PreviousandHead
{
Node HEADOFDLL,PREV;
}
Node Tree2DLL(Node n)
{
PreviousandHead p=new PreviousandHead();
return Btree2DLL(n,p);
}
Node Btree2DLL(Node n,PreviousandHead p)
{
if(n==null)
return n;
Btree2DLL(n.left,p);
if(p.PREV==null)
{
p.HEADOFDLL=n;
}
else
{
p.PREV.right=n;
n.left=p.PREV;
}
p.PREV=n;
Btree2DLL(n.right,p);
return p.HEADOFDLL;
}
之前,我尝试在方法2中传递参数而不创建类PreviousandHead的方式为:
Node B2DLL(Node n)
{
return Btree2DLL(n,null,null);
}
Node Btree2DLL(Node n,Node previous,Node head)
{
if(n==null)
return n;
Btree2DLL(n.left,Node previous,Node head);
if(previous==null)
{
head=n;
}
else
{
previous.right=n;
n.left=previous;
}
previous=n;
Btree2DLL(n.right,Node previous,Node head);
return head;
}
它没有用。我认为他们每次都在创建新实例。
答案 0 :(得分:0)
似乎第二种方法将起作用,但最后一种方法将不起作用。原因是在最后一个方法中,您将引用的副本传递给Node(参数previous
和head
)。因此,调用者将看不到被调用方法中previous
和head
的变化。
有关此的更多信息,您可以阅读文章https://www.javaworld.com/article/2077424/learn-java-does-java-pass-by-reference-or-pass-by-value.html
我认为,如果将参数previous
和head
的类型从Node
更改为AtomicReference<Node>
,则您的代码将起作用
Node b2DLL(Node n)
{
return btree2DLL(n, new AtomicReference<>(), new AtomicReference<>());
}
Node btree2DLL(Node n, AtomicReference<Node> previous, AtomicReference<Node> head)
{
if(n == null)
return n;
btree2DLL(n.left, previous, head);
if(previous.get() == null)
{
head.set(n);
}
else
{
previous.get().right = n;
n.left = previous.get();
}
previous.set(n);
btree2DLL(n.right, previous, head);
return head.get();
}
在Java世界中,考虑以小写字母开头的方法名称。