diff --git a/C++/Binary Tree.cpp b/C++/Binary Tree.cpp new file mode 100644 index 0000000..45c1fbd --- /dev/null +++ b/C++/Binary Tree.cpp @@ -0,0 +1,783 @@ + +/* Binary Tree */ + +#include +#include +#include +#include +using namespace std; + +struct Tree +{ + char data; + Tree *left; + Tree *right; + Tree *parent; +}; + +Tree* lookUp(struct Tree *node, char key) +{ + if(node == NULL) return node; + + if(node->data == key) return node; + else { + if(node->data < key) + return lookUp(node->right, key) ; + else + return lookUp(node->left, key); + } +} + +Tree* leftMost(struct Tree *node) +{ + if(node == NULL) return NULL; + while(node->left != NULL) + node = node->left; + return node; +} + +struct Tree *newTreeNode(int data) +{ + Tree *node = new Tree; + node->data = data; + node->left = NULL; + node->right = NULL; + node->parent = NULL; + + return node; +} + +struct Tree* insertTreeNode(struct Tree *node, int data) +{ + static Tree *p; + Tree *retNode; + + //if(node != NULL) p = node; + + if(node == NULL) { + retNode = newTreeNode(data); + retNode->parent = p; + return retNode; + } + if(data <= node->data ) { + p = node; + node->left = insertTreeNode(node->left,data); + } + else { + p = node; + node->right = insertTreeNode(node->right,data); + } + return node; +} + +void isBST(struct Tree *node) +{ + static int lastData = INT_MIN; + if(node == NULL) return; + + isBST(node->left); + + /* check if the given tree is BST */ + if(lastData < node->data) + lastData = node->data; + else { + cout << "Not a BST" << endl; + return; + } + + isBST(node->right); + return; +} + +int treeSize(struct Tree *node) +{ + if(node == NULL) return 0; + else + return treeSize(node->left) + 1 + treeSize(node->right); +} + +int maxDepth(struct Tree *node) +{ + if(node == NULL || (node->left == NULL && node->right == NULL)) + return 0; + + int leftDepth = maxDepth(node->left); + int rightDepth = maxDepth(node->right); + + return leftDepth > rightDepth ? + leftDepth + 1 : rightDepth + 1; +} + +int minDepth(struct Tree *node) +{ + if(node == NULL || (node->left == NULL && node->right == NULL)) + return 0; + + int leftDepth = minDepth(node->left); + int rightDepth = minDepth(node->right); + + return leftDepth < rightDepth ? + leftDepth + 1 : rightDepth + 1; +} + +bool isBalanced(struct Tree *node) +{ + if(maxDepth(node)-minDepth(node) <= 1) + return true; + else + return false; +} + +/* Tree Minimum */ +Tree* minTree(struct Tree *node) +{ + if(node == NULL) return NULL; + while(node->left) + node = node -> left; + return node; +} + +/* Tree Maximum */ +Tree* maxTree(struct Tree *node) +{ + while(node->right) + node = node -> right; + return node; +} + +/* In Order Successor - a node which has the next higher key */ +Tree *succesorInOrder(struct Tree *node) +{ + /* if the node has right child, seccessor is Tree-Minimum */ + if(node->right != NULL) return minTree(node->right); + + Tree *y = node->parent; + while(y != NULL && node == y->right) { + node = y; + y = y->parent; + } + return y; +} + +/* In Order Predecessor - a node which has the next lower key */ +Tree *predecessorInOrder(struct Tree *node) +{ + /* if the node has left child, predecessor is Tree-Maximum */ + if(node->left != NULL) return maxTree(node->left); + + Tree *y = node->parent; + /* if it does not have a left child, + predecessor is its first left ancestor */ + while(y != NULL && node == y->left) { + node = y; + y = y->parent; + } + return y; +} + +void reverseOrderPrint(struct Tree *node) +{ + if(node == NULL) return; + if(node->left == NULL && node->right == NULL) { + cout << node->data << " "; + return; + } + + reverseOrderPrint(node->right); + cout << node->data << " "; + reverseOrderPrint(node->left); +} + +Tree *lowestCommonAncestor(Tree *node, Tree *p, Tree *q) +{ + Tree *left, *right; + if(node == NULL) return NULL; + if(node->left == p || node->left == q + || node->right == p || node->right == q) return node; + + left = lowestCommonAncestor(node->left,p,q); + right = lowestCommonAncestor(node->right, p,q); + if(left && right) + return node; + else + return (left) ? left : right; +} + +void clear(struct Tree *node) +{ + if(node != NULL) { + clear(node->left); + clear(node->right); + delete node; + } +} +/* print tree in order */ +/* 1. Traverse the left subtree. + 2. Visit the root. + 3. Traverse the right subtree. +*/ + +void printTreeInOrder(struct Tree *node) +{ + if(node == NULL) return; + + printTreeInOrder(node->left); + cout << node->data << " "; + printTreeInOrder(node->right); +} + +/* print tree in postorder*/ +/* 1. Traverse the left subtree. + 2. Traverse the right subtree. + 3. Visit the root. +*/ +void printTreePostOrder(struct Tree *node) +{ + if(node == NULL) return; + + printTreePostOrder(node->left); + printTreePostOrder(node->right); + cout << node->data << " "; +} + +/* print in preorder */ +/* 1. Visit the root. + 2. Traverse the left subtree. + 3. Traverse the right subtree. +*/ +void printTreePreOrder(struct Tree *node) +{ + if(node == NULL) return; + + cout << node->data << " "; + printTreePreOrder(node->left); + printTreePreOrder(node->right); +} + +/* In reverse of printTreeInOrder() */ +void printTreeReverseOrder(struct Tree *node) +{ + if(node == NULL) return; + if(node->left == NULL && node->right == NULL) { + cout << node->data << " "; + return; + } + + printTreeReverseOrder(node->right); + cout << node->data << " "; + printTreeReverseOrder(node->left); +} +/* recursion routine to find path */ +void pathFinder(struct Tree *node, int path[], int level) +{ + if(node == NULL) return; + // save leaf node + if(node->left == NULL && node->right == NULL) { + path[level] = node->data; + for(int i = 0; i <= level; i++) { + cout << (char)path[i]; + } + cout << endl; + return; + } + // save parent node + path[level] = node->data; + pathFinder(node->left, path, level+1); + pathFinder(node->right, path, level+1); +} + +bool matchTree(Tree *r1, Tree *r2) +{ + /* Nothing left in the subtree */ + if(r1 == NULL && r2 == NULL) + return true; + /* Big tree empty and subtree not found */ + if(r1 == NULL || r2 == NULL) + return false; + /* Not matching */ + if(r1->data != r2->data) + return false; + return (matchTree(r1->left, r2->left) && + matchTree(r1->right, r2->right)); +} + +bool subTree(Tree *r1, Tree *r2) +{ + /*Big tree empty and subtree not found */ + if(r1 == NULL) + return false; + if(r1->data == r2->data) + if(matchTree(r1, r2)) return true; + return + (subTree(r1->left, r2) || subTree(r1->right, r2)); +} + +bool isSubTree(Tree *r1, Tree *r2) +{ + /* Empty tree is subtree */ + if(r2 == NULL) + return true; + else + return subTree(r1, r2); +} + +/* change a tree so that the roles of the left +and right hand pointers are swapped at every node */ +void mirror(Tree *r) +{ + if(r == NULL) return; + + Tree *tmp; + mirror(r->left); + mirror(r->right); + + /* swap pointers */ + tmp = r->right; + r->right = r->left; + r->left = tmp; +} + +/* create a new tree from a sorted array */ +Tree *addToBST(char arr[], int start, int end) +{ + if(end < start) return NULL; + int mid = (start + end)/2; + + Tree *r = new Tree; + r->data = arr[mid]; + r->left = addToBST(arr, start, mid-1); + r->right = addToBST(arr, mid+1, end); + return r; +} + +Tree *createMinimalBST(char arr[], int size) +{ + return addToBST(arr,0,size-1); +} + +/* Breadth first traversal using queue */ +void BreadthFirstTraversal(Tree *root) +{ + if (root == NULL) return; + deque queue; + queue.push_back(root); + + while (!queue.empty()) { + Tree *p = queue.front(); + cout << p->data << " "; + queue.pop_front(); + + if (p->left != NULL) + queue.push_back(p->left); + if (p->right != NULL) + queue.push_back(p->right); + } + cout << endl; +} + +/* get the level of a node element: root level = 0 */ +int getLevel(struct Tree *node, int elm, int level) +{ + if(node == NULL) return 0; + if(elm == node->data) + return level; + else if(elm < node->data) + return getLevel(node->left, elm, level+1); + else + return getLevel(node->right, elm, level+1); +} + +/* This code prints out all nodes at the same depth (level) */ +void BreadthFirst_LevelElement_Print + (struct Tree *root, vector > &v;) +{ + if(root == NULL) return; + deque q; + q.push_back(root); + while(!q.empty()) { + Tree *p = q.front(); + int lev = getLevel(root, p->data, 0); + v[lev].push_back(p->data); + q.pop_front(); + if(p->left) q.push_back(p->left); + if(p->right)q.push_back(p->right); + } + return; +} + +/* levelPrint() +prints nodes at the same level +This is simpler than the BreadthFirstTraversal(root) above +It takes 2D vector with the same size of level (= MaxDepth+1) +and fills elements as we traverse (preOrder) */ + +void levelPrint(struct Tree *node, vector >&elm;, int level) +{ + if(node == NULL) return; + // leaf nodes + if(node->left == NULL && node->right == NULL) { + elm[level].push_back(node->data); + return; + } + // other nodes + elm[level++].push_back(node->data); + levelPrint(node->left, elm, level); + levelPrint(node->right, elm, level); +} + +/* find n-th max node from a tree */ +void NthMax(struct Tree* t) +{ + static int n_th_max = 5; + static int num = 0; + if(t == NULL) return; + NthMax(t->right); + num++; + if(num == n_th_max) + cout << n_th_max << "-th maximum data is " + << t->data << endl; + NthMax(t->left); +} + +/* Converting a BST into an Array */ +void TreeToArray(struct Tree *node, int a[]){ + static int pos = 0; + + if(node){ + TreeToArray(node->left,a); + a[pos++] = node->data; + TreeToArray(node->right,a); + } +} + +/* Separate even/odd level elements */ +/* This function is using BFS */ +void level_even_odd(struct Tree *node) +{ + vector evenVec, oddVec; + if (node == NULL) return; + deque que; + que.push_back(node); + + while(!que.empty()) + { + struct Tree *p = que.front(); + int level = getLevel(node, p->data, 0) ; + // even level + if (level % 2 == 0) + evenVec.push_back(p->data); + else + oddVec.push_back(p->data); + que.pop_front(); + if(p->left) que.push_back(p->left); + if(p->right) que.push_back(p->right); + } + + cout << "even level elements : "; + for(int i = 0; i < evenVec.size(); i++) + cout << evenVec[i] << " "; + cout << endl << "odd level elements : "; + for(int i = 0; i < oddVec.size(); i++) + cout << oddVec[i] << " "; + cout << endl; +} + +int main(int argc, char **argv) +{ + char ch, ch1, ch2; + Tree *found; + Tree *succ; + Tree *pred; + Tree *ancestor; + char charArr[9] + = {'A','B','C','D','E','F','G','H','I'}; + + Tree *root = newTreeNode('F'); + insertTreeNode(root,'B'); + insertTreeNode(root,'A'); + insertTreeNode(root,'D'); + insertTreeNode(root,'C'); + insertTreeNode(root,'E'); + insertTreeNode(root,'G'); + insertTreeNode(root,'I'); + insertTreeNode(root,'H'); + + /* is the tree BST? */ + isBST(root); + + /* size of tree */ + cout << "size = " << treeSize(root) << endl; + + /* max depth */ + cout << "max depth = " << maxDepth(root) << endl; + + /* min depth */ + cout << "min depth = " << minDepth(root) << endl; + + /* balanced tree? */ + if(isBalanced(root)) + cout << "This tree is balanced!\n"; + else + cout << "This tree is not balanced!\n"; + + /* min value of the tree*/ + if(root) + cout << "Min value = " << minTree(root)->data << endl; + + /* max value of the tree*/ + if(root) + cout << "Max value = " << maxTree(root)->data << endl; + + /* get the level of a data: root level = 0 */ + cout << "Node B is at level: " << getLevel(root, 'B', 0) << endl; + cout << "Node H is at level: " << getLevel(root, 'H', 0) << endl; + cout << "Node F is at level: " << getLevel(root, 'F', 0) << endl; + + /* separate even/odd level elements */ + level_even_odd(root); + + ch = 'B'; + found = lookUp(root,ch); + if(found) { + cout << "Min value of subtree " << ch << " as a root is " + << minTree(found)->data << endl; + cout << "Max value of subtree " << ch << " as a root is " + << maxTree(found)->data << endl; + } + + ch = 'B'; + found = lookUp(root,ch); + if(found) { + succ = succesorInOrder(found); + if(succ) + cout << "In Order Successor of " << ch << " is " + << succesorInOrder(found)->data << endl; + else + cout << "In Order Successor of " << ch << " is None\n"; + } + + ch = 'E'; + found = lookUp(root,ch); + if(found) { + succ = succesorInOrder(found); + if(succ) + cout << "In Order Successor of " << ch << " is " + << succesorInOrder(found)->data << endl; + else + cout << "In Order Successor of " << ch << " is None\n"; + } + + ch = 'I'; + found = lookUp(root,ch); + if(found) { + succ = succesorInOrder(found); + if(succ) + cout << "In Order Successor of " << ch << " is " + << succesorInOrder(found)->data << endl; + else + cout << "In Order Successor of " << ch << " is None\n"; + } + + ch = 'B'; + found = lookUp(root,ch); + if(found) { + pred = predecessorInOrder(found); + if(pred) + cout << "In Order Predecessor of " << ch << " is " + << predecessorInOrder(found)->data << endl; + else + cout << "In Order Predecessor of " << ch << " is None\n"; + } + + ch = 'E'; + found = lookUp(root,ch); + if(found) { + pred = predecessorInOrder(found); + if(pred) + cout << "In Order Predecessor of " << ch << " is " + << predecessorInOrder(found)->data << endl; + else + cout << "In Order Predecessor of " << ch << " is None\n"; + } + + ch = 'I'; + found = lookUp(root,ch); + if(found) { + pred = predecessorInOrder(found); + if(pred) + cout << "In Order Predecessor of " << ch << " is " + << predecessorInOrder(found)->data << endl; + else + cout << "In Order Predecessor of " << ch << " is None\n"; + } + + /* Lowest Common Ancestor */ + ch1 = 'A'; + ch2 = 'C'; + ancestor = + lowestCommonAncestor(root, + lookUp(root,ch1), lookUp(root,ch2)); + if(ancestor) + cout << "The lowest common ancestor of " << ch1 << " and " + << ch2 << " is " << ancestor->data << endl; + + ch1 = 'E'; + ch2 = 'H'; + ancestor = + lowestCommonAncestor(root, + lookUp(root,ch1), lookUp(root,ch2)); + if(ancestor) + cout << "The lowest common ancestor of " << ch1 << " and " + << ch2 << " is " << ancestor->data << endl; + + ch1 = 'D'; + ch2 = 'E'; + ancestor = + lowestCommonAncestor(root, + lookUp(root,ch1), lookUp(root,ch2)); + if(ancestor) + cout << "The lowest common ancestor of " << ch1 << " and " + << ch2 << " is " << ancestor->data << endl; + + ch1 = 'G'; + ch2 = 'I'; + ancestor = + lowestCommonAncestor(root, + lookUp(root,ch1), lookUp(root,ch2)); + if(ancestor) + cout << "The lowest common ancestor of " << ch1 << " and " + << ch2 << " is " << ancestor->data << endl; + + ch1 = 'H'; + ch2 = 'I'; + ancestor = + lowestCommonAncestor(root, + lookUp(root,ch1), lookUp(root,ch2)); + if(ancestor) + cout << "The lowest common ancestor of " << ch1 << " and " + << ch2 << " is " << ancestor->data << endl; + + /* print tree in order */ + cout << "increasing sort order\n"; + printTreeInOrder(root); + cout << endl; + + /* print tree in postorder*/ + cout << "post order \n"; + printTreePostOrder(root); + cout << endl; + + /* print tree in preorder*/ + cout << "pre order \n"; + printTreePreOrder(root); + cout << endl; + + /* print tree in reverse order*/ + cout << "reverse order \n"; + printTreeReverseOrder(root); + cout << endl; + + /* lookUp */ + ch = 'D'; + found = lookUp(root,ch); + if(found) + cout << found->data << " is in the tree\n"; + else + cout << ch << " is not in the tree\n"; + + /* lookUp */ + ch = 'M'; + found = lookUp(root,ch); + if(found) + cout << found->data << " is in the tree\n"; + else + cout << ch << " is not in the tree\n"; + + /* printing all paths : + Given a binary tree, print out all of its root-to-leaf + paths, one per line. Uses a recursive helper to do the work. */ + cout << "printing paths ..." << endl; + int path[10]; + pathFinder(root, path, 0); + + /* find n-th maximum node */ + NthMax(root); + + /* Traversing level-order. + We visit every node on a level before going to a lower level. + This is also called Breadth-first traversal.*/ + cout << "printing with Breadth-first traversal" << endl; + BreadthFirstTraversal(root); + + /* Prints all element at the same depth (level) */ + int row = maxDepth(root); + vector > levVec(row+1); + BreadthFirst_LevelElement_Print(root, levVec); + for(int m = 0; m < levVec.size(); m++) { + cout << "Level at " << m << ": "; + for(int n = 0; n < levVec[m].size(); n++) + cout << (char)levVec[m][n] << " "; + cout << endl; + } + + /* levelPrint() + prints nodes at the same level + This is simpler than the BreadthFirstTraversal(root) above + It takes 2D vector (elm) with the same size of level (= MaxDepth+1) + and fills elements as we traverse (preOrder) */ + vector > elm; + int mxDepth = maxDepth(root); + elm.resize(mxDepth+1); + int level = 0; + levelPrint(root, elm, level); + cout << "levelPrint() " << endl; + for(int i = 0; i <= mxDepth; i++) { + cout << "level " << i << ": " ; + for(int j = 0; j < elm[i].size(); j++) + cout << elm[i][j] << " "; + cout << endl; + } + + /* convert the tree into an array */ + int treeSz = treeSize(root); + int *array = new int[treeSz]; + TreeToArray(root,array); + cout << "New array: "; + for (int i = 0; i < treeSz; i++) + cout << (char)array[i] << ' '; + cout << endl; + delete [] array; + + /* subtree */ + Tree *root2 = newTreeNode('D'); + insertTreeNode(root2,'C'); + insertTreeNode(root2,'E'); + cout << "1-2 subtree: " << isSubTree(root, root2) << endl; + + Tree *root3 = newTreeNode('B'); + insertTreeNode(root3,'A'); + insertTreeNode(root3,'D'); + insertTreeNode(root3,'C'); + insertTreeNode(root3,'E'); + cout << "1-3 subtree: " << isSubTree(root, root3) << endl; + + Tree *root4 = newTreeNode('B'); + insertTreeNode(root4,'D'); + insertTreeNode(root4,'C'); + insertTreeNode(root4,'E'); + cout << "1-4 subtree: " << isSubTree(root, root4) << endl; + + cout << "2-3 subtree: " << isSubTree(root2, root3) << endl; + cout << "3-2 subtree: " << isSubTree(root3, root2) << endl; + + /* swap left and right */ + mirror(root); + + /* deleting a tree */ + clear(root); + + /* make a new tree with minimal depth */ + Tree *newRoot = createMinimalBST(charArr,9); + + return 0; +} \ No newline at end of file diff --git a/C++/Bubble_Sort.cpp b/C++/Bubble_Sort.cpp deleted file mode 100644 index 37f44ba..0000000 --- a/C++/Bubble_Sort.cpp +++ /dev/null @@ -1,33 +0,0 @@ -using namespace std; - -int main() -{ - int n, i, j, temp; - cout << "Enter the number of elements" << endl; - cin >> n; - int arr[n]; - for (i = 0; i < n; i++) - { - cout << "Enter " << i + 1 << " th element"; - cin >> arr[i]; - } - - for (i = n; i > 0; i--) - { - for (j = 0; j < i - 1; j++) - { - if (arr[j] > arr[j + 1]) - { - temp = arr[j]; - arr[j] = arr[j + 1]; - arr[j + 1] = temp; - } - } - } - cout << "\nSorted Elements are\n"; - for (i = 0; i < n; i++) - { - cout << arr[i] << " "; - } - return 0; -} diff --git a/C++/bubble_sort.cpp b/C++/bubble_sort.cpp deleted file mode 100644 index 831572c..0000000 --- a/C++/bubble_sort.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include -using namespace std; -void swapping(int &a, int &b) { //swap the content of a and b - int temp; - temp = a; - a = b; - b = temp; -} -void display(int *array, int size) { - for(int i = 0; i array[j+1]) { //when the current item is bigger than next - swapping(array[j], array[j+1]); - swaps = 1; //set swap flag - } - } - if(!swaps) - break; // No swap in this pass, so array is sorted - } -} -int main() { - int n; - cout << "Enter the number of elements: "; - cin >> n; - int arr[n]; //create an array with given number of elements - cout << "Enter elements:" << endl; - for(int i = 0; i> arr[i]; - } - cout << "Array before Sorting: "; - display(arr, n); - bubbleSort(arr, n); - cout << "Array after Sorting: "; - display(arr, n); -} \ No newline at end of file