Advertisement
LeCupcake

BST

Dec 4th, 2018
278
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 10.78 KB | None | 0 0
  1. package tree;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.HashMap;
  5. import java.util.List;
  6. import java.util.Map;
  7.  
  8. @SuppressWarnings("WeakerAccess")
  9. public class BST<E extends Comparable<E>> implements BSTInterface<E> {
  10.  
  11.     //----------- end of nested Node class -----------
  12.     protected Node<E> root;     // root of the tree
  13.  
  14.     /**
  15.      * Constructs an empty binary search tree.
  16.      */
  17.     public BST() {
  18.         root = null;
  19.     }
  20.  
  21.     /**
  22.      * @return root Node of the tree (or null if tree is empty)
  23.      */
  24.     protected Node<E> root() {
  25.         return root;
  26.     }
  27.  
  28.     /**
  29.      * Verifies if the tree is empty
  30.      *
  31.      * @return true if the tree is empty, false otherwise
  32.      */
  33.     public boolean isEmpty() {
  34.         return root == null;
  35.     }
  36.  
  37.     /**
  38.      * Inserts an element in the tree.
  39.      */
  40.     public void insert(E element) {
  41.         root = insert(element, root);
  42.     }
  43.  
  44.     private Node<E> insert(E element, Node<E> node) {
  45.         if (node == null) {
  46.             return new Node<>(element, null, null);
  47.         }
  48.  
  49.         if (node.getElement().compareTo(element) > 0) {
  50.             node.setLeft(insert(element, node.getLeft()));
  51.             return node;
  52.         }
  53.  
  54.         if (node.getElement().compareTo(element) < 0) {
  55.             node.setRight(insert(element, node.getRight()));
  56.             return node;
  57.         }
  58.  
  59.         node.setElement(element);
  60.         return node;
  61.     }
  62.  
  63.     /**
  64.      * Removes an element from the tree maintaining its consistency as a Binary
  65.      * Search Tree.
  66.      */
  67.     public void remove(E element) {
  68.         root = remove(element, root());
  69.     }
  70.  
  71.     private Node<E> remove(E element, Node<E> node) {
  72.  
  73.         if (node == null) {
  74.             return null;    //throw new IllegalArgumentException("Element does not exist");
  75.         }
  76.         if (element.compareTo(node.getElement()) == 0) {
  77.             // node is the Node to be removed
  78.             if (node.getLeft() == null && node.getRight() == null) { //node is a leaf (has no childs)
  79.                 return null;
  80.             }
  81.             if (node.getLeft() == null) {   //has only right child
  82.                 return node.getRight();
  83.             }
  84.             if (node.getRight() == null) {  //has only left child
  85.                 return node.getLeft();
  86.             }
  87.             E min = smallestElement(node.getRight());
  88.             node.setElement(min);
  89.             node.setRight(remove(min, node.getRight()));
  90.         } else if (element.compareTo(node.getElement()) < 0) {
  91.             node.setLeft(remove(element, node.getLeft()));
  92.         } else {
  93.             node.setRight(remove(element, node.getRight()));
  94.         }
  95.  
  96.         return node;
  97.     }
  98.  
  99.     /**
  100.      * Returns the number of nodes in the tree.
  101.      *
  102.      * @return number of nodes in the tree
  103.      */
  104.     public int size() {
  105.         return size(root);
  106.     }
  107.  
  108.     private int size(Node<E> node) {
  109.         if (node == null) {
  110.             return 0;
  111.         }
  112.         return 1 + size(node.getLeft()) + size(node.getRight());
  113.     }
  114.  
  115.     /**
  116.      * Returns the height of the tree
  117.      *
  118.      * @return height
  119.      */
  120.     public int height() {
  121.         return height(root);
  122.     }
  123.  
  124.     /**
  125.      * Returns the height of the subtree rooted at Node node.
  126.      *
  127.      * @param node A valid Node within the tree
  128.      * @return height
  129.      */
  130.     protected int height(Node<E> node) {
  131.         if (node == null) {
  132.             return -1;
  133.         }
  134.  
  135.         int leftHeight = height(node.getLeft());
  136.         int rightHeight = height(node.getRight());
  137.  
  138.         if (leftHeight > rightHeight) {
  139.             return 1 + leftHeight;
  140.         }
  141.  
  142.         return 1 + rightHeight;
  143.     }
  144.  
  145.     /**
  146.      * Returns the smallest element within the tree.
  147.      *
  148.      * @return the smallest element within the tree
  149.      */
  150.     public E smallestElement() {
  151.         return smallestElement(root);
  152.     }
  153.  
  154.     protected E smallestElement(Node<E> node) {
  155.         if (node.getLeft() == null) {
  156.             return node.getElement();
  157.         }
  158.         return smallestElement(node.getLeft());
  159.     }
  160.  
  161.     /**
  162.      * Returns the Node containing a specific Element, or null otherwise.
  163.      *
  164.      * @param element the element to find
  165.      * @return the Node that contains the Element, or null otherwise
  166.      * <p>
  167.      * This method despite not being essential is very useful. It is written
  168.      * here in order to be used by this class and its subclasses avoiding
  169.      * recoding. So its access level is protected
  170.      */
  171.     public Node<E> find(E element) {
  172.         return find(element, root);
  173.     }
  174.  
  175.     protected Node<E> find(E element, Node<E> node) {
  176.         if (node == null) {
  177.             return null;
  178.         }
  179.         // if left
  180.         if (node.getLeft().getElement().compareTo(element) > 0) {
  181.             return find(element, node.getLeft());
  182.         }
  183.         // if right
  184.         if (node.getRight().getElement().compareTo(element) < 0) {
  185.             return find(element, node.getRight());
  186.         }
  187.         // if found
  188.         return node;
  189.     }
  190.  
  191.     /**
  192.      * Returns an iterable collection of elements of the tree, reported in in-order.
  193.      *
  194.      * @return iterable collection of the tree's elements reported in in-order
  195.      */
  196.     public Iterable<E> inOrder() {
  197.         List<E> snapshot = new ArrayList<>();
  198.         if (root != null) {
  199.             inOrderSubtree(root, snapshot);   // fill the snapshot recursively
  200.         }
  201.         return snapshot;
  202.     }
  203.  
  204.     /**
  205.      * Adds elements of the subtree rooted at Node node to the given snapshot
  206.      * using an in-order traversal
  207.      *
  208.      * @param node     Node serving as the root of a subtree
  209.      * @param snapshot a list to which results are appended
  210.      */
  211.     private void inOrderSubtree(Node<E> node, List<E> snapshot) {
  212.         if (node == null) {
  213.             return;
  214.         }
  215.         inOrderSubtree(node.getLeft(), snapshot);
  216.         snapshot.add(node.getElement());
  217.         inOrderSubtree(node.getRight(), snapshot);
  218.     }
  219.  
  220.     /**
  221.      * Returns an iterable collection of elements of the tree, reported in
  222.      * pre-order.
  223.      *
  224.      * @return iterable collection of the tree's elements reported in pre-order
  225.      */
  226.     public Iterable<E> preOrder() {
  227.         List<E> lista = new ArrayList<>();
  228.         preOrderSubtree(root, lista);
  229.         return lista;
  230.     }
  231.  
  232.     /**
  233.      * Adds elements of the subtree rooted at Node node to the given snapshot
  234.      * using an pre-order traversal
  235.      *
  236.      * @param node     Node serving as the root of a subtree
  237.      * @param snapshot a list to which results are appended
  238.      */
  239.     private void preOrderSubtree(Node<E> node, List<E> snapshot) {
  240.         if (node != null) {
  241.             snapshot.add(node.getElement());
  242.             preOrderSubtree(node.getLeft(), snapshot);
  243.             preOrderSubtree(node.getRight(), snapshot);
  244.         }
  245.     }
  246.  
  247.     /**
  248.      * Returns an iterable collection of elements of the tree, reported in
  249.      * post-order.
  250.      *
  251.      * @return iterable collection of the tree's elements reported in post-order
  252.      */
  253.     public Iterable<E> posOrder() {
  254.         List<E> lista = new ArrayList<>();
  255.         posOrderSubtree(root, lista);
  256.         return lista;
  257.     }
  258.  
  259.     /**
  260.      * Adds positions of the subtree rooted at Node node to the given snapshot
  261.      * using an post-order traversal
  262.      *
  263.      * @param node     Node serving as the root of a subtree
  264.      * @param snapshot a list to which results are appended
  265.      */
  266.     private void posOrderSubtree(Node<E> node, List<E> snapshot) {
  267.         if (node != null) {
  268.             posOrderSubtree(node.getLeft(), snapshot);
  269.             posOrderSubtree(node.getRight(), snapshot);
  270.             snapshot.add(node.getElement());
  271.         }
  272.     }
  273.  
  274.     /*
  275.      * Returns a map with a list of nodes by each tree level.
  276.      * @return a map with a list of nodes by each tree level
  277.      */
  278.     public Map<Integer, List<E>> nodesByLevel() {
  279.         Map<Integer, List<E>> map = new HashMap<>();
  280.         processBstByLevel(root, map, 0);
  281.         return map;
  282.     }
  283.  
  284.     private void processBstByLevel(Node<E> node, Map<Integer, List<E>> result, int level) {
  285.         if (node != null) {
  286.             if (!result.containsKey(level)) {
  287.                 result.put(level, new ArrayList<>());
  288.             }
  289.             List<E> list = result.get(level);
  290.             list.add(node.getElement());
  291.             processBstByLevel(node.getLeft(), result, level + 1);
  292.             processBstByLevel(node.getRight(), result, level + 1);
  293.         }
  294.     }
  295.  
  296.     /**
  297.      * Returns a string representation of the tree. Draw the tree horizontally
  298.      */
  299.     public String toString() {
  300.         StringBuilder sb = new StringBuilder();
  301.         toStringRec(root, 0, sb);
  302.         return sb.toString();
  303.     }
  304.  
  305. //#########################################################################
  306.  
  307.     private void toStringRec(Node<E> root, int level, StringBuilder sb) {
  308.         if (root == null) {
  309.             return;
  310.         }
  311.         toStringRec(root.getRight(), level + 1, sb);
  312.         if (level != 0) {
  313.             for (int i = 0; i < level - 1; i++) {
  314.                 sb.append("|\t");
  315.             }
  316.             sb.append("|-------").append(root.getElement()).append("\n");
  317.         } else {
  318.             sb.append(root.getElement()).append("\n");
  319.         }
  320.         toStringRec(root.getLeft(), level + 1, sb);
  321.     }
  322.  
  323.     /**
  324.      * Nested static class for a binary search tree node.
  325.      */
  326.     protected static class Node<E> {
  327.  
  328.         private E element;          // an element stored at this node
  329.         private Node<E> left;       // a reference to the left child (if any)
  330.         private Node<E> right;      // a reference to the right child (if any)
  331.  
  332.         /**
  333.          * Constructs a node with the given element and neighbors.
  334.          *
  335.          * @param e          the element to be stored
  336.          * @param leftChild  reference to a left child node
  337.          * @param rightChild reference to a right child node
  338.          */
  339.         public Node(E e, Node<E> leftChild, Node<E> rightChild) {
  340.             element = e;
  341.             left = leftChild;
  342.             right = rightChild;
  343.         }
  344.  
  345.         // accessor methods
  346.         public E getElement() {
  347.             return element;
  348.         }
  349.  
  350.         // update methods
  351.         public void setElement(E e) {
  352.             element = e;
  353.         }
  354.  
  355.         public Node<E> getLeft() {
  356.             return left;
  357.         }
  358.  
  359.         public void setLeft(Node<E> leftChild) {
  360.             left = leftChild;
  361.         }
  362.  
  363.         public Node<E> getRight() {
  364.             return right;
  365.         }
  366.  
  367.         public void setRight(Node<E> rightChild) {
  368.             right = rightChild;
  369.         }
  370.     }
  371.  
  372. } //----------- end of tree.tree class -----------
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement