Subversion Repositories programming

Rev

Rev 100 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
47 irasnyd 1
// Written by Ira Snyder
2
// Due Date: 11-24-2004
3
// Project #4
4
// Helped and was Helped By: Allen Oliver
5
// Got information from: 
6
//     http://www.cs.dartmouth.edu/~chepner/cs15/notes/08_bst.html
108 ira 7
// License: Public Domain, except for code from the above source
8
// License: I am unsure of their license. (added 07-11-2005)
47 irasnyd 9
 
10
import java.io.*;
11
import java.util.*;
12
 
13
class BSTree {
14
    private int key, height;
15
    private Object data;
16
    private BSTree left, right;
17
 
18
    //create an empty tree to be used instead of checking
19
    //for nulls all over the place
20
    public static final BSTree NIL = new BSTree();
21
 
22
    //constructor for the basic BSTree
23
    public BSTree( int key, Object data ) {
24
        this.key = key;
25
        this.data = data;
26
        left = right = NIL;
27
    }
28
 
29
    //method to insert a new key-data pair into the tree
30
    public boolean add( int key, Object data ) {
31
        int oldSize = size();
32
        grow(key,data);
33
        return size() > oldSize;
34
    }
35
 
36
    //provide name mapping for add
37
    public boolean insert( int key, Object data ) {
38
        return add(key,data);
39
    }
40
 
41
    //method to add an element to a tree
42
    private BSTree grow( int key, Object data ) {
43
        if( this == NIL ) return new BSTree(key,data);
44
 
45
        //prevent key dupes, update data
46
        if( key == this.key ) { this.data = data; return this; } 
47
        if( key < this.key ) left = left.grow(key,data);
48
        else right = right.grow(key,data);
49
 
50
        height = 1 + Math.max(left.height,right.height);
51
        return this;
52
    }
53
 
54
    //method to return the size of the tree
55
    public int size() {
56
        if( this == NIL ) return 0;
57
        return 1 + left.size() + right.size();
58
    }
59
 
60
    //I like the BinaryTree toString better than the author's toString()
61
    //so I used it here instead. I left the author's code for completeness.
62
    /*
63
    public String toString() {
64
        if( this == NIL ) return "";
65
        return left + " " + key + " " + right;
66
    }
67
    */
68
 
69
    //method to print the tree as a String
70
    public String toString() {
71
 
72
        if( this == NIL ) return "()";
73
 
74
        String sLeft = sLeft = left.toString();
75
        String sRight = sRight = right.toString();
76
        String answer = new String();
77
 
78
        //assemble the string to return
79
        answer = "(";
80
        if( !sLeft.equals("()") ) { answer += sLeft + ","; }
81
        answer += key;
82
        if( !sRight.equals("()") ) { answer += "," + sRight; }
83
        answer += ")";
84
 
85
        //return the assembled string
86
        return answer;
87
    }
88
 
89
    //constructor to make the empty tree
90
    private BSTree() {
91
        left = right = this;
92
        height = -1;
93
    }
94
 
95
    //constructor to make a new BSTree given a key-data pair, and left
96
    //and right subtrees
97
    private BSTree( int key, Object data, BSTree left, BSTree right ) {
98
        this.key = key;
99
        this.data = data;
100
        this.left = left;
101
        this.right = right;
102
        height = 1 + Math.max(left.height,right.height);
103
    }
104
 
105
    //method to return the height of the tree
106
    public int getHeight() { return height; }
107
 
108
    //method to return the height of the subtree with the
109
    //given key
110
    public int getHeight( int key ) {
111
        if( this == NIL ) { return -1; }
112
        if( key == this.key ) { return getHeight(); }
113
        if( key < this.key ) { return left.getHeight(key); }
114
        return right.getHeight(key);
115
    }
116
 
117
    //method to return the left subtree
118
    public BSTree getLeft() { 
119
        if( this == NIL ) { return NIL; }
120
        return left;
121
    }
122
 
123
    //method to return the left subtree of the subtree with the
124
    //given key
125
    public BSTree getLeft( int key ) {
126
        if( this == NIL ) { return null; } //key not in tree
127
        if( key == this.key ) { return getLeft(); }
128
        if( key < this.key ) { return left.getLeft(key); }
129
        return right.getLeft(key);
130
    }
131
 
132
    //method to return the right subtree
133
    public BSTree getRight() {
134
        if( this == NIL ) { return NIL; }
135
        return right;
136
    }
137
 
138
    //method to return the right subtree of the subtree with the
139
    //given key
140
    public BSTree getRight( int key ) {
141
        if( this == NIL ) { return null; } //key not in tree
142
        if( key == this.key ) { return getRight(); }
143
        if( key < this.key ) { return left.getRight(key); }
144
        return right.getRight(key);
145
    }
146
 
147
    //method to return the key of the root
148
    public int getRoot() { return key; }
149
 
150
    //method to return the key of the root
151
    public int getKey() { return key; }
152
 
153
    //method to return the data of the root
154
    public Object getData() { return data; }
155
 
156
    //method to see if the tree contains a key
157
    public boolean contains( int x ) { 
158
        if( this == NIL ) { return false; }
159
        if( key == x ) { return true; }
160
 
161
        return left.contains(x) || right.contains(x);
162
    }
163
 
164
    //return the data associated with a given key
165
    public Object get( int key ) {
166
        if( this == NIL ) { return NIL; }
167
        if( key == this.key ) { return data; }
168
 
169
        if( key < this.key ) { return left.get(key); }
170
        return right.get(key);
171
    }
172
 
173
    //check if two trees are equals
174
    public boolean equals( Object object ) { 
175
        if( !(object instanceof BSTree) ) { return false; }
176
 
177
        BSTree temp = (BSTree)object; //make it typed
178
 
179
        boolean l=false, r=false;
180
 
181
        //check the left
182
        if( left == NIL && temp.left == NIL ) l = true;
183
        else l = left.equals(temp.left);
184
 
185
        //check the right
186
        if( right == NIL && temp.right == NIL ) r = true;
187
        else r = right.equals(temp.right);
188
 
189
        return (temp.key == key) && l && r;
190
    }
191
 
192
    //method to create a new tree from an array of keys,
193
    //and an array of data
194
    public BSTree( int[] keys, Object[] data ) { 
195
        //this(keys[0],data[0]); //create a new tree
196
 
197
        if( keys.length != data.length ) { throw new IllegalArgumentException(); }
198
 
199
        this.key = keys[0];
200
        this.data = data[0];
201
        left = right = NIL;
202
 
203
        //call add() for every element in the array
204
        for( int i=1; i < keys.length; i++ ) add(keys[i],data[i]);
205
    }
206
 
207
    //method to remove a key-data pair from the tree
208
    public boolean remove( int key ) {
209
        if( !contains(key) ) { return false; }
210
        removeHelper(this,key);
211
        if( contains(key) ) { return false; }
212
        return true;
213
    }
214
 
215
    //a helper method for remove, which performs the actual recursion
216
    private BSTree removeHelper( BSTree tree, int key ) {
217
        if( tree == NIL ) { return NIL; }
218
        else if( key < tree.key ) { tree.left = removeHelper(tree.left,key); }
219
        else if( key > tree.key ) { tree.right = removeHelper(tree.right,key); }
220
        else if( tree.left != NIL && tree.right != NIL ) { 
221
            tree = deleteMinimum(tree.right); 
222
        }
223
        else if( tree.left != NIL ) { tree = tree.left; }
224
        else { tree = tree.right; }
225
 
226
        return tree;
227
    }
228
 
229
    //method to remove the minimum element in a tree
230
    private BSTree deleteMinimum( BSTree tree ) {
231
        if( tree == NIL ) { return NIL; }
232
        if( tree.left == NIL && tree.right == NIL ) { return NIL; }
233
        if( tree.left == NIL ) { 
234
            return new BSTree(tree.right.key,tree.right.data,
235
                               tree.right.left,tree.right.right); 
236
        }
237
        return new BSTree(tree.key,tree.data,deleteMinimum(tree.left),tree.right);
238
    }
239
 
240
    //method to print a tree InOrder
241
    public static void printInOrder( BSTree tree ) {
242
        Queue queue = new Queue();
243
        queue.enqueue(tree);
244
 
245
        while( !queue.isEmpty() ) {
246
            BSTree temp = (BSTree)queue.dequeue();
247
            System.out.print(temp.getKey());
248
            if( temp.getLeft() != NIL ) { queue.enqueue(temp.getLeft()); }
249
            if( temp.getRight() != NIL ) { queue.enqueue(temp.getRight()); }
250
        }
251
    }
252
 
253
    //method to print a tree in PreOrder
254
    public static void printPreOrder( BSTree tree ) {
255
        if( tree == NIL ) return;
256
 
257
        System.out.print(tree.getKey());
258
        BSTree.printPreOrder( tree.getLeft() );
259
        BSTree.printPreOrder( tree.getRight() );
260
    }
261
 
262
} //end BSTree class
263