Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 package utils;
00025
00026 import java.util.*;
00027
00028 public class BinarySearchTree {
00029
00030 protected BinarySearchNode root;
00031
00032 protected class BinarySearchNode {
00033
00034 public Comparable obj;
00035
00036 public BinarySearchNode left;
00037
00038 public BinarySearchNode right;
00039
00040 public BinarySearchNode(Comparable obj) {
00041 this.obj = obj;
00042 }
00043
00044
00045 protected boolean invariant() {
00046 if ((left != null) && !(left.obj.compareTo(this.obj) < 0)) return false;
00047 if ((right != null) && !(this.obj.compareTo(right.obj) < 0)) return false;
00048 if ((left != null) && (right != null) && !(left.obj.compareTo(right.obj) < 0)) return false;
00049
00050 return true;
00051 }
00052
00053 public boolean isLeaf() {
00054 return ((left == null) && (right == null));
00055 }
00056
00057 }
00058
00059
00066 public boolean add(Comparable obj) {
00067
00068 boolean result;
00069
00070 assert(obj != null);
00071 assert(invariant());
00072
00073 if (root == null) {
00074 root = new BinarySearchNode(obj);
00075 result = true;
00076 }
00077 else result = addRecursive(root, obj);
00078
00079 assert(search(obj) == obj);
00080 assert(invariant());
00081
00082 return result;
00083 }
00084
00085 protected boolean addRecursive(BinarySearchNode node, Comparable obj) {
00086
00087 int comparison = obj.compareTo(node.obj);
00088
00089 if (comparison == 0) {
00090 assert(obj.equals(node.obj));
00091 return false;
00092
00093 } else {
00094
00095 if (comparison < 0) {
00096
00097 if (node.left == null) {
00098 node.left = new BinarySearchNode(obj);
00099 return true;
00100 } else {
00101 return addRecursive(node.left, obj);
00102 }
00103
00104 } else {
00105
00106 assert(comparison > 0);
00107
00108 if (node.right == null) {
00109 node.right = new BinarySearchNode(obj);
00110 return true;
00111 } else {
00112 return addRecursive(node.right, obj);
00113 }
00114 }
00115 }
00116
00117 }
00118
00119 public Comparable search(Comparable obj) {
00120 return searchRecursive(root, obj);
00121 }
00122
00123 protected Comparable searchRecursive(BinarySearchNode node, Comparable obj) {
00124
00125 if (node == null) return null;
00126 else {
00127
00128 int comparison = obj.compareTo(node.obj);
00129
00130 if (comparison == 0) {
00131 assert(node.equals(obj));
00132 return node.obj;
00133 } else {
00134 if (comparison < 0) return searchRecursive(node.left, obj);
00135 else {
00136 assert(comparison > 0);
00137 return searchRecursive(node.right, obj);
00138 }
00139 }
00140 }
00141 }
00142
00143
00144
00145 public boolean delete(Comparable obj) {
00146
00147 assert(false);
00148
00149 assert(invariant());
00150
00151 boolean result;
00152 if (root != null) {
00153
00154 int comparison = obj.compareTo(root.obj);
00155
00156 if (comparison == 0) {
00157 assert(root.obj.equals(obj));
00158 root = null;
00159 result = true;
00160
00161 } else {
00162 if (comparison < 0) return deleteRecursive(root, root.left, obj);
00163 else result = deleteRecursive(root, root.right, obj);
00164 }
00165 } else {
00166 result = false;
00167 }
00168
00169 assert(invariant());
00170 assert(search(obj) == null);
00171
00172 return result;
00173 }
00174
00175 protected boolean deleteRecursive(BinarySearchNode parent, BinarySearchNode node, Comparable obj) {
00176
00177 int comparison = obj.compareTo(node.obj);
00178
00179 if (comparison == 0) {
00180 deleteNode(parent, node);
00181 return true;
00182
00183 } else {
00184
00185 if (comparison < 0) {
00186 if (node.left == null) return false;
00187 else return deleteRecursive(node, node.left, obj);
00188 } else {
00189 assert(comparison > 0);
00190 if (node.right == null) return false;
00191 else return deleteRecursive(node, node.right, obj);
00192 }
00193 }
00194
00195 }
00196
00197 protected void deleteNode(BinarySearchNode parent, BinarySearchNode nodeToDelete) {
00198
00199 if (nodeToDelete.isLeaf()) {
00200
00201 if (nodeToDelete == parent.left) parent.left = null;
00202 else {
00203 assert(nodeToDelete == parent.right);
00204 parent.right = null;
00205 }
00206
00207 } else {
00208
00209 if (nodeToDelete.left == null) {
00210
00211 if (nodeToDelete == parent.left) parent.left = nodeToDelete.right;
00212 else {
00213 assert(nodeToDelete == parent.right);
00214 parent.right = nodeToDelete.right;
00215 }
00216
00217 } else if (nodeToDelete.right == null) {
00218
00219 if (nodeToDelete == parent.left) parent.left = nodeToDelete.left;
00220 else {
00221 assert(nodeToDelete == parent.right);
00222 parent.right = nodeToDelete.left;
00223 }
00224
00225 } else {
00226
00227
00228
00229 }
00230
00231 }
00232
00233 }
00234
00235 protected boolean invariant() {
00236 return invariantRecursive(root);
00237 }
00238
00239 protected boolean invariantRecursive(BinarySearchNode node) {
00240 if (node == null) return true;
00241 else {
00242 boolean result = (node.invariant() && invariantRecursive(node.left) && invariantRecursive(node.right));
00243 return result;
00244 }
00245 }
00246
00247 }