summaryrefslogtreecommitdiff
path: root/BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/BinarySearchTree.java
diff options
context:
space:
mode:
authorbculkin2442 <bjculkin@mix.wvu.edu>2015-09-29 16:24:37 -0400
committerbculkin2442 <bjculkin@mix.wvu.edu>2015-09-29 16:24:37 -0400
commitba7711b8546e08fa6376a85271d2ca1c34cc902b (patch)
treea04b8283c828eb49c978955ccef7c4cab3fe9754 /BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/BinarySearchTree.java
parentb964a4b44cd2c24083db8e1cccfd6de22e440861 (diff)
Moved around tree stuff.
Diffstat (limited to 'BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/BinarySearchTree.java')
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/BinarySearchTree.java128
1 files changed, 128 insertions, 0 deletions
diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/BinarySearchTree.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/BinarySearchTree.java
new file mode 100644
index 0000000..d028293
--- /dev/null
+++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/BinarySearchTree.java
@@ -0,0 +1,128 @@
+package bjc.utils.funcdata.bst;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.function.Predicate;
+
+import bjc.utils.funcdata.bst.ITreePart.TreeLinearizationMethod;
+
+/**
+ * A binary search tree, with some mild support for functional traversal.
+ *
+ * @author ben
+ *
+ * @param <T> The data type stored in the node.
+ */
+public class BinarySearchTree<T> {
+ private Comparator<T> comp;
+ private int nCount;
+ private ITreePart<T> root;
+
+ /**
+ * Create a new tree using the specified way to compare elements.
+ * @param cmp
+ */
+ public BinarySearchTree(Comparator<T> cmp) {
+ nCount = 0;
+ comp = cmp;
+ }
+
+ /**
+ * Add a node to the binary search tree.
+ * @param dat The data to add to the binary search tree.
+ */
+ public void addNode(T dat) {
+ nCount++;
+ if (root == null) {
+ root = new TreeNode<T>(dat, null, null);
+ } else {
+ root.add(dat, comp);
+ }
+ }
+
+ /**
+ * Balance the tree, and remove soft-deleted nodes for free.
+ * Takes O(N) time, but also O(N) space.
+ */
+ public void balance() {
+ ArrayList<T> elms = new ArrayList<>(nCount);
+
+ root.forEach(TreeLinearizationMethod.INORDER, e -> elms.add(e));
+
+ root = null;
+
+ int piv = elms.size() / 2;
+ int adj = 0;
+
+ while((piv - adj) >= 0 && (piv + adj) < elms.size()) {
+ if(root == null) {
+ root = new TreeNode<T>(elms.get(piv), null, null);
+ } else {
+ root.add(elms.get(piv + adj), comp);
+ root.add(elms.get(piv - adj), comp);
+ }
+
+ adj++;
+ }
+
+ if((piv - adj) >= 0) {
+ root.add(elms.get(piv - adj), comp);
+ } else if((piv + adj) < elms.size()) {
+ root.add(elms.get(piv + adj), comp);
+ }
+ }
+
+ /**
+ * Get the root of the tree.
+ * @return The root of the tree.
+ */
+ public ITreePart<T> getRoot() {
+ return root;
+ }
+
+ /**
+ * Soft-delete a node from the tree.
+ * Soft-deleted nodes stay in the tree until trim()/balance() is invoked,
+ * and are not included in traversals/finds.
+ * @param dat
+ */
+ public void deleteNode(T dat) {
+ nCount--;
+ root.delete(dat, comp);
+ }
+
+ /**
+ * Check if a node is in the tree
+ * @param dat The node to check the presence of for the tree.
+ * @return Whether or not the node is in the tree.
+ */
+ public boolean isInTree(T dat) {
+ return root.contains(dat, comp);
+ }
+
+ /**
+ * Traverse the tree in a specified way until the function fails
+ * @param tlm The way to linearize the tree for traversal
+ * @param p The function to use until it fails
+ */
+ public void traverse(TreeLinearizationMethod tlm, Predicate<T> p) {
+ root.forEach(tlm, p);
+ }
+
+ /**
+ * Remove all soft-deleted nodes from the tree.
+ */
+ public void trim() {
+ List<T> nds = new ArrayList<>(nCount);
+
+ traverse(TreeLinearizationMethod.PREORDER, d -> {
+ nds.add(d);
+ return true;
+ });
+
+ root = null;
+
+ nds.forEach(d -> addNode(d));
+ }
+}