diff --git a/Java/BinarySearchTree.java b/Java/BinarySearchTree.java new file mode 100644 index 0000000..05e359e --- /dev/null +++ b/Java/BinarySearchTree.java @@ -0,0 +1,171 @@ +package BinarySearchTree; + +/** + * | Binary Search Tree | + * This class implements a binary search tree whose + * nodes hold objects that implement the Comparable + * interface. + * + * Author: AnxietyMedicine on GitHub + */ +public class BinarySearchTree { + private Node root; + + /** + * Constructs an empty tree + */ + public BinarySearchTree() { + root = null; + } + + /** + * Inserts a new node into the tree + * @param obj the object to insert + */ + public void add(Comparable obj) { + Node newNode = new Node(); + newNode.data = obj; + newNode.left = null; + newNode.right = null; + if (root == null) { root = newNode; } + else { root.addNode(newNode); } + } + + /** + * Tries to find an object in the tree + * @param obj the object to find + * @return true if the object is contained in the tree + */ + public boolean find(Comparable obj) { + Node current = root; + + while (current != null) { + int d = current.data.compareTo(obj); + if (d == 0) { + return true; + } + else if (d > 0) { + current = current.left; + } + else { + current = current.right; + } + } + + return false; + } + + /** + * Tries to remove an object from the tree. Does nothing + * if the object is not contained in the tree. + * @param obj the object to remove + */ + public void remove(Comparable obj) { + Node toBeRemoved = root; + Node parent = null; + boolean found = false; + + while (!found && toBeRemoved != null) { + int d = toBeRemoved.data.compareTo(obj); + if (d == 0) { + found = true; + } else { + parent = toBeRemoved; + if (d > 0) { + toBeRemoved = toBeRemoved.left; + } else { + toBeRemoved = toBeRemoved.right; + } + } + } + + if (!found) { + return; + } + + // toBeRemoved contains obj + + // if one of the children is empty, use the other + + if (toBeRemoved.left == null || toBeRemoved.right == null) { + Node newChild; + if (toBeRemoved.left == null) { + newChild = toBeRemoved.right; + } else { + newChild = toBeRemoved.left; + } + + if (parent == null) { + root = newChild; + } // found in root + else if (parent.left == toBeRemoved) { + parent.left = newChild; + } else { + parent.right = newChild; + } + return; + } + + // neither subtree is empty + + // find smallest element of right subtree + + Node smallestParent = toBeRemoved; + Node smallest = toBeRemoved.right; + while (smallest.left != null) { + smallestParent = smallest; + smallest = smallest.left; + } + + // smallest contains smallest child in right subtree + + // move contents, unlink child + + toBeRemoved.data = smallest.data; + if (smallestParent == toBeRemoved) { + smallestParent.right = smallest.right; + } else { + smallestParent.left = smallest.right; + } + } + + /** + * Prints the contents of the tree in sorted order + */ + public void print() { + print(root); + System.out.println(); + } + + /** + * Prints a node and all of its descendants in sorted order + * @param parent the root of the subtree to print + */ + private static void print(Node parent) { + if (parent == null) { return; } + print(parent.left); + System.out.print(parent.data + " "); + print(parent.right); + } + + /** + * A node of a tree stores a data item and + * references to the left and right child nodes + */ + static class Node { + public Comparable data; + public Node left; + public Node right; + + public void addNode(Node newNode) { + int comp = newNode.data.compareTo(data); + if (comp < 0) { + if (left == null) { left = newNode; } + else { left.addNode(newNode); } + } else if (comp > 0) { + if (right == null) { right = newNode; } + else { right.addNode(newNode); } + } + } + } +} diff --git a/Java/CircularArrayQueue.java b/Java/CircularArrayQueue.java new file mode 100644 index 0000000..197b878 --- /dev/null +++ b/Java/CircularArrayQueue.java @@ -0,0 +1,70 @@ +import java.util.NoSuchElementException; + +/** + * An implementation of a queue as a circular array + * + * Author: AnxietyMedicine (GitHub) + */ +public class CircularArrayQueue { + private Object[] elements; + private int head, tail, currentSize; + + /** + * Constructs an empty queue + */ + public CircularArrayQueue() { + final int INITIAL_SIZE = 10; + elements = new Object[INITIAL_SIZE]; + head = tail = currentSize = 0; + } + + /** + * Adds an element to the tail of the queue + * @param newElement new element to add + */ + public void add(Object newElement) { + growIfNecessary(); + currentSize++; + + elements[tail] = newElement; + tail = (tail + 1) % elements.length; + } + + /** + * Removes an element from the head of the queue + * @return removed element + */ + public Object remove() { + if (currentSize == 0) { throw new NoSuchElementException(); } + + Object removed = elements[head]; + head = (head + 1) % elements.length; + + return removed; + } + + /** + * Grows the element array if the current size equals the capacity + */ + private void growIfNecessary() { + if (currentSize == elements.length) { + Object[] newElements = new Object[2 * elements.length]; + + for (int i = 0; i < elements.length; i++) { + newElements[i] = elements[(head + i) % elements.length]; + } + + elements = newElements; + head = 0; + tail = currentSize; + } + } + + /** + * Checks whether queue is empty + * @return true if queue is empty + */ + public boolean empty() { + return currentSize == 0; + } +}