Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java递归:按引用传递_Java_Pass By Reference_Graph Theory_Pass By Value - Fatal编程技术网

Java递归:按引用传递

Java递归:按引用传递,java,pass-by-reference,graph-theory,pass-by-value,Java,Pass By Reference,Graph Theory,Pass By Value,我意识到这对Java程序员来说是一个激烈争论、有争议的话题,但我相信我的问题有点独特。我的算法需要通过引用传递。我正在对一棵普通树(即n个子树)进行顺时针/逆时针的预顺序遍历,以分配虚拟(x,y)坐标。这仅仅意味着我在访问树的节点时对它们进行计数(并标记) /** * Generates a "pre-ordered" list of the nodes contained in this object's subtree * Note: This is counterc

我意识到这对Java程序员来说是一个激烈争论、有争议的话题,但我相信我的问题有点独特。我的算法需要通过引用传递。我正在对一棵普通树(即n个子树)进行顺时针/逆时针的预顺序遍历,以分配虚拟(x,y)坐标。这仅仅意味着我在访问树的节点时对它们进行计数(并标记)

/**
 * Generates a "pre-ordered" list of the nodes contained in this object's subtree
 * Note: This is counterclockwise pre-order traversal
 * 
 * @param clockwise set to true for clockwise traversal and false for counterclockwise traversal
 * 
 * @return Iterator<Tree> list iterator
 */
public Iterator<Tree> PreOrder(boolean clockwise)
{
    LinkedList<Tree> list = new LinkedList<Tree>();
    if(!clockwise)
        PreOCC(this, list);
    else
        PreO(this,list);
    count = 0;
    return list.iterator();
}
private void PreOCC(Tree rt, LinkedList<Tree> list)
{
    list.add(rt);
    rt.setVirtual_y(count);
    count++;
    Iterator<Tree> ci = rt.ChildrenIterator();
    while(ci.hasNext())
        PreOCC(ci.next(), list);      
}
private void PreO(Tree rt, LinkedList<Tree> list, int count)
{
    list.add(rt);
    rt.setX_vcoordinate(count);
    Iterator<Tree> ci = rt.ReverseChildrenIterator();
    while(ci.hasNext())
        PreO(ci.next(), list, ++count);
}
这里还有一句话可以更好地解释x,y坐标。 顶点。顶点的y坐标

逆时针计算 T(T)顶点的预排序 排序从0到n进行编号− 1) ,将它们用作的x坐标 顶点

按顺时针方向计算 T(序)的顶点是 从0到n编号− 1) ,将它们用作 顶点的y坐标


Java的传递值,始终适用于原语和对象。它是为非原语传递的引用,因此您可以更改它们指向的对象的状态,但不能更改引用本身

James Gosling在《Java编程语言》一书中写道:

“…只有一个参数 Java中的传递模式-按值传递- 这让事情变得简单……”

我认为这是这方面的最终权威

我意识到这对Java程序员来说是一个激烈争论、有争议的话题


不,没有争论。詹姆斯·戈斯林从一开始就将这一点融入到语言中。如果你认为这是有争议的,那你就很不幸地被蒙蔽或无知了。

事实上,在Java中有一种通过引用传递的方法:

class Pointer {
    private Object ptr;
    public Pointer(Object v)  { set(v);  }
    public void set(Object v) { ptr = v; }
    public Object get()       { return ptr; }
}
你使用它们:

public void swap(Pointer a, Pointer b) {
    Object tmp = a.get();
    a.set(b.get());
    b.set(tmp);
}
然后像这样进行呼叫交换:

public static void main(String[] args) {
    Integer one = 1; 
    Integer two = 2;
    Pointer pone; pone.set(one);
    Pointer ptwo; ptwo.set(two);
    swap(pone, ptwo);
    System.out.println((Integer) pone.get());
    System.out.println((Integer) ptwo.get());
}

不过,如果你真的这么做,那么你可能是疯了,或者只是还没有用Java思考。

你不需要通过引用传递,你需要一个有副作用的函数。通过引用将是实现这一目标的一种方法;使用可变对象作为函数参数将是另一种选择

private void PreO(Tree rt, LinkedList<Tree> list, int[] count)
{
    list.add(rt);
    rt.setX_vcoordinate(count[0]);
    Iterator<Tree> ci = rt.ReverseChildrenIterator();
    while(ci.hasNext()) {
        ++count[0];
        PreO(ci.next(), list, count);
    }
}
private void PreO(树rt、链接列表、int[]计数)
{
列表。添加(rt);
rt.setX_vcoordinate(计数[0]);
迭代器ci=rt.ReverseChildrenIterator();
while(ci.hasNext()){
++计数[0];
PreO(ci.next(),list,count);
}
}

我同意。这让我们更难理解在这里该做什么!Nathan你确定你正在建造的树有你想要的结构吗?我看不出节点的预顺序遍历是如何以012345的顺序访问它们的。@matt:我不是按这个顺序访问它们的。访问节点的顺序为顶行。我将发布所有这些代码,因为它似乎让很多人感到困惑。好吧,我理解这一点,但这如何帮助我解决我的问题?提出这个问题的原因不是为了引发辩论,而是为了解决我提出的问题。令人遗憾的是,存在着辩论——当然,一方是无知的。就在昨晚,一个随机的家伙给我发了一封电子邮件,试图让我相信Java总是使用pass-by-reference:(对我来说,这就像神创论和进化论:两者的权重并不相等。@Nathan-对不起,你的问题措辞让人觉得你不仅认为Java是通过引用传递的,而且它是你问题的解决方案。如果你不相信,我会编辑你的措辞。我也会让你的问题更清楚,因为我不相信用递归来进行遍历通常是在java中完成的。也许还有其他的东西你错过了。我想它们是差不多的。很明显,这实际上不是在做引用。它是通过额外的间接引用来模拟引用的。我不是说它不起作用,只是它不像是在改变语言。s传递方案:)这不是按引用传递-抱歉。@duffymo:是的,它不是按引用传递,它更类似于按指针传递。如果将所有
a.get()
替换为
*a
a.set(…)
使用
*a=…
,您将从C/C++中获得更熟悉的pass-by指针。指针通常被认为是一种特定形式的引用,因此pass-by-pointer是一种特定类型的pass-by-reference(尽管一些纯粹主义者可能不同意,因为指针本身仍然是按值传递的)@duffymo:还有,你需要一点幽默感;)当我看到一些幽默的东西时,我会笑。如果你用这段代码来表达你的苦涩的一面,恐怕是这样,互联网和浏览器正在过滤掉它。
public static void main(String[] args) {
    Integer one = 1; 
    Integer two = 2;
    Pointer pone; pone.set(one);
    Pointer ptwo; ptwo.set(two);
    swap(pone, ptwo);
    System.out.println((Integer) pone.get());
    System.out.println((Integer) ptwo.get());
}
private void PreO(Tree rt, LinkedList<Tree> list, int[] count)
{
    list.add(rt);
    rt.setX_vcoordinate(count[0]);
    Iterator<Tree> ci = rt.ReverseChildrenIterator();
    while(ci.hasNext()) {
        ++count[0];
        PreO(ci.next(), list, count);
    }
}