made several methods recursive, made independent of AbstractBinaryTree,
made the thing work!
This commit is contained in:
parent
dd9c437269
commit
b34a4b51aa
|
@ -1,76 +0,0 @@
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
/*
|
|
||||||
* * Data Structures & Algorithms 6th Edition
|
|
||||||
* Goodrich, Tamassia, Goldwasser
|
|
||||||
* Code Fragments 8.7, 8.26, 8.22
|
|
||||||
*\
|
|
||||||
|
|
||||||
/**
|
|
||||||
* an abstract base class providing some functionality of the binarytree interface
|
|
||||||
* @author Gabriel Venberg
|
|
||||||
*/
|
|
||||||
public abstract class AbstractBinaryTree<E> extends AbstractTree<E> implements BinaryTree<E> {
|
|
||||||
public Position<E> sibling(Position<E> p){
|
|
||||||
Position<E> parent = parent(p);
|
|
||||||
//p is root.
|
|
||||||
if (parent == null){return null;}
|
|
||||||
//p is left child, right child might be null.
|
|
||||||
if (p==left(parent)){return right(parent);}
|
|
||||||
//p is right child, left child might be null.
|
|
||||||
else {return left(parent);}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**returns the number of children of Position p*/
|
|
||||||
public int numChildren(Position<E> p){
|
|
||||||
int count=0;
|
|
||||||
if (left(p)!=null){count++;}
|
|
||||||
if(right(p)!=null){count++;}
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**returns an iterable collection of Positions representing p's children.*/
|
|
||||||
public Iterable<Position<E>> children(Position<E> p){
|
|
||||||
//max capacity of 2
|
|
||||||
List <Position<E>> snapshot=new ArrayList<>(2);
|
|
||||||
//needed to modify this, as the arraylist we made in class needed an index
|
|
||||||
if(left(p)!=null){snapshot.add(left(p));}
|
|
||||||
if(right(p)!=null){snapshot.add(right(p));}
|
|
||||||
// and our arraylist
|
|
||||||
return snapshot;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**adds positions of the subtree rooted at Position p to the given snapshot*/
|
|
||||||
private void inorderSubtree(Position<E> p, List<Position<E>> snapshot){
|
|
||||||
if(left(p)!=null){inorderSubtree(left(p), snapshot);}
|
|
||||||
snapshot.add(p);
|
|
||||||
if(right(p)!=null){inorderSubtree(right(p), snapshot);}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**returns an iterable collection of the positions of the tree, reported in inorder.*/
|
|
||||||
public Iterable<Position<E>> inorder(){
|
|
||||||
List<Position<E>> snapshot=new ArrayList<>();
|
|
||||||
//fill snapshot recursively
|
|
||||||
if(!isEmpty()){inorderSubtree(root(), snapshot);}
|
|
||||||
return snapshot;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**Overrides positions to make inorder the default order for binary trees*/
|
|
||||||
public Iterable<Position<E>> positions(){
|
|
||||||
return inorder();
|
|
||||||
}
|
|
||||||
|
|
||||||
//nested ElementIterator class
|
|
||||||
/**this class adapts the iteration produced by positions() to returns elements*/
|
|
||||||
private class ElementIterator implements Iterator<E>{
|
|
||||||
Iterator<Position<E>> posIterator=positions().iterator();
|
|
||||||
public boolean hasNext(){return posIterator.hasNext();}
|
|
||||||
//return element
|
|
||||||
public E next(){return posIterator.next().getElement();}
|
|
||||||
public void remove(){posIterator.remove();}
|
|
||||||
}//end of nested ElementIterator class
|
|
||||||
|
|
||||||
/**returns an iterator if the elements stored in the tree*/
|
|
||||||
public Iterator<E> iterator(){return new ElementIterator();}
|
|
||||||
}
|
|
|
@ -1,104 +0,0 @@
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* * Data Structures & Algorithms 6th Edition
|
|
||||||
* Goodrich, Tamassia, Goldwasser
|
|
||||||
* Code Fragments 8.2-8.5, 8.19-21
|
|
||||||
*\
|
|
||||||
/*
|
|
||||||
* an abstract base class providing some functionality of the tree interface.
|
|
||||||
* @author Gabriel Venberg
|
|
||||||
*/
|
|
||||||
public abstract class AbstractTree<E> implements Tree<E> {
|
|
||||||
public boolean isInternal(Position<E> p) {return numChildren(p)>0;}
|
|
||||||
public boolean isExternal(Position<E> p){return numChildren(p)==0;}
|
|
||||||
public boolean isRoot(Position<E> p){return p == root();}
|
|
||||||
public boolean isEmpty(){return size()==0;}
|
|
||||||
|
|
||||||
/**returns the number of levels sperating position p from the root.*/
|
|
||||||
public int depth(Position<E> p){
|
|
||||||
if (isRoot(p)){return 0;}
|
|
||||||
else{return 1+depth(parent(p));}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**returns the hight of the tree.*/
|
|
||||||
private int hightBad(){ //works, but quadratic worst case time.
|
|
||||||
int h=0;
|
|
||||||
for(Position<E> p : positions()){
|
|
||||||
//only consider leaf positions.
|
|
||||||
if(isExternal(p)){h=Math.max(h, depth(p));}
|
|
||||||
}
|
|
||||||
return h;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**returns the hight of the subtree rooted at position p. should be O(n) time.*/
|
|
||||||
public int hight(Position<E> p){
|
|
||||||
//base case if p is external
|
|
||||||
int h=0;
|
|
||||||
for (Position<E> c : children(p)){
|
|
||||||
h=Math.max(h,1+hight(c));
|
|
||||||
}
|
|
||||||
return h;
|
|
||||||
}
|
|
||||||
|
|
||||||
//iterators
|
|
||||||
/**adds positions of the subtree rooted at position p to the given snapshot (for use in traversal)*/
|
|
||||||
private void preorderSubtree(Position<E> p, List<Position<E>> snapshot){
|
|
||||||
//for preorder, add position p before exploring subtrees.
|
|
||||||
snapshot.add(p);
|
|
||||||
for(Position<E> c:children(p)){
|
|
||||||
preorderSubtree(c, snapshot);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**returns an iterable collection of positions in the tree, reported in preorder*/
|
|
||||||
public Iterable<Position<E>> preorder(){
|
|
||||||
List<Position<E>> snapshot=new ArrayList<>();
|
|
||||||
//fill the snapshot recursively
|
|
||||||
if(!isEmpty()){
|
|
||||||
preorderSubtree(root(), snapshot);
|
|
||||||
}
|
|
||||||
return snapshot;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**adds positions of the subtree rooted at position p to the given snapshot (for use in traversal)*/
|
|
||||||
private void postorderSubtree(Position<E> p, List<Position<E>> snapshot){
|
|
||||||
//for postorder, add position p before exploring subtrees.
|
|
||||||
for(Position<E> c:children(p)){
|
|
||||||
postorderSubtree(c, snapshot);
|
|
||||||
}
|
|
||||||
snapshot.add(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**returns an iterable collection of positions in the tree, reported in postorder*/
|
|
||||||
public Iterable<Position<E>> postorder(){
|
|
||||||
List<Position<E>> snapshot=new ArrayList<>();
|
|
||||||
//fill the snapshot recursively
|
|
||||||
if(!isEmpty()){
|
|
||||||
postorderSubtree(root(), snapshot);
|
|
||||||
}
|
|
||||||
return snapshot;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**returns an iterable collection of positions in the tree in breadth first traversal*/
|
|
||||||
public Iterable<Position<E>> breadthFirst(){
|
|
||||||
List<Position<E>> snapshot=new ArrayList<>();
|
|
||||||
if(!isEmpty()){
|
|
||||||
Queue<Position<E>> fringe=new LinkedQueue<>();
|
|
||||||
fringe.enqueue(root());
|
|
||||||
while(!fringe.isEmpty()){
|
|
||||||
Position<E> p=fringe.dequeue();
|
|
||||||
snapshot.add(p);
|
|
||||||
for(Position<E> c:children(p)){
|
|
||||||
fringe.enqueue(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return snapshot;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**default iterator*/
|
|
||||||
public Iterable<Position<E>> positions(){return preorder();}
|
|
||||||
}
|
|
55
Lab110-VenbergGE/src/ArrayStack.java
Normal file
55
Lab110-VenbergGE/src/ArrayStack.java
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* Data Structures & Algorithms 6th Edition
|
||||||
|
* Goodrich, Tamassia, Goldwasser
|
||||||
|
* Code Fragment 6.2
|
||||||
|
*
|
||||||
|
* An implementation of an ArrayStack class
|
||||||
|
* */
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Gabriel Venberg
|
||||||
|
*/
|
||||||
|
public class ArrayStack<E> implements Stack<E> {
|
||||||
|
public static final int CAPACITY = 1000;//default capacity
|
||||||
|
private E[] data; //generic array used for storage.
|
||||||
|
private int t=-1; //index of the top element in the stack
|
||||||
|
|
||||||
|
|
||||||
|
//im swiching the authors comments to javadoc style, for ease of use.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constructs stack with default capacity
|
||||||
|
*/
|
||||||
|
public ArrayStack(){this(CAPACITY);}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constructs stack with given capacity
|
||||||
|
* @param capacity capacity to construct the stack with.
|
||||||
|
*/
|
||||||
|
public ArrayStack(int capacity){
|
||||||
|
data = (E[]) new Object[capacity];
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size(){return (t+1);}
|
||||||
|
|
||||||
|
public boolean isEmpty(){return(t==-1);}
|
||||||
|
|
||||||
|
public void push(E e) throws IllegalStateException{
|
||||||
|
if(size()==data.length){throw new IllegalStateException("Stack is full");}
|
||||||
|
data[++t]=e; //increment t before storing a new item.
|
||||||
|
}
|
||||||
|
|
||||||
|
public E top(){
|
||||||
|
if(isEmpty()){return null;}
|
||||||
|
return data[t];
|
||||||
|
}
|
||||||
|
|
||||||
|
public E pop(){
|
||||||
|
if(isEmpty()){return null;}
|
||||||
|
E answer = data[t];
|
||||||
|
data[t] = null; //dereference to help with garbage collection.
|
||||||
|
t--;
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,11 +1,15 @@
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Gabriel Venberg
|
* @author Gabriel Venberg
|
||||||
*/
|
*/
|
||||||
public class BinarySearchTree extends AbstractBinaryTree<Integer> {
|
public class BinarySearchTree {
|
||||||
|
|
||||||
//Represent a node of binary tree
|
//Represent a node of binary tree
|
||||||
private static class Node implements Position<Integer> {
|
private static class Node implements Position<Integer> {
|
||||||
|
|
||||||
private int data;
|
private int data;
|
||||||
private Node left;
|
private Node left;
|
||||||
private Node right;
|
private Node right;
|
||||||
|
@ -19,15 +23,37 @@ public class BinarySearchTree extends AbstractBinaryTree<Integer> {
|
||||||
this.parent = null;
|
this.parent = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getElement(){return data;}
|
public Integer getElement() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
public Node getLeft(){return left;}
|
public Node getLeft() {
|
||||||
public Node getRight(){return right;}
|
return left;
|
||||||
public Node getParent(){return parent;}
|
}
|
||||||
public void setData(int newData){data=newData;}
|
|
||||||
public void setLeft(Node newLeft){left=newLeft;}
|
public Node getRight() {
|
||||||
public void setRight(Node newRight){right=newRight;}
|
return right;
|
||||||
public void setParent(Node newParent){parent=newParent;}
|
}
|
||||||
|
|
||||||
|
public Node getParent() {
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData(int newData) {
|
||||||
|
data = newData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLeft(Node newLeft) {
|
||||||
|
left = newLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRight(Node newRight) {
|
||||||
|
right = newRight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParent(Node newParent) {
|
||||||
|
parent = newParent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Represent the root of binary tree
|
//Represent the root of binary tree
|
||||||
|
@ -38,11 +64,18 @@ public class BinarySearchTree extends AbstractBinaryTree<Integer> {
|
||||||
root = null;
|
root = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Position<Integer> root(){return root;}
|
public Position<Integer> root() {
|
||||||
public int size(){return size;}
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
//nonpublic utility
|
//nonpublic utility
|
||||||
/**validates the position and returns it as a node*/
|
/**
|
||||||
|
* validates the position and returns it as a node
|
||||||
|
*/
|
||||||
protected Node validate(Position<Integer> p) throws IllegalArgumentException {
|
protected Node validate(Position<Integer> p) throws IllegalArgumentException {
|
||||||
if (!(p instanceof Node)) {
|
if (!(p instanceof Node)) {
|
||||||
throw new IllegalArgumentException("not a valid position type");
|
throw new IllegalArgumentException("not a valid position type");
|
||||||
|
@ -72,6 +105,7 @@ public class BinarySearchTree extends AbstractBinaryTree<Integer> {
|
||||||
return node.getLeft();
|
return node.getLeft();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//copy and modify to find method, use find to calculate depth of each node
|
||||||
//insert() will add new node to the binary search tree
|
//insert() will add new node to the binary search tree
|
||||||
public void insert(int data) {
|
public void insert(int data) {
|
||||||
//Create a new node
|
//Create a new node
|
||||||
|
@ -82,8 +116,7 @@ public class BinarySearchTree extends AbstractBinaryTree<Integer> {
|
||||||
if (root == null) {
|
if (root == null) {
|
||||||
root = newNode;
|
root = newNode;
|
||||||
return;
|
return;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
|
|
||||||
//current node point to root of the tree
|
//current node point to root of the tree
|
||||||
Node current = root, parent = null;
|
Node current = root, parent = null;
|
||||||
|
@ -100,8 +133,7 @@ public class BinarySearchTree extends AbstractBinaryTree<Integer> {
|
||||||
newNode.setParent(parent);
|
newNode.setParent(parent);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
} //If data is greater than current's data, node will be inserted to the right of tree
|
||||||
//If data is greater than current's data, node will be inserted to the right of tree
|
|
||||||
else {
|
else {
|
||||||
current = current.getRight();
|
current = current.getRight();
|
||||||
if (current == null) {
|
if (current == null) {
|
||||||
|
@ -114,13 +146,56 @@ public class BinarySearchTree extends AbstractBinaryTree<Integer> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//find() will take a key and return the depth of that key.
|
||||||
|
public int find(int data) throws IllegalStateException, IllegalArgumentException {
|
||||||
|
int depth = 0;
|
||||||
|
//chekc if tree is empty
|
||||||
|
if (root == null) {
|
||||||
|
throw new IllegalStateException("tree is empty");
|
||||||
|
} else {
|
||||||
|
Node current = root;
|
||||||
|
Node parent = null;
|
||||||
|
while (true) {
|
||||||
|
//advance our way along the tree
|
||||||
|
parent = current;
|
||||||
|
if(data < current.data) {
|
||||||
|
current = current.getLeft();
|
||||||
|
//if there is no left child, element does not exist.
|
||||||
|
if (current == null) {
|
||||||
|
throw new IllegalArgumentException("data does not exitst");
|
||||||
|
}
|
||||||
|
} else if(data > current.data) {
|
||||||
|
current = current.getRight();
|
||||||
|
if (current == null) {
|
||||||
|
throw new IllegalArgumentException("data does not exitst");
|
||||||
|
}
|
||||||
|
} //must otherwise be equal
|
||||||
|
else {
|
||||||
|
return depth;
|
||||||
|
}
|
||||||
|
depth++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//gets the hight of the tree. should run in O(nlog(n)) time.
|
||||||
|
public int hight() throws IllegalStateException {
|
||||||
|
ArrayList<Integer> nodeList = nodeList(root);
|
||||||
|
int hight = 0;
|
||||||
|
for(int i=0; i<nodeList.size(); i++){
|
||||||
|
hight = Math.max(hight, find(nodeList.get(i)));
|
||||||
|
}
|
||||||
|
return hight;
|
||||||
|
}
|
||||||
//minNode() will find out the minimum node
|
//minNode() will find out the minimum node
|
||||||
|
|
||||||
public Position<Integer> minNode(Node root) {
|
public Position<Integer> minNode(Node root) {
|
||||||
if (root.left != null)
|
if (root.left != null) {
|
||||||
return minNode(root.left);
|
return minNode(root.left);
|
||||||
else
|
} else {
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//deleteNode() will delete the given node from the binary search tree
|
//deleteNode() will delete the given node from the binary search tree
|
||||||
public Position<Integer> deleteNode(Position<Integer> position, int value) {
|
public Position<Integer> deleteNode(Position<Integer> position, int value) {
|
||||||
|
@ -128,35 +203,27 @@ public class BinarySearchTree extends AbstractBinaryTree<Integer> {
|
||||||
Node node = validate(position);
|
Node node = validate(position);
|
||||||
if (node == null) {
|
if (node == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
//value is less than node's data then, search the value in left subtree
|
//value is less than node's data then, search the value in left subtree
|
||||||
if(value < node.getElement())
|
if (value < node.getElement()) //should be a safe cast...
|
||||||
//should be a safe cast...
|
{
|
||||||
node.setLeft((Node) deleteNode(node.getLeft(), value));
|
node.setLeft((Node) deleteNode(node.getLeft(), value));
|
||||||
|
} //value is greater than node's data then, search the value in right subtree
|
||||||
//value is greater than node's data then, search the value in right subtree
|
else if (value > node.getElement()) //should be a safe cast...
|
||||||
else if(value > node.getElement())
|
{
|
||||||
//should be a safe cast...
|
|
||||||
node.setRight((Node) deleteNode(node.getRight(), value));
|
node.setRight((Node) deleteNode(node.getRight(), value));
|
||||||
|
} //If value is equal to node's data that is, we have found the node to be deleted
|
||||||
//If value is equal to node's data that is, we have found the node to be deleted
|
|
||||||
else {
|
else {
|
||||||
//If node to be deleted has no child then, set the node to null
|
//If node to be deleted has no child then, set the node to null
|
||||||
if(node.getLeft() == null && node.getRight() == null)
|
if (node.getLeft() == null && node.getRight() == null) {
|
||||||
node = null;
|
node = null;
|
||||||
|
} //If node to be deleted has only one right child
|
||||||
//If node to be deleted has only one right child
|
|
||||||
else if (node.getLeft() == null) {
|
else if (node.getLeft() == null) {
|
||||||
node = node.getRight();
|
node = node.getRight();
|
||||||
}
|
} //If node to be deleted has only one left child
|
||||||
|
|
||||||
//If node to be deleted has only one left child
|
|
||||||
else if (node.getRight() == null) {
|
else if (node.getRight() == null) {
|
||||||
node = node.getLeft();
|
node = node.getLeft();
|
||||||
}
|
} //If node to be deleted has two children node
|
||||||
|
|
||||||
//If node to be deleted has two children node
|
|
||||||
else {
|
else {
|
||||||
//then find the minimum node from right subtree
|
//then find the minimum node from right subtree
|
||||||
//should be a safe cast...
|
//should be a safe cast...
|
||||||
|
@ -173,21 +240,105 @@ public class BinarySearchTree extends AbstractBinaryTree<Integer> {
|
||||||
}
|
}
|
||||||
|
|
||||||
//inorder() will perform inorder traversal on binary search tree
|
//inorder() will perform inorder traversal on binary search tree
|
||||||
|
//made iterative
|
||||||
public void inorderTraversal(Position<Integer> position) {
|
public void inorderTraversal(Position<Integer> position) {
|
||||||
Node node = validate(position);
|
Node node = validate(position);
|
||||||
//Check whether tree is empty
|
//Check whether tree is empty
|
||||||
if (root == null) {
|
if (root == null) {
|
||||||
System.out.println("Tree is empty");
|
System.out.println("Tree is empty");
|
||||||
return;
|
return;
|
||||||
|
} else {
|
||||||
|
ArrayStack<Node> nodeStack = new ArrayStack<>(size);
|
||||||
|
Node current = root;
|
||||||
|
while(current!=null||!nodeStack.isEmpty()){
|
||||||
|
//go down the left side as far as we can.
|
||||||
|
while(current!=null){
|
||||||
|
nodeStack.push(current);
|
||||||
|
current=current.getLeft();
|
||||||
|
}
|
||||||
|
//then go up one and to the right
|
||||||
|
current = nodeStack.pop();
|
||||||
|
System.out.print(current.getElement());
|
||||||
|
current = current.getRight();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//turns out that if we visit the right node before the left one in a preorder, we get a reversed post order traversal.
|
||||||
|
public void postorderTraversal(Position<Integer> position) {
|
||||||
|
Node root = validate(position);
|
||||||
|
if (root == null) {
|
||||||
|
System.out.println("Tree is empty");
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
ArrayStack<Node> nodeStack = new ArrayStack<>(size);
|
||||||
|
ArrayStack<Integer> returnStack = new ArrayStack<>(size);
|
||||||
|
nodeStack.push(root);
|
||||||
|
//do a modified preorder
|
||||||
|
while(!nodeStack.isEmpty()){
|
||||||
|
Node node = nodeStack.pop();
|
||||||
|
returnStack.push(node.getElement());
|
||||||
|
if (node.getRight() != null) {
|
||||||
|
nodeStack.push(node.getRight());
|
||||||
|
}
|
||||||
|
if (node.getLeft() != null) {
|
||||||
|
nodeStack.push(node.getLeft());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//print in reverse order
|
||||||
|
while(!returnStack.isEmpty()){
|
||||||
|
System.out.print(returnStack.pop());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
|
|
||||||
if(node.getLeft()!= null)
|
//made iterative
|
||||||
inorderTraversal((Position<Integer>)node.getLeft());
|
public void preorderTraversal(Position<Integer> position) {
|
||||||
System.out.print(node.getElement() + " ");
|
Node root = validate(position);
|
||||||
if(node.getRight() != null)
|
//Check whether tree is empty
|
||||||
inorderTraversal((Position<Integer>)node.getRight());
|
if (root == null) {
|
||||||
|
System.out.println("Tree is empty");
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
ArrayStack<Node> nodeStack = new ArrayStack<>(size);
|
||||||
|
nodeStack.push(root);
|
||||||
|
while (!nodeStack.isEmpty()) {
|
||||||
|
Node node = nodeStack.pop();
|
||||||
|
System.out.print(node.getElement());
|
||||||
|
if (node.getLeft() != null) {
|
||||||
|
nodeStack.push(node.getLeft());
|
||||||
|
}
|
||||||
|
if (node.getRight() != null) {
|
||||||
|
nodeStack.push(node.getRight());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//returns a list of entries from the external children of the node.
|
||||||
|
//made iterative
|
||||||
|
public ArrayList<Integer> nodeList(Position<Integer> position) throws IllegalStateException {
|
||||||
|
Node root = validate(position);
|
||||||
|
ArrayList<Integer> nodeList = new ArrayList<>();
|
||||||
|
//Check whether tree is empty
|
||||||
|
if (root == null) {
|
||||||
|
throw new IllegalStateException("tree is empty");
|
||||||
|
} else {
|
||||||
|
ArrayStack<Node> nodeStack = new ArrayStack<>(size);
|
||||||
|
nodeStack.push(root);
|
||||||
|
while (!nodeStack.isEmpty()) {
|
||||||
|
Node node = nodeStack.pop();
|
||||||
|
//only add if it is external.
|
||||||
|
if (node.getLeft() == null && node.getRight() == null) {
|
||||||
|
nodeList.add(node.getElement());
|
||||||
|
}
|
||||||
|
if (node.getLeft() != null) {
|
||||||
|
nodeStack.push(node.getLeft());
|
||||||
|
}
|
||||||
|
if (node.getRight() != null) {
|
||||||
|
nodeStack.push(node.getRight());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return nodeList;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
/*
|
|
||||||
* * Data Structures & Algorithms 6th Edition
|
|
||||||
* Goodrich, Tamassia, Goldwasser
|
|
||||||
* Code Fragments 8.6
|
|
||||||
*\
|
|
||||||
|
|
||||||
\**
|
|
||||||
*an interface for a binary tree, in which each node has at most two children.
|
|
||||||
* @author Gabriel Venberg
|
|
||||||
*/
|
|
||||||
public interface BinaryTree<E> extends Tree<E> {
|
|
||||||
/**returns the position of p's left child (or null if no child exists).*/
|
|
||||||
Position<E> left(Position<E> p) throws IllegalArgumentException;
|
|
||||||
/**returns the position of p's right child (or null if no child exists)*/
|
|
||||||
Position<E> right(Position<E> p) throws IllegalArgumentException;
|
|
||||||
/**returns the position of p's sibling (or null of no sibling exists).*/
|
|
||||||
Position <E> sibling(Position<E> p) throws IllegalArgumentException;
|
|
||||||
}
|
|
|
@ -27,7 +27,7 @@ public class Client {
|
||||||
|
|
||||||
|
|
||||||
//set up stuff needed for test.
|
//set up stuff needed for test.
|
||||||
final int BSTSize = 10;
|
final int BSTSize = 1000000;
|
||||||
long startTime;
|
long startTime;
|
||||||
long endTime;
|
long endTime;
|
||||||
String[][] data = new String[7][2];
|
String[][] data = new String[7][2];
|
||||||
|
@ -36,27 +36,34 @@ public class Client {
|
||||||
BinarySearchTree testTree = new BinarySearchTree();
|
BinarySearchTree testTree = new BinarySearchTree();
|
||||||
startTime=System.nanoTime();
|
startTime=System.nanoTime();
|
||||||
for(int i=0; i<BSTSize; i++){
|
for(int i=0; i<BSTSize; i++){
|
||||||
System.out.println("test1,"+i);
|
|
||||||
testTree.insert(i);
|
testTree.insert(i);
|
||||||
}
|
}
|
||||||
data[0][1] = String.format("%,d", testTree.hight(testTree.root()));
|
data[0][1] = String.format("%,d", testTree.hight());
|
||||||
System.out.println("test2");
|
|
||||||
endTime=System.nanoTime();
|
endTime=System.nanoTime();
|
||||||
data[0][0]=String.format("%,d", endTime-startTime);
|
data[0][0]=String.format("%,d", endTime-startTime);
|
||||||
|
|
||||||
testTree.inorderTraversal(testTree.root());
|
testTree.inorderTraversal(testTree.root());
|
||||||
System.out.println();
|
System.out.println();
|
||||||
|
testTree.preorderTraversal(testTree.root());
|
||||||
|
System.out.println();
|
||||||
|
testTree.postorderTraversal(testTree.root());
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
|
||||||
//decending order test
|
//decending order test
|
||||||
testTree = new BinarySearchTree();
|
testTree = new BinarySearchTree();
|
||||||
startTime=System.nanoTime();
|
startTime=System.nanoTime();
|
||||||
for(int i=BSTSize-1; i>=0; i--){
|
for(int i=BSTSize-1; i>=0; i--){
|
||||||
System.out.println("test3,"+i);
|
|
||||||
testTree.insert(i);
|
testTree.insert(i);
|
||||||
}
|
}
|
||||||
data[1][1] = String.format("%,d", testTree.hight(testTree.root()));
|
data[1][1] = String.format("%,d", testTree.hight());
|
||||||
System.out.println("test4,");
|
|
||||||
endTime=System.nanoTime();
|
endTime=System.nanoTime();
|
||||||
data[1][0]=String.format("%,d", endTime-startTime);
|
data[1][0]=String.format("%,d", endTime-startTime);
|
||||||
|
|
||||||
|
testTree.preorderTraversal(testTree.root());
|
||||||
|
System.out.println();
|
||||||
|
testTree.postorderTraversal(testTree.root());
|
||||||
|
System.out.println();
|
||||||
testTree.inorderTraversal(testTree.root());
|
testTree.inorderTraversal(testTree.root());
|
||||||
System.out.println();
|
System.out.println();
|
||||||
|
|
||||||
|
@ -73,15 +80,11 @@ public class Client {
|
||||||
|
|
||||||
startTime=System.nanoTime();
|
startTime=System.nanoTime();
|
||||||
for(int j=0; j<uniqueNumbers.length; j++){
|
for(int j=0; j<uniqueNumbers.length; j++){
|
||||||
System.out.println("test5,"+i+","+j);
|
|
||||||
testTree.insert(uniqueNumbers[j]);
|
testTree.insert(uniqueNumbers[j]);
|
||||||
}
|
}
|
||||||
data[i+2][1]=String.format("%,d", testTree.hight(testTree.root()));
|
data[i+2][1]=String.format("%,d", testTree.hight());
|
||||||
System.out.println("test6,"+i);
|
|
||||||
endTime=System.nanoTime();
|
endTime=System.nanoTime();
|
||||||
data[i+2][0]=String.format("%,d", endTime-startTime);
|
data[i+2][0]=String.format("%,d", endTime-startTime);
|
||||||
testTree.inorderTraversal(testTree.root());
|
|
||||||
System.out.println();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] colHeaders = {"Time taken", "Tree hight"};
|
String[] colHeaders = {"Time taken", "Tree hight"};
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
/*
|
|
||||||
* Data Structures & Algorithms 6th Edition
|
|
||||||
* Goodrich, Tamassia, Goldwasser
|
|
||||||
* Code Fragment 6.11
|
|
||||||
*
|
|
||||||
* An implementation of the LinkedQueue class
|
|
||||||
* */
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Gabriel Venberg
|
|
||||||
*/
|
|
||||||
public class LinkedQueue<E> implements Queue<E>{
|
|
||||||
private SinglyLinkedList<E> list = new SinglyLinkedList(); //an empty list
|
|
||||||
public LinkedQueue(){} //new queue relies on initaly empty list
|
|
||||||
public int size(){return list.size();}
|
|
||||||
public boolean isEmpty(){return list.isEmpty();}
|
|
||||||
public void enqueue(E element){list.addLast(element);}
|
|
||||||
public E first(){return list.first();}
|
|
||||||
public E dequeue(){return list.removeFirst();}
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
/**
|
|
||||||
* Data Structures & Algorithms 6th Edition
|
|
||||||
* Goodrich, Tamassia, Goldwasser
|
|
||||||
* Code Fragment 6.9
|
|
||||||
*
|
|
||||||
* An implementation of the Queue interface
|
|
||||||
* */
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Gabriel Venberg
|
|
||||||
*/
|
|
||||||
public interface Queue<E> {
|
|
||||||
/** returns the number of elements in the queue*/
|
|
||||||
int size();
|
|
||||||
|
|
||||||
/** tests whether the queue is empty*/
|
|
||||||
boolean isEmpty();
|
|
||||||
|
|
||||||
/**inserts an element at the rear of the queue*/
|
|
||||||
void enqueue(E e);
|
|
||||||
|
|
||||||
/**returns, but does not remove, the first element of the queue (null if empty). */
|
|
||||||
E first();
|
|
||||||
|
|
||||||
/** removes and returns the first element of the queue (null if empty)*/
|
|
||||||
E dequeue();
|
|
||||||
}
|
|
|
@ -1,78 +0,0 @@
|
||||||
/**
|
|
||||||
*SinglyLinkedListClass
|
|
||||||
* Code Fragments 3.14, 3.15
|
|
||||||
* from
|
|
||||||
* Data Structures & Algorithms, 6th edition
|
|
||||||
* by Michael T. Goodrich, Roberto Tamassia & Michael H. Goldwasser
|
|
||||||
* Wiley 2014
|
|
||||||
* Transcribed by
|
|
||||||
* @author Gabe Venberg
|
|
||||||
*/
|
|
||||||
public class SinglyLinkedList<E> {
|
|
||||||
|
|
||||||
private static class Node<E> {
|
|
||||||
private E element; //refrence to element stored at this node
|
|
||||||
private Node<E> next; //refrence to subsequent node of list
|
|
||||||
|
|
||||||
public Node(E e, Node<E> n){
|
|
||||||
element = e;
|
|
||||||
next = n;
|
|
||||||
}
|
|
||||||
|
|
||||||
public E getElement() {return element;}
|
|
||||||
|
|
||||||
public Node<E> getNext() {return next;}
|
|
||||||
|
|
||||||
public void setNext(Node<E> n) {next = n;}
|
|
||||||
}
|
|
||||||
|
|
||||||
//instance variables of SinglyLinkedList
|
|
||||||
private Node<E> head = null;//head node of list
|
|
||||||
private Node<E> tail = null;//last node of list
|
|
||||||
private int size = 0;//number of nodes in list
|
|
||||||
|
|
||||||
public SinglyLinkedList(){}//constructs an initaly empty list
|
|
||||||
|
|
||||||
//access methods
|
|
||||||
public int size() {return size;}
|
|
||||||
|
|
||||||
public boolean isEmpty() {return size == 0;}
|
|
||||||
|
|
||||||
public E first(){//returns but does not remove the first element
|
|
||||||
if (size == 0) {return null;} //special case
|
|
||||||
return head.getElement();
|
|
||||||
}
|
|
||||||
|
|
||||||
public E last(){//returns but does not remove last elemnt
|
|
||||||
if (size ==0) {return null;}//special case
|
|
||||||
return tail.getElement();
|
|
||||||
}
|
|
||||||
|
|
||||||
//update methods
|
|
||||||
public void addFirst(E e){//adds element e to the front of the list
|
|
||||||
head = new Node<>(e, head);//create and link a new node
|
|
||||||
if (size == 0) {tail = head;}//special case, head becomes tail also
|
|
||||||
size++;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addLast(E e){//adds element to end of list
|
|
||||||
Node<E> newest = new Node<>(e, null);//create and link a new node
|
|
||||||
if(size == 0){//special case, previously empty list
|
|
||||||
head = newest;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
tail.setNext(newest);//new node after existing tail
|
|
||||||
}
|
|
||||||
tail = newest;//new node becomes tail
|
|
||||||
size++;
|
|
||||||
}
|
|
||||||
|
|
||||||
public E removeFirst(){//removes and returns the first element
|
|
||||||
if(size == 0){return null;}//nothing to remove
|
|
||||||
E answer = head.getElement();
|
|
||||||
head = head.getNext();//will become null if list had only one node.
|
|
||||||
size--;
|
|
||||||
if(size==0){tail = null;}// special case as list is now empty
|
|
||||||
return answer;
|
|
||||||
}
|
|
||||||
}
|
|
46
Lab110-VenbergGE/src/Stack.java
Normal file
46
Lab110-VenbergGE/src/Stack.java
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/**
|
||||||
|
* Data Structures & Algorithms 6th Edition
|
||||||
|
* Goodrich, Tamassia, Goldwasser
|
||||||
|
* Code Fragment 6.1
|
||||||
|
*
|
||||||
|
* An implementation of the stack interface
|
||||||
|
* */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A collection of objects that are inserted and removed according to a last-in
|
||||||
|
* first-out principle. Although similar in purpose, this interface differs from
|
||||||
|
* java.util.stack.
|
||||||
|
* @author Gabriel Venberg
|
||||||
|
*/
|
||||||
|
public interface Stack<E> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the number of elements in the stack
|
||||||
|
* @return number of elements in the stack.
|
||||||
|
*/
|
||||||
|
int size();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tests whether the stack is empty.
|
||||||
|
* @return true if stack is empty, false otherwise.
|
||||||
|
*/
|
||||||
|
boolean isEmpty();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* inserts an element at the top of the stack.
|
||||||
|
* @param e the element to be inserted.
|
||||||
|
*/
|
||||||
|
void push(E e);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns, but does not remove, the top element of the stack.
|
||||||
|
* @return top element of the stack or null if empty.
|
||||||
|
*/
|
||||||
|
E top();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* removes and returns the top element from the stack.
|
||||||
|
* @return element removed or null if empty.
|
||||||
|
*/
|
||||||
|
E pop();
|
||||||
|
}
|
|
@ -1,29 +0,0 @@
|
||||||
|
|
||||||
import java.util.Iterator;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Data Structures & Algorithms 6th Edition
|
|
||||||
* Goodrich, Tamassia, Goldwasser
|
|
||||||
* Code Fragment 8.1
|
|
||||||
*
|
|
||||||
* An implementation of the tree interface
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An interface for a tree where nodes can have an arbitrary number of children.
|
|
||||||
* @author Gabriel Venberg
|
|
||||||
*/
|
|
||||||
public interface Tree<E> extends Iterable<E>{
|
|
||||||
Position <E> root();
|
|
||||||
Position<E> parent(Position<E> p) throws IllegalArgumentException;
|
|
||||||
Iterable<Position<E>> children(Position<E> p) throws IllegalArgumentException;
|
|
||||||
int numChildren(Position<E> p) throws IllegalArgumentException;
|
|
||||||
boolean isInternal(Position<E> p) throws IllegalArgumentException;
|
|
||||||
boolean isExternal(Position<E> p) throws IllegalArgumentException;
|
|
||||||
boolean isRoot(Position<E> p) throws IllegalArgumentException;
|
|
||||||
int size();
|
|
||||||
boolean isEmpty();
|
|
||||||
Iterator<E> iterator();
|
|
||||||
Iterable<Position<E>> positions();
|
|
||||||
}
|
|
Reference in a new issue