Professional Documents
Culture Documents
Fields
The definition of a binary tree pretty much requires the following fields:
Object value; BinaryTree leftChild; BinaryTree rightChild;
Maintaining control
It is the responsibility of any class to ensure the safety and validity of its objects Is there any real harm in letting the fields of a node in a binary tree be public?
In other words, how easily can the binary tree be damaged? I claim its quite easy, as I will demonstrate shortly In my design, leftChild, rightChild, and parent are private, and I provide getters and setters
For consistency, the value field should also be privatehowever, this is not a validity issue
3
Header nodes
With a header: BinaryTreeHeader myTree Without a header: BinaryTree myTree
I dont like to use a header node for a binary tree, because that gets in the way of treating the subtrees as binary trees in their own right
5
Constructors
There is an obvious three-argument constructor that we need:
public BinaryTree(Object value, BinaryTree leftChild, BinaryTree rightChild) { ... }
Naive setLeftChild
Remember that, in this design, a node also has a link to its parent This version of
setLeftChild
Now is this code correct? Is it reasonable to set the left child to null?
A binary tree can be empty, so yes
Do you see any more problems? What if the left child was originally null?
10
Now is there anything wrong? What if the new child already has a parent?
11
I think that this is a problem only if the new child is an ancestor of the node it is to be added to
This is an O(log n) search, if the tree is balanced Is this worth doing? Its a judgment callhow safe does our code need to be? The answer depends on what the code is for
14
2. To preserve flexibility, in case you might want to change the object some time in the future
For example, if we did not originally have the parent link, the following code would have been enough: public void setLeftChild(BinaryTree newChild) { leftChild = newChild; } We might have felt this method is silly and not bothered with it
15
Taking stock
Are the constructors and mutators (setXxx methods) adequate to construct any binary tree?
Yes, provided you start from the root and build the binary tree by working downwards However, there isnt much support for changing an existing binary tree
16
17
detach()
After all weve been through with setLeftChild, detach is pretty trivial:
public void detach() { if (parent != null) { if(parent.leftChild == this) parent.leftChild = null; else parent.rightChild = null; parent = null; } }
19
20
Serialization methods
In case the binary tree needs to be serialized, I added the following two methods:
public static BinaryTree load(String fileName) throws IOException public void save(String fileName) throws IOException
Because a binary tree isnt terribly easy to read when its shown linearly, I also wrote the following method to give me a nicely indented tree:
public void print()
22
toString
public String toString() { if (isLeaf()) return value.toString(); StringBuffer buffer = new StringBuffer(); buffer.append("[" + value + ", "); root if (leftChild == null) buffer.append("null"); left else buffer.append(leftChild.toString()); subtree buffer.append(", "); if (rightChild == null) buffer.append("null"); right else buffer.append(rightChild.toString()); subtree buffer.append("]"); return buffer.toString(); }
23
print()
toString is handy for producing condensed,
single-line output, but doesnt show the shape of the binary tree To keep track of indentation, we need either a global variable (bad) or a parameter (OK) I dont want the user to have to supply this parameter, so:
public void print() { print(""); } private void print(String indent) { ... }
24
print(String indent)
private void print(String indent) { System.out.println(indent + value); root if (isLeaf()) return; if (leftChild == null) { System.out.println(indent + " " + "null"); } else { leftChild.print(indent + " "); } if (rightChild == null) { System.out.println(indent + " " + "null"); } else { rightChild.print(indent + " "); } }
25
left subtree
right subtree
Final comments
I didnt think of everything when I first wrote setLeftChildmy first version was pretty sloppy
Maybe there are still some problems Ive overlooked No program is ever perfect Corrections are, as always, welcome
26
The End
27