add insert and find functionality

This commit is contained in:
Joel Beckmeyer 2017-12-09 17:38:25 -05:00
parent 0748930c0f
commit 1ef89e8e9e
1 changed files with 182 additions and 44 deletions

View File

@ -11,6 +11,8 @@ package termproject;
public class TwoFourTree public class TwoFourTree
implements Dictionary { implements Dictionary {
private static final int MAX_ITEMS = 3;
private Comparator treeComp; private Comparator treeComp;
private int size = 0; private int size = 0;
private TFNode treeRoot = null; private TFNode treeRoot = null;
@ -27,6 +29,112 @@ public class TwoFourTree
treeRoot = root; treeRoot = root;
} }
private TFNode search(Object key) {
TFNode current = treeRoot;
TFNode parent = null;
if(treeRoot == null) {
throw new TwoFourTreeException("root was null");
}
// loop until we have reached the child of an external node, or until
// we find the key
while(current != null) {
int index = FFGTE(current, key);
if(treeComp.isEqual(current.getItem(index).key(), key)) {
break;
}
parent = current;
current = current.getChild(index);
}
// if key was not found, we know we are at an external node, so we must
// return that node rather than its null "child"
if(current == null) {
return parent;
}else {
return current;
}
}
private int FFGTE(TFNode node, Object key) {
int i;
for(i = 0; i < node.getNumItems(); ++i) {
if(treeComp.isGreaterThanOrEqualTo(node.getItem(i).key(), key)) {
break;
}
}
return i;
}
private int WCIT(TFNode node) {
TFNode parent = node.getParent();
int i;
for(i = 0; i < parent.getNumItems() + 1; ++i) {
if(parent.getChild(i) == node) {
break;
}
}
return i;
}
private TFNode getInOrderSuccessor(TFNode current, Object key) {
if(current == null) {
return null;
}
int index = FFGTE(current, key);
TFNode next = getInOrderSuccessor(current.getChild(index), key);
if(next == null) {
return current;
}else {
return next;
}
}
private void fixOverflow(TFNode node) {
if(node.getNumItems() <= MAX_ITEMS) {
return;
}
TFNode left = node.getChild(3);
TFNode right = node.getChild(4);
TFNode parent = node.getParent();
// special case when root overflows (we must increase height of tree)
if(parent == null) {
parent = new TFNode();
parent.setChild(0, node);
node.setParent(parent);
treeRoot = parent;
}
// removes offending data from current node
int index = WCIT(node);
Item toSibling = node.deleteItem(3);
Item toParent = node.deleteItem(2);
node.setChild(3, null);
node.setChild(4, null);
// creates and populates new sibling node
TFNode sibling = new TFNode();
sibling.addItem(0, toSibling);
sibling.setParent(parent);
sibling.setChild(0, left);
sibling.setChild(1, right);
if(left != null) {
left.setParent(sibling);
right.setParent(sibling);
}
// inserts data into parent node and hooks up sibling
parent.insertItem(index, toParent);
parent.setChild(index + 1, sibling);
// recursively call on parent
fixOverflow(parent);
}
public int size() { public int size() {
return size; return size;
} }
@ -41,7 +149,18 @@ public class TwoFourTree
* @return object corresponding to key; null if not found * @return object corresponding to key; null if not found
*/ */
public Object findElement(Object key) { public Object findElement(Object key) {
return null; // first get the node which might contain the given key
TFNode target = search(key);
// find the key in this node
for(int i = 0; i < target.getNumItems(); ++i) {
if(treeComp.isEqual(target.getItem(i).key(), key)) {
return target.getItem(i).element();
}
}
// if key was not in node, return null
return null;
} }
/** /**
@ -50,6 +169,16 @@ public class TwoFourTree
* @param element to be inserted * @param element to be inserted
*/ */
public void insertElement(Object key, Object element) { public void insertElement(Object key, Object element) {
if(treeRoot == null) {
treeRoot = new TFNode();
}
TFNode node = getInOrderSuccessor(treeRoot, key);
int index = FFGTE(node, key);
node.insertItem(index, new Item(key, element));
if(node.getNumItems() > MAX_ITEMS) {
fixOverflow(node);
}
} }
/** /**
@ -60,79 +189,86 @@ public class TwoFourTree
* @exception ElementNotFoundException if the key is not in dictionary * @exception ElementNotFoundException if the key is not in dictionary
*/ */
public Object removeElement(Object key) throws ElementNotFoundException { public Object removeElement(Object key) throws ElementNotFoundException {
return null; TFNode node = search(key);
int index = FFGTE(node, key);
if(node.getItem(index).key() != key) {
throw new ElementNotFoundException("element is not in tree");
}
} }
public static void main(String[] args) { public static void main(String[] args) {
Comparator myComp = new IntegerComparator(); Comparator myComp = new IntegerComparator();
TwoFourTree myTree = new TwoFourTree(myComp); TwoFourTree myTree = new TwoFourTree(myComp);
Integer myInt1 = new Integer(47); myTree.insertElement(47, 47);
myTree.insertElement(myInt1, myInt1); myTree.printAllElements();
Integer myInt2 = new Integer(83);
myTree.insertElement(myInt2, myInt2);
Integer myInt3 = new Integer(22);
myTree.insertElement(myInt3, myInt3);
Integer myInt4 = new Integer(16); myTree.insertElement(83, 83);
myTree.insertElement(myInt4, myInt4); myTree.printAllElements();
Integer myInt5 = new Integer(49); myTree.insertElement(22, 22);
myTree.insertElement(myInt5, myInt5); myTree.printAllElements();
Integer myInt6 = new Integer(100); myTree.insertElement(16, 16);
myTree.insertElement(myInt6, myInt6); myTree.printAllElements();
Integer myInt7 = new Integer(38); myTree.insertElement(49, 49);
myTree.insertElement(myInt7, myInt7); myTree.printAllElements();
Integer myInt8 = new Integer(3); myTree.insertElement(100, 100);
myTree.insertElement(myInt8, myInt8); myTree.printAllElements();
Integer myInt9 = new Integer(53); myTree.insertElement(38, 38);
myTree.insertElement(myInt9, myInt9); myTree.printAllElements();
Integer myInt10 = new Integer(66); myTree.insertElement(3, 3);
myTree.insertElement(myInt10, myInt10); myTree.printAllElements();
Integer myInt11 = new Integer(19); myTree.insertElement(53, 53);
myTree.insertElement(myInt11, myInt11); myTree.printAllElements();
Integer myInt12 = new Integer(23); myTree.insertElement(66, 66);
myTree.insertElement(myInt12, myInt12); myTree.printAllElements();
Integer myInt13 = new Integer(24); myTree.insertElement(19, 19);
myTree.insertElement(myInt13, myInt13); myTree.printAllElements();
Integer myInt14 = new Integer(88); myTree.insertElement(23, 23);
myTree.insertElement(myInt14, myInt14); myTree.printAllElements();
Integer myInt15 = new Integer(1); myTree.insertElement(24, 24);
myTree.insertElement(myInt15, myInt15); myTree.printAllElements();
Integer myInt16 = new Integer(97); myTree.insertElement(88, 88);
myTree.insertElement(myInt16, myInt16); myTree.printAllElements();
Integer myInt17 = new Integer(94); myTree.insertElement(1, 1);
myTree.insertElement(myInt17, myInt17); myTree.printAllElements();
Integer myInt18 = new Integer(35); myTree.insertElement(97, 97);
myTree.insertElement(myInt18, myInt18); myTree.printAllElements();
Integer myInt19 = new Integer(51); myTree.insertElement(94, 94);
myTree.insertElement(myInt19, myInt19); myTree.printAllElements();
myTree.insertElement(35, 35);
myTree.printAllElements();
myTree.insertElement(51, 51);
myTree.printAllElements();
myTree.printAllElements();
System.out.println("done"); System.out.println("done");
myTree = new TwoFourTree(myComp); /*myTree = new TwoFourTree(myComp);
final int TEST_SIZE = 10000; final int TEST_SIZE = 10000;
for (int i = 0; i < TEST_SIZE; i++) { for (int i = 0; i < TEST_SIZE; i++) {
myTree.insertElement(new Integer(i), new Integer(i)); myTree.insertElement(new Integer(i), new Integer(i));
// myTree.printAllElements(); myTree.printAllElements();
// myTree.checkTree(); myTree.checkTree();
} }
System.out.println("removing"); System.out.println("removing");
for (int i = 0; i < TEST_SIZE; i++) { for (int i = 0; i < TEST_SIZE; i++) {
@ -144,6 +280,7 @@ public class TwoFourTree
myTree.printAllElements(); myTree.printAllElements();
} }
} }
*/
System.out.println("done"); System.out.println("done");
} }
@ -155,6 +292,7 @@ public class TwoFourTree
else { else {
printTree(root(), indent); printTree(root(), indent);
} }
System.out.println("");
} }
public void printTree(TFNode start, int indent) { public void printTree(TFNode start, int indent) {