Commit 245a266c5b9f5e5f884cef1e388a5f0496ff8ad9

Authored by Iuliia Romanivna Ukrainets
0 parents

make a method isPerfect(), implement inorder traversing without recurrence with stack

.gitignore 0 → 100644
  1 +++ a/.gitignore
  1 +out/
  2 +.idea/
0 3 \ No newline at end of file
... ...
BST.iml 0 → 100644
  1 +++ a/BST.iml
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<module type="JAVA_MODULE" version="4">
  3 + <component name="NewModuleRootManager" inherit-compiler-output="true">
  4 + <exclude-output />
  5 + <content url="file://$MODULE_DIR$">
  6 + <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
  7 + </content>
  8 + <orderEntry type="inheritedJdk" />
  9 + <orderEntry type="sourceFolder" forTests="false" />
  10 + </component>
  11 +</module>
  12 +
... ...
src/AbstractTree.java 0 → 100644
  1 +++ a/src/AbstractTree.java
  1 +public abstract class AbstractTree<E extends Comparable<E>> implements Tree<E>, Iterable<E> {
  2 + public boolean isEmpty() {
  3 + return getSize() == 0;
  4 + }
  5 +}
... ...
src/BinarySearchTree.java 0 → 100644
  1 +++ a/src/BinarySearchTree.java
  1 +import java.util.ArrayList;
  2 +import java.util.LinkedList;
  3 +import java.util.Stack;
  4 +
  5 +public class BinarySearchTree<E extends Comparable<E>> extends AbstractTree<E> {
  6 + /** Root node for the tree. */
  7 + private TreeNode<E> root;
  8 +
  9 + /** Size of the tree, number of nodes. */
  10 + private int size = 0;
  11 +
  12 + /** Create a default binary tree. */
  13 + BinarySearchTree() {
  14 + }
  15 +
  16 + /**
  17 + * Create a binary tree from an array of objects.
  18 + *
  19 + * @param objects Array of objects to use in creation of tree.
  20 + */
  21 + BinarySearchTree(E[] objects) {
  22 + for (E object : objects) {
  23 + insert(object);
  24 + }
  25 + }
  26 +
  27 + /////////////////////////////////////////////////////////////////////////////
  28 + // Interface Methods //
  29 + /////////////////////////////////////////////////////////////////////////////
  30 +
  31 + public boolean search(E element) {
  32 + TreeNode<E> current = root; // Start from the root
  33 +
  34 + while (current != null) {
  35 + if (element.compareTo(current.element) < 0) {
  36 + current = current.left;
  37 + } else if (element.compareTo(current.element) > 0) {
  38 + current = current.right;
  39 + } else { // element matches current.element
  40 + return true; // Element is found
  41 + }
  42 + }
  43 +
  44 + return false;
  45 + }
  46 +
  47 + public boolean insert(E element) {
  48 + if (root == null) { // First element in Tree.
  49 + root = createNewNode(element);
  50 + } else {
  51 + // Locate the parent node
  52 + TreeNode<E> parent = null;
  53 + TreeNode<E> current = root;
  54 +
  55 + while (current != null) { // Go through the tree till we reach appropriate leaf node.
  56 + parent = current;
  57 +
  58 + if (element.compareTo(current.element) < 0) {
  59 + current = current.left;
  60 + } else if (element.compareTo(current.element) > 0) {
  61 + current = current.right;
  62 + } else {
  63 + return false; // Duplicate node not inserted
  64 + }
  65 + }
  66 +
  67 + // Create the new node and attach it to the parent node
  68 + if (element.compareTo(parent.element) < 0) {
  69 + parent.left = createNewNode(element);
  70 + } else {
  71 + parent.right = createNewNode(element);
  72 + }
  73 + }
  74 +
  75 + size++;
  76 + return true; // Element inserted
  77 + }
  78 +
  79 + public boolean delete(E element) {
  80 + if (! search(element)) {
  81 + return false; // Element is not in the tree
  82 + }
  83 +
  84 + // Locate the node to be deleted and also locate its parent node
  85 + TreeNode<E> parent = null;
  86 + TreeNode<E> current = root;
  87 +
  88 + while (current != null) {
  89 + parent = current;
  90 +
  91 + if (element.compareTo(current.element) < 0) {
  92 + current = current.left;
  93 + } else if (element.compareTo(current.element) > 0) {
  94 + current = current.right;
  95 + } else {
  96 + break; // Element is in the tree pointed by current
  97 + }
  98 + }
  99 +
  100 + if (current.left == null) {
  101 + // Case 1: current has no left children
  102 + if (parent == null) { // We delete root, simply replace root with right child
  103 + root = current.right;
  104 + } else { // Connect the parent with the right child
  105 + if (element.compareTo(parent.element) < 0) {
  106 + parent.left = current.right;
  107 + } else {
  108 + parent.right = current.right;
  109 + }
  110 + }
  111 + } else {
  112 + // Case 2: The current node has a left child
  113 + // Locate the rightmost node in the left subtree of
  114 + // the current node and also its parent
  115 + TreeNode<E> parentOfRightMost = current;
  116 + TreeNode<E> rightMost = current.left;
  117 +
  118 + while (rightMost.right != null) {
  119 + parentOfRightMost = rightMost;
  120 + rightMost = rightMost.right; // Keep going to the right
  121 + }
  122 +
  123 + // Replace the element in current by the element in rightMost
  124 + current.element = rightMost.element;
  125 +
  126 + // Eliminate rightmost node
  127 + if (parentOfRightMost.right == rightMost) {
  128 + parentOfRightMost.right = rightMost.left;
  129 + } else { // Special case: parentOfRightMost == current
  130 + parentOfRightMost.left = rightMost.left;
  131 + }
  132 + }
  133 +
  134 + size--;
  135 + return true; // Element removed
  136 + }
  137 +
  138 + public void inOrder() {
  139 + traverse(root, Traversal.IN_ORDER);
  140 + }
  141 +
  142 + public void iterativeInOrder() {
  143 + Stack<TreeNode> nodes = new Stack<>();
  144 + TreeNode<E> current = root;
  145 + while (!nodes.empty() || current!=null){
  146 + if (current!=null) {
  147 + nodes.push(current);
  148 + current = current.left;
  149 + } else {
  150 + current = nodes.pop();
  151 + System.out.print(current.element + " ");
  152 + current = current.right;
  153 + }
  154 + }
  155 + }
  156 +
  157 + public void postOrder() {
  158 + traverse(root, Traversal.POST_ORDER);
  159 + }
  160 +
  161 + public void preOrder() {
  162 + traverse(root, Traversal.PRE_ORDER);
  163 + }
  164 +
  165 + public java.util.Iterator<E> iterator() {
  166 + return new InOrderIterator();
  167 + }
  168 +
  169 + public int getSize() {
  170 + return size;
  171 + }
  172 +
  173 + /////////////////////////////////////////////////////////////////////////////
  174 + // Additional Methods //
  175 + /////////////////////////////////////////////////////////////////////////////
  176 +
  177 + /** Remove all elements from the tree */
  178 + void clear() {
  179 + root = null;
  180 + size = 0;
  181 + }
  182 +
  183 + /**
  184 + * Returns the root of the tree.
  185 + *
  186 + * @return Root node of the tree.
  187 + */
  188 + private TreeNode<E> getRoot() {
  189 + return root;
  190 + }
  191 +
  192 + /**
  193 + * Creates an array list of nodes from root to the given element. List
  194 + * will be empty if the element is not in the tree.
  195 + *
  196 + * @param element Element to which path should be created.
  197 + *
  198 + * @return List of nodes from root to element.
  199 + */
  200 + ArrayList<TreeNode<E>> path(E element) {
  201 + if (! search(element)) {
  202 + return new ArrayList<>();
  203 + }
  204 +
  205 + ArrayList<TreeNode<E>> list = new ArrayList<>();
  206 + TreeNode<E> current = getRoot(); // Start from the root
  207 +
  208 + while (current != null) {
  209 + list.add(current); // Add the node to the list
  210 + if (element.compareTo(current.element) < 0) {
  211 + current = current.left;
  212 + } else if (element.compareTo(current.element) > 0) {
  213 + current = current.right;
  214 + } else {
  215 + break;
  216 + }
  217 + }
  218 +
  219 + return list; // Return an array of nodes
  220 + }
  221 +
  222 + public boolean isPerfect(){
  223 + return Math.pow(2, height()) - 1 == size;
  224 + }
  225 +
  226 + /**
  227 + * Return the height of this binary tree. Height is the number of the nodes in
  228 + * the longest path of the tree.
  229 + *
  230 + * @return Height og tree.
  231 + */
  232 + int height() {
  233 + return height(getRoot());
  234 + }
  235 +
  236 + /**
  237 + * Method for traversing the tree and displaying its nodes in a Depth First
  238 + * manner.
  239 + */
  240 + void depthFirstTraversal() {
  241 + // First add the root to queue
  242 + // While queue is not empty
  243 + // Pop last element from queue.
  244 + // Print the popped element.
  245 + // Add its right and left children to stack.
  246 + traversalHelper(false);
  247 + }
  248 +
  249 + /**
  250 + * Method for traversing the tree and displaying its nodes in a Breadth First
  251 + * manner.
  252 + */
  253 + void breadthFirstTraversal() {
  254 + // First add the root to queue
  255 + // While queue is not empty
  256 + // Pop first element from queue.
  257 + // Print the popped element.
  258 + // Add its right and left children to stack.
  259 + traversalHelper(true);
  260 + }
  261 +
  262 + /////////////////////////////////////////////////////////////////////////////
  263 + // Helper Methods //
  264 + /////////////////////////////////////////////////////////////////////////////
  265 +
  266 + /**
  267 + * Helper method to create a TreeNode for a given element.
  268 + *
  269 + * @param element Element to be put into the TreeNode
  270 + *
  271 + * @return A TreeNode with specified element inside it
  272 + */
  273 + private TreeNode<E> createNewNode(E element) {
  274 + return new TreeNode<>(element);
  275 + }
  276 +
  277 + /**
  278 + * Helper method for general traversal from a subtree.
  279 + *
  280 + * @param node Which node to start traversal from.
  281 + * @param mode Traversal mode, In-oder, Pre-oder or Post-order.
  282 + */
  283 + private void traverse(TreeNode<E> node, Traversal mode) {
  284 + if (node == null) {
  285 + return;
  286 + }
  287 +
  288 + if (mode == Traversal.PRE_ORDER) {
  289 + System.out.print(node.element + " ");
  290 + }
  291 + traverse(node.left, mode);
  292 + if (mode == Traversal.IN_ORDER) {
  293 + System.out.print(node.element + " ");
  294 + }
  295 + traverse(node.right, mode);
  296 + if (mode == Traversal.POST_ORDER) {
  297 + System.out.print(node.element + " ");
  298 + }
  299 + }
  300 +
  301 + /**
  302 + * Helper method for traversing the tree in Breadth Frist and DepthTree manner.
  303 + *
  304 + * @param breadthFirst If true, traverses breadth first, depth first otherwise.
  305 + */
  306 + private void traversalHelper(boolean breadthFirst) {
  307 + if (getRoot() == null) {
  308 + return;
  309 + }
  310 +
  311 + LinkedList<TreeNode<E>> queue = new LinkedList<>();
  312 + TreeNode<E> node;
  313 + queue.add(getRoot());
  314 +
  315 + while (! queue.isEmpty()) {
  316 + node = breadthFirst ? queue.removeFirst() : queue.removeLast();
  317 +
  318 + System.out.print(node.element + " ");
  319 +
  320 + if (node.left != null) {
  321 + queue.add(node.left);
  322 + }
  323 + if (node.right != null) {
  324 + queue.add(node.right);
  325 + }
  326 + }
  327 + }
  328 +
  329 + /**
  330 + * Helper method for the recursive method, hidden as private since it's not
  331 + * meant to be used elsewhere.
  332 + *
  333 + * @param node Which node to count height for.
  334 + *
  335 + * @return Height of tree from given node.
  336 + */
  337 + private int height(TreeNode node) {
  338 + if (node == null) {
  339 + return 0;
  340 + } else {
  341 + return 1 + Math.max(height(node.left), height(node.right));
  342 + }
  343 +
  344 + // Or:
  345 + // return node == null? 0 : 1 + Math.max(height(node.left), height(node.right));
  346 + }
  347 +
  348 +
  349 +
  350 + /////////////////////////////////////////////////////////////////////////////
  351 + // Private Classes //
  352 + /////////////////////////////////////////////////////////////////////////////
  353 +
  354 + class TreeNode<T extends Comparable<T>> {
  355 + T element;
  356 + TreeNode<T> left;
  357 + TreeNode<T> right;
  358 +
  359 + TreeNode(T element) {
  360 + this.element = element;
  361 + }
  362 + }
  363 +
  364 + private class InOrderIterator implements java.util.Iterator<E> {
  365 + // Store the elements in a list
  366 + private ArrayList<E> list = new ArrayList<>();
  367 +
  368 + private int current = 0; // Point to the current element in list
  369 +
  370 + InOrderIterator() {
  371 + inOrder(); // Traverse binary tree and store elements in list
  372 + }
  373 +
  374 + /** In-order traversal from the root */
  375 + private void inOrder() {
  376 + inOrder(getRoot());
  377 + }
  378 +
  379 + /** In-order traversal from a subtree */
  380 + private void inOrder(TreeNode<E> root) {
  381 + if (root == null) {
  382 + return;
  383 + }
  384 + inOrder(root.left);
  385 + list.add(root.element);
  386 + inOrder(root.right);
  387 + }
  388 +
  389 + /** Next element for traversing? */
  390 + public boolean hasNext() {
  391 + return current < list.size();
  392 + }
  393 +
  394 + /** Get the current element and move cursor to the next. */
  395 + public E next() {
  396 + return list.get(current++);
  397 + }
  398 +
  399 + /** Remove the current element and refresh the list. */
  400 + public void remove() {
  401 + delete(list.get(current)); // Delete the current element
  402 + list.clear(); // Clear the list
  403 + inOrder(); // Rebuild the list
  404 + }
  405 + }
  406 +
  407 + private enum Traversal {
  408 + IN_ORDER, POST_ORDER, PRE_ORDER
  409 + }
  410 +}
