1 /**
2 This class implements a binary search tree whose
3 nodes hold objects that implement the Comparable
4 interface.
5 */
6 public class BinarySearchTree
7 {
8 private Node root;
9
10 /**
11 Constructs an empty tree.
12 */
13 public BinarySearchTree()
14 {
15 root = null;
16 }
17
18 /**
19 Inserts a new node into the tree.
20 @param obj the object to insert
21 */
22 public void add(Comparable obj)
23 {
24 Node newNode = new Node();
25 newNode.data = obj;
26 newNode.left = null;
27 newNode.right = null;
28 if (root == null) root = newNode;
29 else root.addNode(newNode);
30 }
31
32 /**
33 Tries to find an object in the tree.
34 @param obj the object to find
35 @return true if the object is contained in the tree
36 */
37 public boolean find(Comparable obj)
38 {
39 Node current = root;
40 while (current != null)
41 {
42 int d = current.data.compareTo(obj);
43 if (d == 0) return true;
44 else if (d > 0) current = current.left;
45 else current = current.right;
46 }
47 return false;
48 }
49
50 /**
51 Tries to remove an object from the tree. Does nothing
52 if the object is not contained in the tree.
53 @param obj the object to remove
54 */
55 public void remove(Comparable obj)
56 {
57 // Find node to be removed
58
59 Node toBeRemoved = root;
60 Node parent = null;
61 boolean found = false;
62 while (!found && toBeRemoved != null)
63 {
64 int d = toBeRemoved.data.compareTo(obj);
65 if (d == 0) found = true;
66 else
67 {
68 parent = toBeRemoved;
69 if (d > 0) toBeRemoved = toBeRemoved.left;
70 else toBeRemoved = toBeRemoved.right;
71 }
72 }
73
74 if (!found) return;
75
76 // toBeRemoved contains obj
77
78 // If one of the children is empty, use the other
79
80 if (toBeRemoved.left == null || toBeRemoved.right == null)
81 {
82 Node newChild;
83 if (toBeRemoved.left == null)
84 newChild = toBeRemoved.right;
85 else
86 newChild = toBeRemoved.left;
87
88 if (parent == null) // Found in root
89 root = newChild;
90 else if (parent.left == toBeRemoved)
91 parent.left = newChild;
92 else
93 parent.right = newChild;
94 return;
95 }
96
97 // Neither subtree is empty
98
99 // Find smallest element of the right subtree
100
101 Node smallestParent = toBeRemoved;
102 Node smallest = toBeRemoved.right;
103 while (smallest.left != null)
104 {
105 smallestParent = smallest;
106 smallest = smallest.left;
107 }
108
109 // smallest contains smallest child in right subtree
110
111 // Move contents, unlink child
112
113 toBeRemoved.data = smallest.data;
114 if (smallestParent == toBeRemoved)
115 smallestParent.right = smallest.right;
116 else
117 smallestParent.left = smallest.right;
118 }
119
120 /**
121 Prints the contents of the tree in sorted order.
122 */
123 public void print()
124 {
125 if (root != null)
126 root.printNodes();
127 System.out.println();
128 }
129
130 /**
131 A node of a tree stores a data item and references
132 of the child nodes to the left and to the right.
133 */
134 class Node
135 {
136 public Comparable data;
137 public Node left;
138 public Node right;
139
140 /**
141 Inserts a new node as a descendant of this node.
142 @param newNode the node to insert
143 */
144 public void addNode(Node newNode)
145 {
146 int comp = newNode.data.compareTo(data);
147 if (comp < 0)
148 {
149 if (left == null) left = newNode;
150 else left.addNode(newNode);
151 }
152 else if (comp > 0)
153 {
154 if (right == null) right = newNode;
155 else right.addNode(newNode);
156 }
157 }
158
159 /**
160 Prints this node and all of its descendants
161 in sorted order.
162 */
163 public void printNodes()
164 {
165 if (left != null)
166 left.printNodes();
167 System.out.print(data + " ");
168 if (right != null)
169 right.printNodes();
170 }
171 }
172 }
173
174
175