我意识到这是一个备受争议的Java程序员争议话题,但我相信我的问题有点独特。我的算法 REQUIRES 通过引用传递。我正在进行一般树(即n-children)的顺时针/逆时针预先遍历遍历,以分配虚拟(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);
}
这里我生成了树的结构:
Tree root = new Tree(new Integer(0));
root.addChild(new Tree(new Integer(1), root));
root.addChild(new Tree(new Integer(2), root));
root.addChild(new Tree(new Integer(3), root));
Iterator<Tree> ci = root.ChildrenIterator();
ci.next();
Tree select = ci.next();
select.addChild(new Tree(new Integer(4), select));
select.addChild(new Tree(new Integer(5), select));
当我打印遍历节点的顺序以及它分配给相应节点的坐标时,这是我的输出。
0 3 2 5 4 1
0 1 2 3 4 3
0 1 2 4 5 3
0 1 2 3 4 3
注意:前两行是顺时针预先遍历遍历和x坐标的分配。接下来的两行是逆时针预先遍历遍历并分配它们的y坐标。
我的问题是我如何能够阅读第二行:
0 1 2 3 4 5
编辑1:这是我用来打印我访问节点的顺序和我指定的坐标的代码。
Iterator<Tree> pre = root.PreOrder(true);
System.out.println(" \t");
while(pre.hasNext())
System.out.print(pre.next() + "\t");
pre = root.PreOrder(true);
System.out.println();
System.out.println("x-coordinates:\t");
while(pre.hasNext())
System.out.print(pre.next().getVirtual_x() + "\t");
System.out.println();
System.out.println();
Iterator<Tree> preCC = root.PreOrder(false);
System.out.println(" \t");
while(preCC.hasNext())
System.out.print(preCC.next() + "\t");
preCC = root.PreOrder(false);
System.out.println();
System.out.println("x-coordinates:\t");
while(preCC.hasNext())
System.out.print(preCC.next().getVirtual_y() + "\t");
这里还有一个引用来更好地解释x,y坐标。 顶点。顶点的y坐标。
逆时针计算 预先排序T的顶点( 订购编号从0到n - 1),使用它们作为x坐标 顶点。
计算顺时针的预先排序 T的顶点(排序是 编号从0到n - 1),用它们作为 顶点的y坐标。
答案 0 :(得分:13)
Java总是通过值传递 - 对于基元和对象。它是为非基元传递的引用,因此您可以更改它们指向的对象的状态,但不能更改引用本身。
来自James Gosling的“Java编程语言”:
“......只有一个参数 在Java中传递模式 - 按值传递 - 这让事情变得简单。 ..“
我认为这是对此的最终权威。
我意识到这是一个备受争议的Java程序员争议话题
不,没有辩论。詹姆斯·戈斯林(James Gosling)从一开始就将这种语言融入到语言中。如果你认为这是有争议的,那你就会被遗憾或无知。
答案 1 :(得分:0)
实际上,有一种方法可以通过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);
}
并像这样调用swap:
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思考。
答案 2 :(得分:0)
您不需要通过引用传递,您需要具有副作用的函数。通过引用传递将是实现这一目标的一种方式;使用可变对象作为函数参数将是另一个。
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);
}
}