Subversion Repositories programming

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
41 irasnyd 1
// Written by Ira Snyder
2
// Due Date: 11-24-2004
3
// Project #4
4
 
5
import java.io.*;
6
import java.util.*;
7
 
8
class AVLTree {
9
    private int key, height;
43 irasnyd 10
    private Object data;
41 irasnyd 11
    private AVLTree left, right;
12
 
13
    public static final AVLTree NIL = new AVLTree();
14
 
43 irasnyd 15
    public AVLTree( int key, Object data ) {
41 irasnyd 16
        this.key = key;
43 irasnyd 17
        this.data = data;
41 irasnyd 18
        left = right = NIL;
19
    }
20
 
43 irasnyd 21
    public boolean add( int key, Object data ) {
41 irasnyd 22
        int oldSize = size();
43 irasnyd 23
        grow(key,data);
41 irasnyd 24
        return size() > oldSize;
25
    }
26
 
43 irasnyd 27
    //provide name mapping
28
    public boolean insert( int key, Object data ) {
29
        return add(key,data);
30
    }
41 irasnyd 31
 
43 irasnyd 32
    public AVLTree grow( int key, Object data ) {
33
        if( this == NIL ) return new AVLTree(key,data);
34
        if( key == this.key ) { this.data = data; return this; } //prevent key dupes, update data
35
        if( key < this.key ) left = left.grow(key,data);
36
        else right = right.grow(key,data);
37
 
41 irasnyd 38
        rebalance();
39
 
40
        height = 1 + Math.max(left.height,right.height);
41
        return this;
42
    }
43
 
44
    public int size() {
45
        if( this == NIL ) return 0;
46
        return 1 + left.size() + right.size();
47
    }
48
 
42 irasnyd 49
    //I like the BinaryTree toString better than the author's toString()
50
    //so I used it here instead. I left the author's code for completeness.
51
    /*
41 irasnyd 52
    public String toString() {
53
        if( this == NIL ) return "";
54
        return left + " " + key + " " + right;
55
    }
42 irasnyd 56
    */
57
 
58
    public String toString() {
59
 
60
        if( this == NIL ) return "()";
61
 
62
        String sLeft = sLeft = left.toString();
63
        String sRight = sRight = right.toString();
64
        String answer = new String();
65
 
66
        //assemble the string to return
67
        answer = "(";
68
        if( !sLeft.equals("()") ) { answer += sLeft + ","; }
69
        answer += key;
70
        if( !sRight.equals("()") ) { answer += "," + sRight; }
71
        answer += ")";
72
 
73
        //return the assembled string
74
        return answer;
75
    }
76
 
41 irasnyd 77
    private AVLTree() { //construct the empty tree
78
        left = right = this;
79
        height = -1;
80
    }
81
 
43 irasnyd 82
    private AVLTree( int key, Object data, AVLTree left, AVLTree right ) {
41 irasnyd 83
        this.key = key;
43 irasnyd 84
        this.data = data;
41 irasnyd 85
        this.left = left;
86
        this.right = right;
87
        height = 1 + Math.max(left.height,right.height);
88
    }
89
 
90
    private void rebalance() {
91
        if( right.height > (left.height + 1) ) {
92
            if( right.left.height > right.right.height ) right.rotateRight();
93
            rotateLeft();
94
        }
95
        else if( left.height > (right.height + 1) ) {
96
            if( left.right.height > left.left.height ) left.rotateLeft();
97
            rotateRight();
98
        }
99
    }
100
 
101
    private void rotateLeft() {
43 irasnyd 102
        left = new AVLTree(key,data,left,right.left);
41 irasnyd 103
        key = right.key;
43 irasnyd 104
        data = right.data;
41 irasnyd 105
        right = right.right;
106
    }
107
 
108
    private void rotateRight() {
43 irasnyd 109
        right = new AVLTree(key,data,left.right,right);
41 irasnyd 110
        key = left.key;
43 irasnyd 111
        data = left.data;
41 irasnyd 112
        left = left.left;
113
    }
114
 
42 irasnyd 115
    // new functions from Prog. Probs PG 411
116
    public int getHeight() { return height; }
43 irasnyd 117
 
118
    public int getHeight( int key ) {
119
        if( this == NIL ) { return -1; }
120
        if( key == this.key ) { return getHeight(); }
121
        if( key < this.key ) { return left.getHeight(key); }
122
        return right.getHeight(key);
123
    }
42 irasnyd 124
 
125
    public AVLTree getLeft() { 
126
        if( this == NIL ) { return NIL; }
127
        return left;
128
    }
43 irasnyd 129
 
130
    public AVLTree getLeft( int key ) {
131
        if( this == NIL ) { return null; } //key not in tree
132
        if( key == this.key ) { return getLeft(); }
133
        if( key < this.key ) { return left.getLeft(key); }
134
        return right.getLeft(key);
135
    }
42 irasnyd 136
 
43 irasnyd 137
    public AVLTree getRight() {
42 irasnyd 138
        if( this == NIL ) { return NIL; }
139
        return right;
140
    }
43 irasnyd 141
 
142
    public AVLTree getRight( int key ) {
143
        if( this == NIL ) { return null; } //key not in tree
144
        if( key == this.key ) { return getRight(); }
145
        if( key < this.key ) { return left.getRight(key); }
146
        return right.getRight(key);
147
    }
42 irasnyd 148
 
43 irasnyd 149
    public int getRoot() { return key; }
150
    public int getKey() { return key; }
151
    public Object getData() { return data; }
42 irasnyd 152
 
153
    public boolean contains( int x ) { 
154
        if( this == NIL ) { return false; }
155
        if( key == x ) { return true; }
156
 
157
        return left.contains(x) || right.contains(x);
158
    }
159
 
43 irasnyd 160
    // I am guessing this returns the tree with x == key as the root,
161
    // since the book was not very specific
162
    public Object get( int key ) {
42 irasnyd 163
        if( this == NIL ) { return NIL; }
43 irasnyd 164
        if( key == this.key ) { return data; }
42 irasnyd 165
 
43 irasnyd 166
        if( key < this.key ) { return left.get(key); }
167
        return right.get(key);
42 irasnyd 168
    }
169
 
170
    public boolean equals( Object object ) { 
171
        if( !(object instanceof AVLTree) ) { return false; }
172
 
173
        AVLTree temp = (AVLTree)object; //make it typed
174
 
175
        boolean l=false, r=false;
176
 
177
        //check the left
178
        if( left == NIL && temp.left == NIL ) l = true;
179
        else l = left.equals(temp.left);
180
 
181
        //check the right
182
        if( right == NIL && temp.right == NIL ) r = true;
183
        else r = right.equals(temp.right);
184
 
185
        return (temp.key == key) && l && r;
186
    }
187
 
43 irasnyd 188
    public AVLTree( int[] keys, Object[] data ) { 
189
        this(keys[0],data[0]); //create a new tree
42 irasnyd 190
 
191
        //call add() for every element in the array
43 irasnyd 192
        for( int i=1; i < keys.length; i++ ) add(keys[i],data[i]);
42 irasnyd 193
    }
45 irasnyd 194
 
195
 
196
    public boolean remove( int key ) {
197
        if( !contains(key) ) { return false; }
198
        removeHelper(this,key);
199
        if( contains(key) ) { return false; }
200
        return true;
201
    }
202
 
203
    private AVLTree removeHelper( AVLTree tree, int key ) {
204
        if( tree == NIL ) { return NIL; }
205
        else if( key < tree.key ) { tree.left = removeHelper(tree.left,key); }
206
        else if( key > tree.key ) { tree.right = removeHelper(tree.right,key); }
207
        else if( tree.left != NIL && tree.right != NIL ) { tree = deleteMinimum(tree.right); }
208
        else if( tree.left != NIL ) { tree = tree.left; }
209
        else { tree = tree.right; }
210
        tree.rebalance();
211
        return tree;
212
    }
213
 
214
 
42 irasnyd 215
    /*
216
    public boolean remove( int key ) { 
217
        if( this == NIL ) { return false; }
218
        if( key < this.key ) { return left.remove(key); }
219
        if( key > this.key ) { return right.remove(key); }
220
 
43 irasnyd 221
        if( left == NIL && right == NIL ) { 
222
            //same as "this = NIL;"
223
            setThis(NIL);
224
 
225
            return true; 
226
        }
42 irasnyd 227
        if( left == NIL ) { 
43 irasnyd 228
            //same as "this = new AVLTree(right.key,right.left,right.right);"
229
            AVLTree temp = new AVLTree(right.key,right.data,right.left,right.right);
230
            setThis(temp);
231
 
42 irasnyd 232
            return true;
233
        }
234
        if( right == NIL ) {
43 irasnyd 235
            //same as "this = new AVLTree(left.key,left.left,left.right);"
236
            AVLTree temp = new AVLTree(left.key,left.data,left.left,left.right);
237
            setThis(temp);
238
 
42 irasnyd 239
            return true;
240
        }
43 irasnyd 241
        //same as "this = new AVLTree(deleteMinimum(right));
45 irasnyd 242
        AVLTree temp = deleteMinimum(right);
43 irasnyd 243
        setThis(temp);
244
 
42 irasnyd 245
        rebalance(); //fix the balance
246
        return true;
45 irasnyd 247
    } 
248
    */
44 irasnyd 249
    public void ira_dm() {
250
        System.out.println( this );
45 irasnyd 251
        System.out.println( deleteMinimum(this) );
42 irasnyd 252
    }
253
 
45 irasnyd 254
    private AVLTree deleteMinimum( AVLTree tree ) {
44 irasnyd 255
        if( tree == NIL ) { return NIL; }
256
        if( tree.left == NIL && tree.right == NIL ) { return NIL; }
257
        if( tree.left == NIL ) { 
258
            return new AVLTree(tree.right.key,tree.right.data,
259
                               tree.right.left,tree.right.right); 
42 irasnyd 260
        }
44 irasnyd 261
        return new AVLTree(tree.key,tree.data,deleteMinimum(tree.left),tree.right);
42 irasnyd 262
    }
43 irasnyd 263
 
44 irasnyd 264
 
43 irasnyd 265
    private void setThis( AVLTree that ) {
266
        this.key = that.key;
267
        this.data = that.data;
268
        this.height = that.height;
269
        this.left = that.left;
270
        this.right = that.right;
271
    }
42 irasnyd 272
 
43 irasnyd 273
    public static void printInOrder( AVLTree tree ) {
274
        Queue queue = new Queue();
275
        queue.enqueue(tree);
276
 
277
        while( !queue.isEmpty() ) {
278
            AVLTree temp = (AVLTree)queue.dequeue();
279
            System.out.print(temp.getKey());
280
            if( temp.getLeft() != NIL ) { queue.enqueue(temp.getLeft()); }
281
            if( temp.getRight() != NIL ) { queue.enqueue(temp.getRight()); }
282
        }
283
    }
284
 
285
    public static void printPreOrder( AVLTree tree ) {
286
        if( tree == NIL ) return;
287
 
288
        System.out.print(tree.getKey());
289
        AVLTree.printPreOrder( tree.getLeft() );
290
        AVLTree.printPreOrder( tree.getRight() );
291
    }
292
 
41 irasnyd 293
} //end AVLTree class
294