1

High, I'm mostly familiar with C & C++ but I've been trying my hand at java recently.

My issue is that line if (parent.leftChild == temp) is never true. Although parent.leftChild.Key = temp.key (and the rest of the contents are the same), I'm under the impression that the issue is that parent.leftChild's ID in Eclipse's debugger = ...5792 while temp's ID is ...3632.

I was hoping that someone could further explain. A workaround to my code can always be to change the if statement to if (parent.leftChild.key = temp.key), but shouldn't parent.left == temp be valid?

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;
}
nem035
  • 31,501
  • 5
  • 73
  • 88
user2589339
  • 101
  • 10

1 Answers1

2

Every object in Java represents a reference type. Typically, a reference is the memory address at which the object or array is stored. However, since Java references are opaque and cannot be manipulated in any way, this is an implementation detail. Therefore Java doesn't really have pointers like C++ but it has references to objects.

As for your problem, using the workaround you suggested should be the easiest and simplest way to solve your problem. However, if you want to compare objects in Java in general, here is how you do it.

Java has two kinds of object equality:

Object reference equality : when two object references point to the same object.

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

Object value equality : when two separate objects happen to have the same values/state.

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

The reason "equal" is in quotes is because it is up to us to say when exactly are two objects equal.

To be able to value-compare two Java objects of the same class, the boolean equals(Object obj) method must be overridden and implemented by the class.

Note that equal objects must have equal hash codes. Therefore, when overriding the equals method, we must also override the hashCode method. Failure to do so violates the general contract for the hashCode method, and any classes that use the hash code, such as HashMap will not function properly.

We decide which values must be equal to consider two objects to be equal. In your case, you could just override the equals() method without the hashCode since you are not putting Node objects in any containers that require a properly implemented hashCode but you should be aware of the possible consequences. The equals() method inside the Node class could compare nodes based on their keys and would look something like:

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

Then you can just use the following statement in your code:

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

The advantage of using equals() implementation is that you can define object equality in many specific ways so it is a quite flexible solution.

Here is a good stackoverflow thread on this

Here is another useful read

nem035
  • 31,501
  • 5
  • 73
  • 88