... ...
src/BinarySearchTreeTest.java 0 → 100644
  1 +++ a/src/BinarySearchTreeTest.java
  1 +import java.util.ArrayList;
  2 +
  3 +public class BinarySearchTreeTest {
  4 + public static void main(String[] args) {
  5 + // Create a BST
  6 + BinarySearchTree<String> tree = new BinarySearchTree<>();
  7 + tree.insert("George");
  8 + tree.insert("Michael");
  9 + tree.insert("Tom");
  10 + tree.insert("Adam");
  11 + tree.insert("Jones");
  12 + tree.insert("Peter");
  13 + tree.insert("Daniel");
  14 +
  15 + // Simple tree traversal
  16 + System.out.println("In-order (sorted): ");
  17 + tree.inOrder();
  18 + System.out.println("\nPost-order: ");
  19 + tree.postOrder();
  20 + System.out.println("\nPre-order: ");
  21 + tree.preOrder();
  22 + System.out.println("\n");
  23 +
  24 + // Advanced tree traversal
  25 + System.out.print("Depth first traversal: ");
  26 + tree.depthFirstTraversal();
  27 + System.out.print("\nBreadth first traversal: ");
  28 + tree.breadthFirstTraversal();
  29 + System.out.println("\n");
  30 +
  31 + // Basic operations
  32 + System.out.printf("The height of tree is: %2d%n", tree.height());
  33 + System.out.printf("The number of nodes is: %2d%n", tree.getSize());
  34 + System.out.printf("Is the tree empty? %s%n", tree.isEmpty() ? "Yes!" : "No!");
  35 + System.out.printf("Is Peter in the tree? %s%n", tree.search("Peter") ? "Yes!" : "No!");
  36 + System.out.printf("Is Clarice in the tree? %s%n%n", tree.search("Clarice") ? "Yes!" : "No!");
  37 +
  38 + // Path method
  39 + System.out.print("A path from the root to Peter is: ");
  40 + ArrayList<BinarySearchTree<String>.TreeNode<String>> path = tree.path("Peter");
  41 + if (! path.isEmpty()) {
  42 + path.forEach((e) -> System.out.print(e.element + " "));
  43 + } else {
  44 + System.out.print("There is no path from root to Peter");
  45 + }
  46 + System.out.print("\nA path from the root to Clarice is: ");
  47 + path = tree.path("Clarice");
  48 + if (! path.isEmpty()) {
  49 + path.forEach((e) -> System.out.println(e.element));
  50 + } else {
  51 + System.out.println("There is no path from root to Clarice");
  52 + }
  53 +
  54 + // Iterating through tree
  55 + System.out.print("\nIterator test: ");
  56 + java.util.Iterator iter = tree.iterator();
  57 + while (iter.hasNext()) {
  58 + System.out.print(iter.next() + " ");
  59 + }
  60 + System.out.print("\nEnhanced for loop: ");
  61 + for (String element : tree) {
  62 + System.out.print(element + " ");
  63 + }
  64 + System.out.print("\nforEach / Lambda: ");
  65 + tree.forEach((e) -> System.out.print(e + " "));
  66 + System.out.println("\n");
  67 +
  68 + // Tree manipulation
  69 + Integer[] numbers = {2, 4, 3, 1, 8, 5, 6, 7};
  70 + BinarySearchTree<Integer> intTree = new BinarySearchTree<>(numbers);
  71 + System.out.print("Tree of numbers: ");
  72 + intTree.inOrder();
  73 + System.out.printf("%nCan insert 1? %s%n", intTree.insert(1) ? "Yes!" : "No!");
  74 + System.out.printf("Can insert 9? %s%n", intTree.insert(9) ? "Yes!" : "No!");
  75 + System.out.printf("Can delete 1? %s%n", intTree.delete(1) ? "Yes!" : "No!");
  76 + System.out.printf("Can delete 10? %s%n", intTree.delete(10) ? "Yes!" : "No!");
  77 + System.out.print("Tree before clearing: ");
  78 + intTree.inOrder();
  79 + System.out.print("\nTree after clearing: ");
  80 + intTree.clear();
  81 + intTree.inOrder();
  82 + System.out.printf("%nIs the tree empty now? %s%n", intTree.isEmpty() ? "Yes!" : "No!");
  83 + }
  84 +}
