0

nullを含む可能性のあるオブジェクトを他のメソッドに渡す最良の方法について質問があります。他のメソッドは、渡されたオブジェクトがnullの場合、オブジェクトがnullの場合に新しいインスタンスを作成します。私の質問は、2番目のメソッドが最初に渡されたnullオブジェクトポインタを変更できるようにする方法についてです。基本的に、ファイルからBSTを読み取り、ツリーを作成しているときに、この問題に直面しました。同じ例を使用して問題を説明すると、より多くの感覚が得られると思います。

以下のコードでは、キューに格納されているすべての値からBSTを読み取って構築しています。キュー値は、別のメソッドから読み取ったツリーのインオーダートラバーサルです。

    TreeNode root2;
public void readBST(Queue<Integer> input){
    if (input==null || input.isEmpty()) return;     
    int i=input.poll();
    root2 = new TreeNode(i);
    readBSTHelper(root2.leftChild , input, Integer.MIN_VALUE , i-1);
    readBSTHelper(root2.rightChild, input, i+1, Integer.MAX_VALUE);
}

private void readBSTHelper(TreeNode curr, Queue<Integer> input, int min, int max){
    if (input==null && input.isEmpty()) return;
    int i = input.peek();
    if (i>=min && i<=max){
        input.poll();
        curr = new TreeNode(i);
        readBSTHelper(curr.leftChild, input, min, i-1);
        readBSTHelper(curr.rightChild,input, i+1, max);
    }
}

しかし、私が直面している問題は、root2が作成されたとき、それはであり、でleftChildあるということrightChildですnull。実際TreeNode(i)には、TreeNodewithdata=iとequalleftChildを作成します。パスを呼び出すと、ポインタが渡されます。これはポインタであるため、ポインタのコピーがに渡されます。したがって、からの結果は失われ、実際に返される/割り当てられることはありません。元のポインタの参照を渡すことにより、C++でこのような問題を防ぐことができます。以下のようにコードを変更することで、一時的に問題を解決することができました。rightChildnullreadBSTHelperroot2.leftChildnullnullnullreadBSTHelperreadBSTHelperroot2.leftChild

    TreeNode root2;
public void readBST(Queue<Integer> input){
    if (input==null || input.isEmpty()) return;     
    int i=input.poll();
    root2 = new TreeNode(i);
    readBSTHelper(root2, "left", input, Integer.MIN_VALUE , i-1);
    readBSTHelper(root2, "right", input, i+1, Integer.MAX_VALUE);
}
private void readBSTHelper(TreeNode curr, String side, Queue<Integer> input, int min, int max){
    if (input.isEmpty()) return;
    int i = input.peek();
    if (i>=min && i<=max){
        input.poll();
        if (side.equals("left")) {
            curr.leftChild = new TreeNode(i);
            readBSTHelper(curr.leftChild,"left", input, min, i-1);
            readBSTHelper(curr.leftChild, "right", input, i+1, max);
        } else {
            curr.rightChild = new TreeNode(i);
            readBSTHelper(curr.rightChild,"left", input, min, i-1);
            readBSTHelper(curr.rightChild, "right", input, i+1, max);
        }

    }
}

しかし、このコードは私には醜いように見えます。最初のコードを機能させる方法について何かアドバイスはありますか?

4

1 に答える 1

2

オプション1:ラッパー

class NodeWrapper
{
  TreeNode node;
}

class TreeNode
{
  ...
  TreeNode(int num)
  {
    leftChild = new NodeWrapper();
    rightChild = new NodeWrapper();
    ...
  }
  NodeWrapper leftChild, rightChild;
}

void readBSTHelper(NodeWrapper curr, Queue<Integer> input, int min, int max)
{
  ...
}

オプション2:コンストラクターで子を初期化します

この目的専用の別のコンストラクターを用意することをお勧めします(以下ではありません)。そうしないと、挿入関数によって誤って子が作成されます。

class TreeNode
{
  ...
  TreeNode()
  {
    val = null;
  }
  TreeNode(int num)
  {
    init(num);
  }
  init(int num)
  {
    leftChild = new TreeNode();
    rightChild = new TreeNode();
    val == num;
  }
  Integer val;
}

public void readBST(Queue<Integer> input){
    if (input==null || input.isEmpty()) return;     
    int i=input.poll();
    root2 = new TreeNode(i);
    if (!readBSTHelper(root2.leftChild , input, Integer.MIN_VALUE , i-1))
      root2.leftChild = null; // delete child if not populated
    if (!readBSTHelper(root2.rightChild, input, i+1, Integer.MAX_VALUE))
      root2.rightChild = null; // delete child if not populated
}

boolean readBSTHelper(TreeNode curr, Queue<Integer> input, int min, int max){
    if (input==null && input.isEmpty()) return false;
    int i = input.peek();
    if (i>=min && i<=max){
        input.poll();
        curr.init(i);
        if (!readBSTHelper(curr.leftChild, input, min, i-1))
          curr.leftChild = null;
        if (!readBSTHelper(curr.rightChild, input, i+1, max))
          curr.rightChild = null;
        return true;
    }
    return false;
}
于 2013-03-08T07:24:05.867 に答える