避免递归中的静态变量

时间:2019-04-17 13:25:49

标签: java reference static tree

我的树节点定义为:

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;
}

它没有用。我认为他们每次都在创建新实例。

1 个答案:

答案 0 :(得分:0)

似乎第二种方法将起作用,但最后一种方法将不起作用。原因是在最后一个方法中,您将引用的副本传递给Node(参数previoushead)。因此,调用者将看不到被调用方法中previoushead的变化。

有关此的更多信息,您可以阅读文章https://www.javaworld.com/article/2077424/learn-java-does-java-pass-by-reference-or-pass-by-value.html

我认为,如果将参数previoushead的类型从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世界中,考虑以小写字母开头的方法名称。