3

これは Java プログラマーの間で激しく議論され、物議を醸すトピックであることは認識していますが、私の問題はやや独特だと思います。私のアルゴリズムは、参照渡しが必要です。仮想(x、y)座標を割り当てるために、一般的なツリー(つまり、n-children)の時計回り/反時計回りの事前注文トラバーサルを行っています。これは単純に、訪問したツリーのノードをカウント (およびタグ付け) することを意味します。

/**
 * 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

注: 最初の 2 行は、時計回りの事前順序走査と x 座標の割り当てです。次の 2 行は、反時計回りの事前順序走査と y 座標の割り当てです。

私の質問は、2 行目を読み取る方法です。 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 座標として使用します。

4

3 に答える 3

13

Java の値渡しは常に - プリミティブとオブジェクトの両方に対して。非プリミティブに渡されるのは参照であるため、それらが指すオブジェクトの状態を変更できますが、参照自体は変更できません。

「The Java Programming Language」の James Gosling から:

「...Java には 1 つのパラメーター受け渡しモード (値による受け渡し) があり、それによって物事が単純になります。..」

これが最終的な権限だと思います。

これは、Java プログラマーの間で激しく議論され、物議を醸すトピックであることを認識しています。

いいえ、議論はありません。これは、James Gosling によって最初から言語に組み込まれています。それが物議を醸すと思うなら、あなたは悲しいことに惑わされているか、無知です.

于 2010-10-30T20:26:14.017 に答える
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);
}

次のようにスワップを呼び出します。

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でまだ考えていないかのどちらかです。

于 2010-10-30T20:39:06.347 に答える
0

参照渡しは必要ありません。副作用のある関数が必要です。参照渡しは、これを実現する 1 つの方法です。変更可能なオブジェクトを関数の引数として使用するのは別の方法です。

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);
    }
}
于 2010-10-31T00:46:14.757 に答える