1

ハイ、私はほとんど C と C++ に精通していますが、最近は Java を試しています。

私の問題は、その行if (parent.leftChild == temp)が決して真実ではないということです。(そしてparent.leftChild.Key = temp.key残りの内容は同じです)が、問題は、Eclipseのデバッガーでのparent.leftChildのID = ... 5792であるのに対し、tempのIDは... 3632であるという印象を受けています。

誰かがさらに説明できることを望んでいました。私のコードの回避策は、常に if ステートメントを に変更することですが、有効if (parent.leftChild.key = temp.key)ではありませんか?parent.left == temp

class Node{
int key;
char color;

Node leftChild;
Node rightChild;
Node parent;
//...constructors..//
}

private Node GetParent(Node node){
    if(node != null)
        return node.parent;
    else
        return null;
}

private void RemoveNodeFromTree(Node myNode){
    Node temp  = new Node(myNode);

    //traverse
    if(temp.leftChild!= null){
        temp = temp.leftChild;
        while(temp.rightChild!= null)
            temp = temp.rightChild;

        myNode.key = temp.key;
    }
    else if(temp.rightChild != null)
        myNode.key = temp.rightChild.key;

    Node parent = GetParent(temp);
    Node childL = temp.leftChild;
    Node childR = temp.rightChild;

    //have parent point to the proper new node.
    //parent points to left if it exists, then it tries right. 
    //if both are null, point to right anyway
    if(parent !=null ){
        //replace temp with it's left child
        if(childL!= null){
            if (parent.leftChild == temp)
                parent.leftChild = childL;
            else
                parent.rightChild = childL;

            childL.parent = parent;

            childL.color = 'B';
            if(childL.color == 'B' && temp.color == 'B')
                DoubleBlackRestructure(childL, parent);
        }
        else //replace temp with it's right child
        {
            if (parent.leftChild == temp)
                parent.leftChild = childR;
            else
                parent.rightChild = childR;

            if(childR!= null)
                childR.parent = parent;

            if((childR == null || childR.color == 'B') && temp.color == 'B')
            {
                if(childR != null)
                    childR.color = 'B';
                DoubleBlackRestructure(childR, parent);
            }
            else if (childR != null)
                childR.color = 'B';
        }
    }
    else
        myNode = null;
    temp = null;
}
4

1 に答える 1

2

Java のすべてのオブジェクトはreference type. 通常、参照は、オブジェクトまたは配列が格納されているメモリ アドレスです。ただし、Java 参照は不透明であり、いかなる方法でも操作できないため、これは実装の詳細です。したがって、Java には C++ のようなポインタはありませんが、オブジェクトへの参照があります。

問題に関しては、提案された回避策を使用することが、問題を解決する最も簡単で簡単な方法です。ただし、一般的に Java でオブジェクトを比較する場合は、次のようにします。

Java には 2 種類のオブジェクトの等価性があります。

オブジェクト参照の等価性: 2 つのオブジェクト参照が同じオブジェクトを指している場合。

if (obj1 == obj2) {
    // The two object references point to the same object
}

オブジェクト値の等価性: 2 つの別個のオブジェクトがたまたま同じ値/状態を持っている場合。

if(obj1.equals(obj2)) {
   // two object references contain "equal" objects
}

「等しい」が引用符で囲まれている理由は、2 つのオブジェクトがいつ等しいかを判断するのは私たち次第だからです。

同じクラスの 2 つの Java オブジェクトの値を比較できるようにするには、クラスboolean equals(Object obj)によってメソッドをオーバーライドして実装する必要があります。

等しいオブジェクトには、等しいハッシュ コードが必要であることに注意してください。したがって、equalsメソッドをオーバーライドするときは、メソッドもオーバーライドする必要がありますhashCode。そうしないと、メソッドの一般規約に違反しhashCode、ハッシュ コードを使用するクラス ( など)HashMapが正しく機能しなくなります。

2 つのオブジェクトが等しいと見なすには、どの値が等しくなければならないかを決定します。あなたの場合、適切に実装された を必要とするコンテナにオブジェクトを配置していないため、equals()なしでメソッドをオーバーライドすることができますが、考えられる結果に注意する必要があります。クラス内のメソッドは、キーに基づいてノードを比較でき、次のようになります。hashCodeNodehashCodeequals()Node

class Node {
    int key;
    char color;

    Node leftChild;
    Node rightChild;
    Node parent;

    //...constructors..//

    boolean equals(Object obj) {
        //null instanceof Object will always return false
        if (!(obj instanceof Node)) {
            return false;
        }
        // each object is obviously equal to itself
        if (obj == this) {
            return true;
        }
        return  this.key == ((Node) obj).key;
    }

    /* This is a simple example of how to override the hashCode as well.
    public int hashCode() {
        // some code to represent each node uniquely
        // i just assume each node has a unique key
        return this.key
    }
    */
}

次に、コードで次のステートメントを使用できます。

if (parent.leftChild.key.equals(temp.key))

実装を使用する利点はequals()、多くの特定の方法でオブジェクトの等価性を定義できるため、非常に柔軟なソリューションになることです。

Here is a good stackoverflow thread on this

Here is another useful read

于 2014-10-12T01:16:41.503 に答える