2016-03-29 6 views
0

私はバイナリ検索ツリーにキーと値のペアを格納するプログラムを作成しました。クラスには、ツリーのルートノードを追跡するルートポインタが含まれています。 This.rootはコンストラクタでnullに設定されます。メソッドは、渡された元のノードを変更しません(Java)

put(K、V)メソッドは、新しいキー/値のペアをツリーに挿入しようとします。キーがすでにツリーに存在する場合、メソッドはそのキーに対応する既存の値を返します。そうでない場合は、キー/値のペアがヘルパーメソッドput(K、V、BNode)を通じて挿入されます。 ***通常はthis.put(...)を返すだけですが、このコードスニペットでは戻り値nullに置き換えて、ルートノードが実際に変更されたかどうかを確認する前にprintステートメントを追加することがあります。

私のプログラムは、最初のキーと値のペアを挿入する際に失敗します。私は私の挿入物にprintステートメントを置き、メソッドが正しく動作するかどうかを確認しました。この場合、curr(これはちょうどthis.root)は、空のツリーから開始しているので、挿入前にはnullです。私は新しいノードを作成し、insert()でこのノードを返します。今currはこの作成されたノードを指し示します。 printステートメント "curr key" + curr.keyは正しいキーを出力し、このノードの作成が成功したことを示します。しかし、this.root.keyを印刷しようとするとNullPointerExceptionが発生します。 2番目のメソッドでcurrを修正すると、最初のメソッドでthis.rootも変更されますか?第二の方法でCURRの

//this.root is the root node of this binary search tree 
public V put(K key, V val) { 
    System.out.println("put reached"); 
    this.put(key, val, this.root); // original return statement 
    System.out.println("root key: " + this.root.key); // checks if root node was modified 
// THIS print statement returns a NullPointerException 

    return null; // dummy return statement 
} 

private V put(K key, V val, BNode curr) { 
    V originalValue = this.get(key, curr); // returns null if key does not exist 
//else returns corresponding key value 

    if (originalValue == null) { 
     curr = this.insert(key, val, curr); // helper method which uses recursion to insert 
     System.out.println("curr key " + curr.key); // checks if curr was modified 
     this.size++; 
     this.state++; 
    } 

    return originalValue; 
} 

private BNode insert(K newKey, V newValue, BNode n) { 
    if (n == null) { 
     return new BNode(newKey, newValue); 
    } else if (newKey.compareTo(n.key) < 0) { 
     n.left = this.insert(newKey, newValue, n.left); 
    } else { 
     n.right = this.insert(newKey, newValue, n.right); 
    } 

    return n; 
} 

答えて

0

はずの修飾はまた、第1の方法ではthis.rootを変更しましたか?

短い答え:いいえ。これは、rootの値が決して変更されないためです。

これは物事を明確にするのに役立ち、これが私ができるよりもうまくいく理由を説明します:Is Java "pass-by-reference" or "pass-by-value"?

新しいノードをルートとして割り当てる場合は、明示的に行う必要があります。メソッドに渡される値を変更しようとするのではなく、currが指すものだけを変更するためです。

trappski迅速な返信用

0

おかげJavaは本当に、私は私のプログラムで抱えてきた問題は、今より理にかなって参照渡しされている場合。しかし、ツリーの一部であるオリジナルのものではなく、重複したBNodeだけが変更されている場合、このような再帰的なメソッドが機能するのはなぜですか?

private BNode deleteMin(BNode n) { 
    if (n.left == null) { 
     return n.right; 
    } 

    n.left = this.deleteMin(n.left); 
    return n; 
} 
+0

ここでは、渡された参照値を変更するのではなく、オブジェクトのメソッドを操作します。 – trappski

関連する問題