... ...
src/Main.java 0 → 100644
  1 +++ a/src/Main.java
  1 +public class Main {
  2 +
  3 + public static void main(String[] args) {
  4 +
  5 + BinarySearchTree<Integer> tree = new BinarySearchTree<>();
  6 + tree.insert(2);
  7 + tree.insert(3);
  8 + tree.insert(1);
  9 + System.out.println("Tree is perfect: " + tree.isPerfect());
  10 + tree.insert(4);
  11 + System.out.println("Tree is perfect: " + tree.isPerfect());
  12 + System.out.println("bfs: ");
  13 + tree.breadthFirstTraversal();
  14 + System.out.println();
  15 + System.out.println("dfs: ");
  16 + tree.depthFirstTraversal();
  17 +
  18 +
  19 + BinarySearchTree<Character> tree1 = new BinarySearchTree<>();
  20 + for (Character letter: "ABCDEFGIH".toCharArray()) {
  21 + tree1.insert(letter);
  22 + }
  23 + System.out.println();
  24 + System.out.println("Iterative in order traversal: ");
  25 + tree1.iterativeInOrder();
  26 + System.out.println();
  27 + System.out.println("Recursive in order traversal: ");
  28 + tree1.inOrder();
  29 + }
  30 +
  31 +}
... ...
src/Tree.java 0 → 100644
  1 +++ a/src/Tree.java
  1 +public interface Tree<E extends Comparable<E>> {
  2 + /**
  3 + * Returns true if the element is in the tree.
  4 + *
  5 + * @param element Element to search for.
  6 + *
  7 + * @return True if element is in tree, false otherwise.
  8 + */
  9 + boolean search(E element);
  10 +
  11 + /**
  12 + * Insert element o into the binary tree Return true if the element is
  13 + * inserted successfully
  14 + *
  15 + * @param element Element to be inserted into the tree.
  16 + *
  17 + * @return True if element was unique, false if element was duplicate.
  18 + */
  19 + boolean insert(E element);
  20 +
  21 + /**
  22 + * Delete the specified element from the tree Return true if the element is
  23 + * deleted successfully
  24 + */
  25 + boolean delete(E e);
  26 +
  27 + /** In-order traversal from the root. */
  28 + void inOrder();
  29 +
  30 + /** Post-order traversal from the root. */
  31 + void postOrder();
  32 +
  33 + /** Pre-order traversal from the root. */
  34 + void preOrder();
  35 +
  36 + /**
  37 + * Get the number of nodes in the tree.
  38 + *
  39 + * @return Number of nodes in the tree.
  40 + */
  41 + int getSize();
  42 +
  43 + /**
  44 + * Checks whether the tree is empty or not.
  45 + *
  46 + * @return True if empty, false otherwise.
  47 + */
  48 + boolean isEmpty();
  49 +
  50 + /** Return an iterator to traverse elements in the tree */
  51 + java.util.Iterator<E> iterator();
  52 +}
... ...