diff --git a/Sorts/InsertionSort.java b/Sorts/InsertionSort.java index c77b895f7a9d..fc2f5ac8b03c 100644 --- a/Sorts/InsertionSort.java +++ b/Sorts/InsertionSort.java @@ -1,6 +1,6 @@ /** * - * @author Varun Upadhyay (https://github.com/varunu28) + * @author Shubham Singh (https://github.com/ss3681755) * */ @@ -9,55 +9,27 @@ class InsertionSort { /** * This method implements the Generic Insertion Sort * - * @param array The array to be sorted - * @param last The count of total number of elements in array + * @param initialArray The array to be sorted * Sorts the array in increasing order **/ - public static > void IS(T array[], int last) { - T key; - for (int j=1;j=0 && key.compareTo(array[i]) < 0) { - array[i+1] = array[i]; - i--; - } - // Placing the key (Card) at its correct position in the sorted subarray - array[i+1] = key; - } - } - - // Driver Program - public static void main(String[] args) { - // Integer Input - int[] arr1 = {4,23,6,78,1,54,231,9,12}; - int last = arr1.length; - Integer[] array = new Integer[arr1.length]; - for (int i=0;i> void sort(T[] initialArray) { + for (int index = 1; index < initialArray.length; index++) { - // Output => 1 4 6 9 12 23 54 78 231 - for (int i=0;i= 0 && key.compareTo(initialArray[previousIndex]) <= 0) { + initialArray[previousIndex + 1] = initialArray[previousIndex]; + previousIndex -= 1; + } - IS(array1, last); - - //Output => a b c d e - for(int i=0; i 0; lastSortedIndex--){ - - //If our extracted element is smaller than element to the right, switch them. - if (sortedArray[lastSortedIndex-1] > extractedElement){ - //move the element to the left of extractedElement to the right in sortedArray - sortedArray[lastSortedIndex] = sortedArray[lastSortedIndex-1]; - //And move the current extractedElement to the left one (since it's smaller). - sortedArray[lastSortedIndex-1] = extractedElement; - } - else{ - //insert element where it is. - sortedArray[lastSortedIndex] = extractedElement; - //Terminating loop since element is in the right spot. - break; - } - - } - - } - - return sortedArray; - - } - -} diff --git a/data_structures/Trees/BinarySearchTree.java b/data_structures/Trees/BinarySearchTree.java new file mode 100644 index 000000000000..061df9494803 --- /dev/null +++ b/data_structures/Trees/BinarySearchTree.java @@ -0,0 +1,550 @@ +/** + * This entire class is used to build a Binary Search Tree data structure. + * There is the Node Class and the BinarySearchTree Class, both explained below. + * @author Shubham Singh (ss3681755) + * + **/ + + +class Node> implements Comparable> { + + /* Generic data type T for value of Node. */ + private T value; + /* Left child of node containing generic data type T. */ + private Node left; + /* Right child of node containing generic data type T. */ + private Node right; + /* Parent of node containing generic data type T. */ + private Node parent; + + /** + * + * Class constructor when value of the node is provided. + * + **/ + public Node(T value) { + this(value, null, null, null); + } + + /** + * + * Class constructor when value and parent of the node are provided. + * + **/ + public Node(T value, Node parent) { + this(value, null, null, parent); + } + + /** + * + * Class constructor when value, left and right children of the node are provided. + * + **/ + public Node(T value, Node left, Node right) { + this(value, left, right, null); + } + + /** + * + * Class constructor when every attribute of node is provided. + * + **/ + public Node(T value, Node left, Node right, Node parent) { + this.value = value; + this.left = left; + this.right = right; + this.parent = parent; + } + + /** + * + * Setter method to set the value of Node + * @param value + * + **/ + public void setValue(T value) { + this.value = value; + } + + /** + * + * Getter method to fetch the value of Node + * @return value of the Node + * + **/ + public T getValue() { + return value; + } + + /** + * + * Setter method to set the left child of Node + * @param Left Child + * + **/ + public void setLeft(Node left) { + this.left = left; + } + + /** + * + * Getter method to fetch the left child of Node + * @return Left Child + * + **/ + public Node getLeft() { + return left; + } + + /** + * + * Setter method to set the right child of Node + * @param Right Child + * + **/ + public void setRight(Node right) { + this.right = right; + } + + /** + * + * Getter method to fetch the right child of Node + * @return Right Child + * + **/ + public Node getRight() { + return right; + } + + /** + * + * Setter method to set the parent of Node + * @param Parent Node + * + **/ + public void setParent(Node parent) { + this.parent = parent; + } + + /** + * + * Getter method to fetch the parent of Node + * @return Parent Node + * + **/ + public Node getParent() { + return parent; + } + + /** + * + * This function compares to Node type objects on top + * of the comparators of Primitive type and returns positive + * value if current object is greater than passed one, negative + * if current object is lesser than passed one and 0 if both + * are same. + * @param Node to which comparison will be done + * @return integer value as per rules discussed above. + * + **/ + public int compareTo(Node object) { + return getValue().compareTo(object.getValue()); + } +} + +public class BinarySearchTree> { + + /* Root node of tree containing generic data type T. */ + private Node root; + + /** + * + * Constructor for Tree when nothing is provided. + * + **/ + public BinarySearchTree() { + this(null); + } + + /** + * + * Constructor of Tree when root of Tree is provided. + * + **/ + public BinarySearchTree(Node root) { + this.root = root; + } + + /** + * + * Setter method to set the root of tree. + * @param root of tree + * + **/ + public void setRoot(Node root) { + this.root = root; + } + + /** + * + * Getter method to fetch the root of tree. + * @return root of tree + * + **/ + public Node getRoot() { + return root; + } + + /** + * + * Search for the key provided by user. + * @param Key + * @return Node containing Key if available otherwise null + * + **/ + public Node find(T key) { + + // If tree is empty or key is null + if(key == null || this.root == null) + return null; + + // Otherwise find it in tree + Node keyNode = new Node<>(key); + return find(this.root, keyNode); + } + + /** + * + * Search for the key provided in tree. This function is a + * utility and is not acessible to user as it is private. + * @param Local root of tree + * @param Node containing key value. + * @return Node containing key + * + **/ + private Node find(Node localRoot, Node keyNode) { + + // Return null if tree is empty. + if(localRoot == null) { + return null; + } + + int compareValue = localRoot.compareTo(keyNode); + + if(compareValue > 0) { + // Key < localRoot then search in left subtree. + return find(localRoot.getLeft(), keyNode); + } else if(compareValue < 0) { + // Key > localRoot then search in right subtree. + return find(localRoot.getRight(), keyNode); + } + + // Key == localRoot then return localRoot + return localRoot; + } + + /** + * + * This function returns the possbile Immediate parent of a node for + * a provided key. It is not necessary for key to be present in tree. + * @param Key + * @return Possible immediate parent node of key + * + **/ + public Node findImmediateParent(T key) { + if(this.root == null || key == null) + return null; + + Node keyNode = new Node<>(key); + return findImmediateParent(this.root, keyNode); + } + + /** + * + * Just a utility of function above and is not accessible to user. + * This function returns Possible Immediate parent Node of the key + * if key is as same as root then it returns null. + * @param Local root of a tree. + * @param Node containing key + * @return Possible immediate parent node + * + **/ + private Node findImmediateParent(Node localRoot, Node keyNode) { + // If tree is empty. + if(localRoot == null) + return null; + + int compareValue = localRoot.compareTo(keyNode); + Node ret = null; + + if(compareValue > 0) { + // Key < localRoot search in left subtree. + ret = findImmediateParent(localRoot.getLeft(), keyNode); + // If ret is null means localRoot's left child is either key + // or possibly will be the key is inserted. + ret = ret == null ? localRoot : ret; + } else if(compareValue < 0) { + // Key > localRoot search in right subtree. + ret = findImmediateParent(localRoot.getRight(), keyNode); + // If ret is null means localRoot's right child is either key + // or possibly will be the key is inserted. + ret = ret == null ? localRoot : ret; + } + + // Key == localRoot the return ret as null. + return ret; + } + + /** + * + * This function inserts key into tree if not available. + * Duplicate insertion is not allowed in this tree. + * @param Key + * + **/ + public void put(T key) { + if(key == null) + return ; + + Node keyNode = new Node<>(key); + this.root = put(this.root, keyNode); + } + + /** + * + * This function is a utility of function described above. + * But it is not accessible to user as it is private. + * @param Local root node of tree + * @param Key node + * @return Modified local root node of tree. + * + **/ + private Node put(Node localRoot, Node keyNode) { + // Tree is empty then make Key node as root + if(localRoot == null) { + localRoot = keyNode; + return localRoot; + } + + int compareValue = localRoot.compareTo(keyNode); + + if(compareValue > 0) { + // Key < localRoot then traverse in left subtree./ + localRoot.setLeft(put(localRoot.getLeft(), keyNode)); + // In case localRoot's left child has been modified update + // its parent as localRoot. + localRoot.getLeft().setParent(localRoot); + } else if(compareValue < 0) { + // Key < localRoot then traverse in right subtree./ + localRoot.setRight(put(localRoot.getRight(), keyNode)); + // In case localRoot's right child has been modified update + // its parent as localRoot. + localRoot.getRight().setParent(localRoot); + } + + // Key == localRoot return localRoot. + return localRoot; + } + + /** + * + * This function removes a node containing key provided by user. + * And returns true if successfully deleted otherwise false. + * @param Key + * @return boolean + * + **/ + public boolean remove(T key) { + // If tree is empty or key is null or is not present in tree. + if(this.root == null || key == null || find(key) == null) { + return false; + } + + Node keyNode = new Node<>(key); + this.root = remove(this.root, keyNode); + return true; + } + + /** + * + * This function is a utility to the function described above. + * But this is not acessible to user as it is private. + * @param Local root of tree. + * @param Node containing key. + * @return Modified local root node after deleting key. + * + **/ + private Node remove(Node localRoot, Node keyNode) { + + int compareValue = localRoot.compareTo(keyNode); + + if(compareValue > 0) { + // Key < localRoot then traverse left subtree. + localRoot.setLeft(remove(localRoot.getLeft(), keyNode)); + // Now get Modified left child of localRoot. + Node left = localRoot.getLeft(); + // If left child is not null then update its parent as localRoot. + if(left != null) + left.setParent(localRoot); + } else if(compareValue < 0) { + // Key < localRoot then traverse right subtree. + localRoot.setRight(remove(localRoot.getRight(), keyNode)); + // Now get Modified right child of localRoot. + Node right = localRoot.getLeft(); + // If right child is not null then update its parent as localRoot. + if(right != null) + right.setParent(localRoot); + } else { + // Key == localRoot then process deleting node. + + if(localRoot.getRight() == null) { + // If right child of root is null then assign its left child. + localRoot = localRoot.getLeft(); + } else if(localRoot.getLeft() == null) { + // If left child of root is null then assign its right child. + localRoot = localRoot.getRight(); + } else { + // None of the children is null then find out inorder predecessor + // of the node localRoot in its left Subtree. + Node maxValNode = maxValueNode(localRoot.getLeft()); + // Copy value of inorder predecessor to localRoot + localRoot.setValue(maxValNode.getValue()); + // After that remove inorder predecessor from its left subtree. + // And update the localRoot's left child. + localRoot.setLeft(remove(localRoot.getLeft(), maxValNode)); + // Now get the updated left child of localRoot. + maxValNode = localRoot.getLeft(); + // If left child is not null the update its parent as localRoot. + if(maxValNode != null) + maxValNode.setParent(localRoot); + } + } + return localRoot; + } + + /** + * + * This function returns a node containing maximum value in tree. + * If tree is empty then null. + * @param localRoot of tree. + * @return Node containing maximum value. + * + **/ + public Node maxValueNode(Node localRoot) { + if(localRoot != null) { + Node ret = maxValueNode(localRoot.getRight()); + ret = ret == null ? localRoot : ret; + return ret; + } + return localRoot; + } + + /** + * + * This function returns a node containing minimum value in tree. + * If tree is empty then null. + * @param localRoot of tree. + * @return Node containing minimum value. + * + **/ + public Node minValueNode(Node localRoot) { + if(localRoot != null) { + Node ret = minValueNode(localRoot.getLeft()); + ret = ret == null ? localRoot : ret; + } + return localRoot; + } + + /** + * + * This function prints the inorder traversal of tree. + * + **/ + public void inOrderTraversal() { + inOrderTraversal(this.root); + System.out.println(); + } + + /** + * + * This is a utility to function described above. + * It is not accessible by user as it is private. + * @param Local root of tree. + * + **/ + private void inOrderTraversal(Node localRoot) { + if(localRoot == null) { + return ; + } + + inOrderTraversal(localRoot.getLeft()); + System.out.print(localRoot.getValue().toString() + " "); + inOrderTraversal(localRoot.getRight()); + } + + /** + * + * This function prints the preorder traversal of tree. + * + **/ + public void preOrderTraversal() { + preOrderTraversal(this.root); + System.out.println(); + } + + /** + * + * This is a utility to function described above. + * It is not accessible by user as it is private. + * @param Local root of tree. + * + **/ + private void preOrderTraversal(Node localRoot) { + if(localRoot == null) { + return ; + } + + System.out.print(localRoot.getValue().toString() + " "); + preOrderTraversal(localRoot.getLeft()); + preOrderTraversal(localRoot.getRight()); + } + + /** + * + * This function prints the postorder traversal of tree. + * + **/ + public void postOrderTraversal() { + postOrderTraversal(this.root); + System.out.println(); + } + + /** + * + * This is a utility to function described above. + * It is not accessible by user as it is private. + * @param Local root of tree. + * + **/ + private void postOrderTraversal(Node localRoot) { + if(localRoot == null) + return ; + + postOrderTraversal(localRoot.getLeft()); + postOrderTraversal(localRoot.getRight()); + System.out.print(localRoot.getValue().toString() + " "); + } + + /* Driver Program to test class.*/ + /* + public static void main(String[] args) { + BinarySearchTree tree = new BinarySearchTree<>(); + tree.put(10); + tree.put(4); tree.put(1); tree.put(7); + tree.put(16); tree.put(13); tree.put(19); + tree.inOrderTraversal(); + tree.remove(10); + tree.inOrderTraversal(); + } + */ +} \ No newline at end of file diff --git a/data_structures/Trees/BinaryTree.java b/data_structures/Trees/BinaryTree.java deleted file mode 100644 index a20d24eebc35..000000000000 --- a/data_structures/Trees/BinaryTree.java +++ /dev/null @@ -1,268 +0,0 @@ -/** -* This entire class is used to build a Binary Tree data structure. -* There is the Node Class and the Tree Class, both explained below. -* -* @author Unknown -* -*/ - - -/** -* This class implements the nodes that will go on the Binary Tree. -* They consist of the data in them, the node to the left, the node -* to the right, and the parent from which they came from. -* -* @author Unknown -* -*/ -class Node{ - /** Data for the node */ - public int data; - /** The Node to the left of this one */ - public Node left; - /** The Node to the right of this one */ - public Node right; - /** The parent of this node */ - public Node parent; - - /** - * Constructor of Node - * - * @param value Value to put in the node - */ - public Node(int value){ - data = value; - left = null; - right = null; - parent = null; - } -} - - -/** -* A binary tree is a data structure in which an element -* has two successors(children). The left child is usually -* smaller than the parent, and the right child is usually -* bigger. -* -* @author Unknown -* -*/ -class Tree{ - /** The root of the Binary Tree */ - private Node root; - - /** - * Constructor - */ - public Tree(){ - root = null; - } - - /** - * Method to find a Node with a certain value - * - * @param key Value being looked for - * @return The node if it finds it, otherwise returns the parent - */ - public Node find(int key) { - Node current = root; - while (current != null) { - if(key < current.data) { - current = current.left; - } else if(key > current.data) { - current = current.right; - } else { // If you find the value return it - return current; - } - } - return null; - } - - /** - * Inserts certain value into the Binary Tree - * - * @param value Value to be inserted - */ - public void put(int value){ - Node newNode = new Node(value); - if(root == null) - root = newNode; - else{ - //This will return the soon to be parent of the value you're inserting - Node parent = find(value); - - //This if/else assigns the new node to be either the left or right child of the parent - if(value < parent.data){ - parent.left = newNode; - parent.left.parent = parent; - return; - } - else{ - parent.right = newNode; - parent.right.parent = parent; - return; - } - } - } - - /** - * Deletes a given value from the Binary Tree - * - * @param value Value to be deleted - * @return If the value was deleted - */ - public boolean remove(int value){ - //temp is the node to be deleted - Node temp = find(value); - - //If the value doesn't exist - if(temp.data != value) - return false; - - //No children - if(temp.right == null && temp.left == null){ - if(temp == root) - root = null; - - //This if/else assigns the new node to be either the left or right child of the parent - else if(temp.parent.data < temp.data) - temp.parent.right = null; - else - temp.parent.left = null; - return true; - } - - //Two children - else if(temp.left != null && temp.right != null){ - Node successor = findSuccessor(temp); - - //The left tree of temp is made the left tree of the successor - successor.left = temp.left; - successor.left.parent = successor; - - //If the successor has a right child, the child's grandparent is it's new parent - if(successor.right != null && successor.parent != temp){ - successor.right.parent = successor.parent; - successor.parent.left = successor.right; - successor.right = temp.right; - successor.right.parent = successor; - } - if(temp == root){ - successor.parent = null; - root = successor; - return true; - } - - //If you're not deleting the root - else{ - successor.parent = temp.parent; - - //This if/else assigns the new node to be either the left or right child of the parent - if(temp.parent.data < temp.data) - temp.parent.right = successor; - else - temp.parent.left = successor; - return true; - } - } - //One child - else{ - //If it has a right child - if(temp.right != null){ - if(temp == root){ - root = temp.right; return true;} - - temp.right.parent = temp.parent; - - //Assigns temp to left or right child - if(temp.data < temp.parent.data) - temp.parent.left = temp.right; - else - temp.parent.right = temp.right; - return true; - } - //If it has a left child - else{ - if(temp == root){ - root = temp.left; return true;} - - temp.left.parent = temp.parent; - - //Assigns temp to left or right side - if(temp.data < temp.parent.data) - temp.parent.left = temp.left; - else - temp.parent.right = temp.left; - return true; - } - } - } - - /** - * This method finds the Successor to the Node given. - * Move right once and go left down the tree as far as you can - * - * @param n Node that you want to find the Successor of - * @return The Successor of the node - */ - public Node findSuccessor(Node n){ - if(n.right == null) - return n; - Node current = n.right; - Node parent = n.right; - while(current != null){ - parent = current; - current = current.left; - } - return parent; - } - - /** - * Returns the root of the Binary Tree - * - * @return the root of the Binary Tree - */ - public Node getRoot(){ - return root; - } - - /** - * Prints leftChild - root - rightChild - * - * @param localRoot The local root of the binary tree - */ - public void inOrder(Node localRoot){ - if(localRoot != null){ - inOrder(localRoot.left); - System.out.print(localRoot.data + " "); - inOrder(localRoot.right); - } - } - - /** - * Prints root - leftChild - rightChild - * - * @param localRoot The local root of the binary tree - */ - public void preOrder(Node localRoot){ - if(localRoot != null){ - System.out.print(localRoot.data + " "); - preOrder(localRoot.left); - preOrder(localRoot.right); - } - } - - /** - * Prints rightChild - leftChild - root - * - * @param localRoot The local root of the binary tree - */ - public void postOrder(Node localRoot){ - if(localRoot != null){ - postOrder(localRoot.left); - postOrder(localRoot.right); - System.out.print(localRoot.data + " "); - } - } - }