Subversion Repositories Code-Repo

Rev

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

Rev Author Line No. Line
96 Kevin 1
import java.util.ArrayList;
2
 
3
// Generic BST implementation
4
public class BSTree<K extends Comparable<? super K>, E> implements Dictionary<K, E> {
5
	private BSTreeNode<K,E> root;	// Root of the BST
6
	NodeSerializer serializer;
7
 
8
	// Constructor
9
	public BSTree(MemManager mem) {
10
		serializer = new NodeSerializer(mem);
11
		this.root = null;
12
	}
13
 
14
	// Inserts a node into the BST
15
	public void insert(K key, E element) {
16
		// Set the BST root as the returned node
17
		this.root = insertRecursive(root, key, element);
18
	}
19
 
20
	// Removes a node from the BST given the key
21
	public void remove(K key) {
22
		// Adds invalid coordinates if none are specified
23
		this.remove(key, -1, -1);
24
	}
25
 
26
	public void remove(K key, int x, int y) {
27
		// Check if node exists
28
		E temp = findRecursive(root, key);
29
		if (temp != null) {
30
			// Remove the node
31
			this.root = removeRecursive(root, key, x, y);
32
		}
33
	}
34
 
35
	// Returns a node from the BST given the key
36
	public E find(K key) {
37
		return findRecursive(root, key);
38
	}
39
 
40
	// Returns a list of all nodes with the given key
41
	public ArrayList<E> findAll(K key) {
42
		ArrayList<E> elementList = new ArrayList<E>();
43
		findAllRecursive(root, key, elementList);
44
		return elementList;
45
	}
46
 
47
	// Removes all nodes from the BST
48
	public void clear() {
49
		this.root = null;
50
	}
51
 
52
	// Recursively inserts a node into the BST
53
	private BSTreeNode<K,E> insertRecursive(BSTreeNode<K,E> root, K key, E element) {
54
		if (root == null)
55
			// If there are no nodes in the BST, create and return a new node
56
			return new BSTreeNode<K,E>(key, element);
57
		if (root.getKey().compareTo(key) > 0)
58
			// If passed key is smaller, insert into left child
59
			root.setLeft(insertRecursive(root.getLeft(), key, element));
60
		else
61
			// If passed key is greater, insert into right child
62
			root.setRight(insertRecursive(root.getRight(), key, element));
63
		return root;
64
	}
65
 
66
	// Recursively searches minimal nodes for matches to the given key
67
	private E findRecursive(BSTreeNode<K,E> root, K key) {
68
		if (root == null)
69
			return null;
70
 
71
		if (root.getKey().compareTo(key) > 0)
72
			// If passed key is smaller, search the left child
73
			return findRecursive(root.getLeft(), key);
74
		else if (root.getKey().compareTo(key) == 0)
75
			// If key is found, return with the found element
76
			return root.getElement();
77
		else
78
			// If key is not found, search the right child
79
			return findRecursive(root.getRight(), key);
80
	}
81
 
82
	// Recursively searches all nodes for matches to the given key
83
	private void findAllRecursive(BSTreeNode<K,E> root, K key, ArrayList<E> elementList) {
84
		if (root == null)
85
			return;
86
 
87
		// If key matches, save to list
88
		if (root.getKey().compareTo(key) == 0)
89
			elementList.add(root.getElement());
90
 
91
		// Recursively call search on all possible nodes
92
		if (root.getKey().compareTo(key) > 0)
93
			findAllRecursive(root.getLeft(), key, elementList);
94
		else
95
			findAllRecursive(root.getRight(), key, elementList);
96
	}
97
 
98
	// Recursively removes a node from the BST given a key
99
	private BSTreeNode<K,E> removeRecursive(BSTreeNode<K,E> root, K key, int x, int y) {
100
		if (root == null)
101
			return null;
102
		// Find the node to remove
103
		if (root.getKey().compareTo(key) > 0)
104
			root.setLeft(removeRecursive(root.getLeft(), key, x, y));
105
		else if (root.getKey().compareTo(key) < 0)
106
			root.setRight(removeRecursive(root.getRight(), key, x, y));
107
		// Node's key matches
108
		else {
109
			// If we want to narrow it down by coordinates as well
110
			if (x >= 0 && y >= 0) {
111
				CityRecord record = serializer.handleToCityRecord((Handle)root.getElement());
112
				// If coordinates do not match, keep searching from the right child
113
//				if (((Record)root.getElement()).getX() != x || ((Record)root.getElement()).getY() != y) {
114
				if (record.getX() != x || record.getY() != y) {
115
					root.setRight(removeRecursive(root.getRight(), key, x, y));
116
				} else {
117
					// If one of the leaves is null, just return the other leaf
118
					if (root.getLeft() == null) {
119
						serializer.removeCityRecordHandle((Handle)root.getElement());
120
						return root.getRight();
121
					} else if (root.getRight() == null) {
122
						serializer.removeCityRecordHandle((Handle)root.getElement());
123
						return root.getLeft();
124
					} else {
125
						serializer.removeCityRecordHandle((Handle)root.getElement());
126
						// Otherwise create a new node with the smallest value on the right leaf
127
						BSTreeNode<K,E> temp = getMin(root.getRight());
128
						root.setElement(temp.getElement());
129
						root.setKey(temp.getKey());
130
						root.setRight(deleteMin(root.getRight()));
131
					}
132
				}
133
			// Otherwise just remove the node
134
			} else {
135
				// If one of the leaves is null, just return the other leaf
136
				if (root.getLeft() == null) {
137
					serializer.removeCityRecordHandle((Handle)root.getElement());
138
					return root.getRight();
139
				} else if (root.getRight() == null) {
140
					serializer.removeCityRecordHandle((Handle)root.getElement());
141
					return root.getLeft();
142
				} else {
143
					serializer.removeCityRecordHandle((Handle)root.getElement());
144
					// Otherwise create a new node with the smallest value on the right leaf
145
					BSTreeNode<K,E> temp = getMin(root.getRight());
146
					root.setElement(temp.getElement());
147
					root.setKey(temp.getKey());
148
					root.setRight(deleteMin(root.getRight()));
149
				}
150
			}
151
		}
152
		return root;
153
	}
154
 
155
	// Recursively returns the minimum key node
156
	private BSTreeNode<K,E> getMin(BSTreeNode<K,E> root) {
157
		if (root.getLeft() == null)
158
			return root;
159
		else
160
			return getMin(root.getLeft());
161
	}
162
 
163
	// Recursively deletes the minimum key node
164
	private BSTreeNode<K,E> deleteMin(BSTreeNode<K,E> root) {
165
		if (root.getLeft() == null)
166
			return root.getRight();
167
		else {
168
			root.setLeft(deleteMin(root.getLeft()));
169
			return root;
170
		}
171
	}
172
}