BinarySearchTree.java
Go to the documentation of this file.
00001 /*
00002  * (c) copyright 2008, Technische Universitaet Graz and Technische Universitaet Wien
00003  *
00004  * This file is part of jdiagengine.
00005  *
00006  * jdiagengine is free software: you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation, either version 3 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * jdiagengine is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  * You should have received a copy of the GNU General Public License
00016  * along with jdiagengine. If not, see <http://www.gnu.org/licenses/>.
00017  *
00018  * Authors: Joerg Weber, Franz Wotawa
00019  * Contact: jweber@ist.tugraz.at (preferred), or fwotawa@ist.tugraz.at
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;  // the left node must have a value smaller than this node
00037         
00038         public BinarySearchNode right;  // the right node must have a value larger than this node
00039         
00040         public BinarySearchNode(Comparable obj) {
00041             this.obj = obj;
00042         }
00043 
00044         // The invariant checks if the order (left < this < right) is correct.
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     }  // nested class BinarySearchNode
00058 
00059 
00066     public boolean add(Comparable obj) {
00067         
00068         boolean result;
00069 
00070         assert(obj != null);  // precondition
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);  // postcondition
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) {  // obj already exists
00090             assert(obj.equals(node.obj));
00091             return false;
00092 
00093         } else {  
00094             
00095             if (comparison < 0) {  // add to left
00096 
00097                 if (node.left == null) {
00098                     node.left = new BinarySearchNode(obj);  // create new node
00099                     return true;
00100                 } else {
00101                     return addRecursive(node.left, obj);  // recursion: add to left sub-tree
00102                 }             
00103 
00104             } else {  // add to right
00105                 
00106                 assert(comparison > 0);
00107 
00108                 if (node.right == null) {
00109                     node.right = new BinarySearchNode(obj);  // create new node
00110                     return true;
00111                 } else {
00112                     return addRecursive(node.right, obj);  // recursion: add to right sub-tree
00113                 }
00114             }
00115         }
00116 
00117     }  // addRecursive()
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);  // method not yet supported: look for XXX for positions where code is missing!
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) {  // node found!
00180             deleteNode(parent, node);
00181             return true;
00182 
00183         } else {  // node not yet found -> continue search
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     }  // deleteRecursive()
00196     
00197     protected void deleteNode(BinarySearchNode parent, BinarySearchNode nodeToDelete) {
00198         
00199         if (nodeToDelete.isLeaf()) {  // easiest case: node is a leaf
00200 
00201             if (nodeToDelete == parent.left) parent.left = null;
00202             else {
00203                 assert(nodeToDelete == parent.right);
00204                 parent.right = null;
00205             }
00206         
00207         } else {  // node is not a leaf
00208             
00209             if (nodeToDelete.left == null) {  // nodeToDelete has no left child
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) {   // nodeToDelete has no right child
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 {  // nodeToDelete has 2 children
00226                 
00227                 // XXX
00228 
00229             }
00230 
00231         }
00232 
00233     }  // deleteNode()
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 }


tug_ist_diagnosis_engine
Author(s): Safdar Zaman, Gerald Steinbauer
autogenerated on Mon Jan 6 2014 11:51:16