Showing posts with label Trees. Show all posts
Showing posts with label Trees. Show all posts

Wednesday, 20 January 2016

Binary Tree Implementation : Basic and Advanced Operation

Binary Trees

Introduction

We extend the concept of linked data structures to structure containing nodes with more than one self-referenced field. A binary tree is made of nodes, where each node contains a "left" reference, a "right" reference, and a data element. The topmost node in the tree is called the root.Every node (excluding a root) in a tree is connected by a directed edge from exactly one other node. This node is called a parent. On the other hand, each node can be connected to arbitrary number of nodes, called children. Nodes with no children are called leaves, or external nodes. Nodes which are not leaves are called internal nodes. Nodes with the same parent are called siblings.  
More tree terminology:
  • The depth of a node is the number of edges from the root to the node.
  • The height of a node is the number of edges from the node to the deepest leaf.
  • The height of a tree is a height of the root.
  • A full binary tree.is a binary tree in which each node has exactly zero or two children.
  • A complete binary tree is a binary tree, which is completely filled, with the possible exception of the bottom level, which is filled from left to right.
A complete binary tree is very special tree, it provides the best possible ratio between the number of nodes and the height. The height h of a complete binary tree with N nodes is at most O(log N). We can easily prove this by counting nodes on each level, starting with the root, assuming that each level has the maximum number of nodes:





n = 1 + 2 + 4 + ... + 2h-1 + 2h = 2h+1 - 1
Solving this with respect to h, we obtain





h = O(log n)
where the big-O notation hides some superfluous details.

Advantages of trees

Trees are so useful and frequently used, because they have some very serious advantages:
  • Trees reflect structural relationships in the data
  • Trees are used to represent hierarchies
  • Trees provide an efficient insertion and searching
  • Trees are very flexible data, allowing to move subtrees around with minumum effort

Traversals

A traversal is a process that visits all the nodes in the tree. Since a tree is a nonlinear data structure, there is no unique traversal. We will consider several traversal algorithms with we group in the following two kinds
  • depth-first traversal
  • breadth-first traversal
There are three different types of depth-first traversals, :
  • PreOrder traversal - visit the parent first and then left and right children;
  • InOrder traversal - visit the left child, then the parent and the right child;
  • PostOrder traversal - visit left child, then the right child and then the parent;
There is only one kind of breadth-first traversal--the level order traversal. This traversal visits nodes by levels from top to bottom and from left to right.
As an example consider the following tree and its four traversals:

PreOrder - 8, 5, 9, 7, 1, 12, 2, 4, 11, 3
InOrder - 9, 5, 1, 7, 2, 12, 8, 4, 3, 11
PostOrder - 9, 1, 2, 12, 7, 5, 3, 11, 4, 8
LevelOrder - 8, 5, 4, 9, 7, 11, 1, 12, 3, 2
    
In the next picture we demonstarte the order of node visitation. Number 1 denote the first node in a particular traversal and 7 denote the last node.
These common traversals can be represented as a single algorithm by assuming that we visit each node three times. An Euler tour is a walk around the binary tree where each edge is treated as a wall, which you cannot cross. In this walk each node will be visited either on the left, or under the below, or on the right. The Euler tour in which we visit nodes on the left produces a preorder traversal. When we visit nodes from the below, we get an inorder traversal. And when we visit nodes on the right, we get a postorder traversal.

1:  package com.examples.ajay;  
2:  import java.util.ArrayDeque;  
3:  import java.util.ArrayList;  
4:  import java.util.List;  
5:  import java.util.Queue;  
6:  import java.util.Stack;  
7:  import org.w3c.dom.ls.LSInput;  
8:  class Node{  
9:       int data;  
10:       Node left;  
11:       Node right;  
12:  }  
13:  class Item{  
14:       int data;  
15:       int level;  
16:  }  
17:  class Height{  
18:       int data;  
19:  }  
20:  public class BinaryTreeImplementation {  
21:       private static int count = 0;  
22:       private static int preOrderIndex = 0;  
23:       public static int max(int i, int j) {  
24:            if(i < j) return j;  
25:            else return i;  
26:       }  
27:       public static void preorder(Node node){  
28:            if(node == null) return;  
29:            System.out.print(node.data + " ");  
30:            preorder(node.left);  
31:            preorder(node.right);  
32:       }  
33:       public static void postorder(Node node){  
34:            if(node == null) return;  
35:            postorder(node.left);  
36:            postorder(node.right);  
37:            System.out.print(node.data + " ");  
38:       }  
39:       public static void inorder(Node node){  
40:            if(node == null) return;  
41:            inorder(node.left);  
42:            System.out.print(node.data + " ");  
43:            inorder(node.right);  
44:       }  
45:       public static void levelOrder(Node node){  
46:            Queue<Node> queue = new ArrayDeque<Node>();  
47:            queue.add(node);  
48:            while(!queue.isEmpty()){  
49:                 Node temp = queue.remove();  
50:                 System.out.print(temp.data + " ");  
51:                 if(temp.left != null) queue.add(temp.left);  
52:                 if(temp.right != null) queue.add(temp.right);  
53:            }  
54:       }  
55:       public static void preorderIteration(Node node){  
56:            Stack<Node> stack = new Stack<Node>();  
57:            stack.push(node);  
58:            while(!stack.isEmpty()){  
59:                 Node temp = stack.pop();  
60:                 System.out.print(temp.data + " ");  
61:                 if(temp.right != null) stack.push(temp.right);  
62:                 if(temp.left != null) stack.push(temp.left);  
63:            }  
64:       }  
65:       public static void postorderIteration(Node node){  
66:            Stack<Node> stack = new Stack<Node>();  
67:            if(node == null) return;  
68:            do{  
69:                 while(node != null){  
70:                   if(node.right != null)     stack.push(node.right);  
71:                      stack.push(node);  
72:                      node = node.left;  
73:                 }  
74:                 node = stack.pop();  
75:                 if((node.right != null) && (!stack.isEmpty()) && (node.right == stack.peek())){  
76:                      stack.pop();  
77:                      stack.push(node);  
78:                      node = node.right;  
79:                 }else{  
80:                      System.out.print(node.data + " ");  
81:                      node = null;  
82:                 }  
83:            }while(!stack.isEmpty());  
84:       }  
85:       public static void inorderIteration(Node node){  
86:            Stack<Node> stack = new Stack<Node>();  
87:            if(node == null) return;  
88:            do{  
89:                 while(node != null){  
90:                      stack.push(node);  
91:                      node = node.left;  
92:                 }  
93:                 if(stack.empty()) break;  
94:                 node = stack.pop();  
95:                 System.out.print(node.data + " ");  
96:                 node = node.right;  
97:            }while(true);  
98:       }  
99:       public static int maximum(Node root){  
100:            int max = Integer.MIN_VALUE;  
101:            int left, right;  
102:            if(root == null) return max;  
103:            left = maximum(root.left);  
104:            right = maximum(root.right);  
105:            if(left > right) max = left;  
106:            else max = right;  
107:            if(max < root.data) max = root.data;  
108:            return max;  
109:       }  
110:       public static boolean searchElement(Node root, int data){  
111:            boolean isLeft = false;  
112:            boolean isRight = false;  
113:            if(root == null) return false;  
114:            if(root.data == data) return true;  
115:            isLeft = searchElement(root.left, data);  
116:            isRight = searchElement(root.right, data);  
117:            if(isLeft == false && isRight == false) return false;  
118:            else return true;  
119:       }  
120:       public static int sizeOfTree(Node root){  
121:            if(root == null) return 0;  
122:            int leftSize = sizeOfTree(root.left);  
123:            int rightSize = sizeOfTree(root.right);  
124:            return leftSize + rightSize + 1;  
125:       }  
126:       public static Node createFullBST(int height){  
127:            if(height == 0) return null;  
128:            Node temp = new Node();  
129:            temp.left = createFullBST(height-1);  
130:            temp.data = count++;  
131:            temp.right = createFullBST(height-1);  
132:            return temp;  
133:       }  
134:       public static int heightTree(Node root){  
135:            if(root == null) return 0;  
136:            int leftHeight = heightTree(root.left) + 1;  
137:            int rightHeight = heightTree(root.right) + 1;  
138:            if(leftHeight > rightHeight ) return leftHeight;  
139:            else return rightHeight;  
140:       }  
141:       public static Item deepestNode(Node root, int level){  
142:            if(root == null) return null;  
143:            Item left = deepestNode(root.left, level+1);  
144:            Item right =deepestNode(root.right, level+1);  
145:            if(left == null && right == null){  
146:                 Item item = new Item();  
147:                 item.data = root.data;  
148:                 item.level = level;  
149:                 return item;  
150:            }else{  
151:                 if(left != null && right != null){  
152:                      if(left.level > right.level){  
153:                           return left;  
154:                      }else{  
155:                           return right;  
156:                      }  
157:                 }  
158:                 else if(left == null) return right;  
159:                 else return left;  
160:            }  
161:       }  
162:       public static boolean isIdentical(Node root1, Node root2){  
163:            if(root1 == null && root2 == null) return true;  
164:            if(root1 == null || root2 == null) return false;  
165:            if(root1.data == root2.data){  
166:                 boolean isLeft = isIdentical(root1.left, root2.left);  
167:                 boolean isRight = isIdentical(root1.right, root2.right);  
168:                 if(isLeft == true && isRight == true) return true;  
169:                 else return false;  
170:            }else return false;  
171:       }  
172:       public static Height diameterTree(Node root, Height height){  
173:            Height leftHeight = new Height();  
174:            Height rightHeight = new Height();  
175:            if(root == null){  
176:                 height.data = 0;  
177:                 return height;  
178:            }  
179:            Height ldiameter = diameterTree(root.left, leftHeight);  
180:            Height rdiameter = diameterTree(root.right, rightHeight);  
181:            height.data = max(leftHeight.data, rightHeight.data) + 1;  
182:            Height newHeight = new Height();  
183:            newHeight.data = max(leftHeight.data + rightHeight.data + 1, max(ldiameter.data, rdiameter.data));  
184:            return newHeight;  
185:       }  
186:       public static void allPathToLeaf(Node root, int[] list, int pathLength){  
187:            if(root == null) return;  
188:            list[pathLength] = root.data;  
189:            pathLength++;  
190:            if(root.left == null && root.right == null){  
191:                 for(int i = 0; i < pathLength; i++){  
192:                      System.out.print(list[i] + " -> ");  
193:                 }  
194:                 System.out.println();  
195:            }else{  
196:                 allPathToLeaf(root.left, list, pathLength);  
197:                 allPathToLeaf(root.right, list, pathLength);  
198:            }  
199:       }  
200:       public static boolean isPathWithSum(Node root, int sum){  
201:            if(sum == 0) return true;  
202:            if(sum != 0 && root == null) return false;  
203:            if(sum < 0) return false;  
204:            sum -= root.data;  
205:            boolean leftpart = isPathWithSum(root.left, sum);  
206:            boolean rightpart = isPathWithSum(root.right, sum);  
207:            if(leftpart || rightpart) return true;  
208:            else return false;  
209:       }  
210:       public static int sumAllElements(Node root){  
211:            if(root == null) return 0;  
212:            int leftSum = sumAllElements(root.left);  
213:            int rightSum = sumAllElements(root.right);  
214:            return leftSum + rightSum + root.data;  
215:       }  
216:       public static void getMirror(Node root){  
217:            if(root == null) return;  
218:            Node temp = root.left;  
219:            root.left = root.right;  
220:            root.right = temp;  
221:            getMirror(root.left);  
222:            getMirror(root.right);  
223:       }  
224:       public static Node constuctPreorderInorderTree(int[] preorder, int[] inorder, int inStart, int inEnd){  
225:            if(inStart > inEnd) return null;  
226:            Node node = new Node();  
227:            node.data = preorder[preOrderIndex++];  
228:            int index = search(inorder, node.data, inStart, inEnd);  
229:            if(index != -1){  
230:                 node.left = constuctPreorderInorderTree(preorder, inorder, inStart, index - 1);  
231:                 node.right = constuctPreorderInorderTree(preorder, inorder, index + 1, inEnd);  
232:            }  
233:            return node;  
234:       }  
235:       private static int search(int[] inorder, int key, int inStart, int inEnd) {  
236:            for(int i = inStart; i <= inEnd; i++) if(inorder[i] == key) return i;  
237:            return -1;  
238:       }  
239:       private static boolean printAncesstor(Node node, int key){  
240:            if(node == null) return false;  
241:            if(node.data == key){  
242:                 System.out.print(node.data+ " ");  
243:                 return true;  
244:            }  
245:            boolean isLeft = printAncesstor(node.left, key);  
246:            boolean isRight = printAncesstor(node.right, key);  
247:            if(isLeft || isRight){  
248:                 System.out.print(node.data + " ");  
249:                 return true;  
250:            }else return false;  
251:       }  
252:       public static void main(String[] args) {  
253:            Node root = createFullBST(4);  
254:            System.out.println("Preorder with recursion : ");   
255:            preorder(root);  
256:            System.out.println("\nPreorder without recursion : ");   
257:            preorderIteration(root);  
258:            System.out.println("\nPostorder with recursion : ");   
259:            postorder(root);  
260:            System.out.println("\nPostorder without recursion : ");   
261:            postorderIteration(root);  
262:            System.out.println("\nInorder with recursion : ");   
263:            inorder(root);  
264:            System.out.println("\nInorder without recursion : ");   
265:            inorderIteration(root);  
266:            System.out.println("\nLevel with recursion : ");   
267:            levelOrder(root);  
268:            System.out.println("\n\nMaximum in Tree is : "+ maximum(root));  
269:            if(searchElement(root, 5)){  
270:                 System.out.println("\nYes !! Present");  
271:            }else System.out.println("\nNo !! Not Present");  
272:            System.out.println("\nSize of Tree : "+sizeOfTree(root));  
273:            System.out.println("\nHeight of Tree : "+heightTree(root));  
274:            Node node1 = new Node();  
275:            node1.data = 1;  
276:            node1.left = new Node();  
277:            node1.left.data = 2;  
278:            node1.right = new Node();  
279:            node1.right.data = 3;  
280:            node1.left.left = new Node();  
281:            node1.left.left.data = 4;  
282:            node1.right.right = new Node();  
283:            node1.right.right.data =5;  
284:            node1.left.left.left = new Node();  
285:            node1.left.left.left.data = 6;  
286:            Node node2 = new Node();  
287:            node2.data = 1;  
288:            node2.left = new Node();  
289:            node2.left.data = 2;  
290:            node2.right = new Node();  
291:            node2.right.data = 3;  
292:            node2.left.left = new Node();  
293:            node2.left.left.data = 4;  
294:            node2.right.right = new Node();  
295:            node2.right.right.data =5;  
296:            node2.left.left.left = new Node();  
297:            node2.left.left.left.data = 9;  
298:            node2.left.right = new Node();  
299:            node2.left.right.data = 6;  
300:            node2.left.right.right = new Node();  
301:            node2.left.right.right.data = 7;  
302:            node2.left.right.right.right = new Node();  
303:            node2.left.right.right.right.data = 8;  
304:            Item deepest = deepestNode(node1, 0);  
305:            System.out.println("\nDeepest node of Tree : "+deepest.data);  
306:            System.out.println("\nIs tow Trees Identcal : "+ isIdentical(node1, node2));  
307:            Height height = new Height();  
308:            height.data = 0;  
309:            System.out.println("\nDiameter of tree : "+ diameterTree(node2, height).data);  
310:            int[] list = new int[1000];  
311:            allPathToLeaf(node2, list, 0);  
312:            System.out.println("\nDoes it have path : "+ isPathWithSum(node2, 10));  
313:            System.out.println("\nSum all elements of tree : "+sumAllElements(root));  
314:            System.out.println("\nBefore Mirror :");  
315:            preorder(node2);  
316:            getMirror(node2);  
317:            System.out.println("\nAfter Mirror :");  
318:            preorder(node2);  
319:            System.out.println("\n=================================================================");  
320:            int[] inorder = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };  
321:            int[] preorder = {7, 3, 1, 0, 2, 5, 4, 6, 11, 9, 8, 10, 13, 12, 14};  
322:            Node constructedTree = constuctPreorderInorderTree(preorder, inorder, 0, inorder.length - 1);  
323:            postorder(constructedTree);  
324:            System.out.println("\n=================================================================");  
325:            System.out.println("\nAncesstors : "+ printAncesstor(node2, 8));  
326:       }  
327:  }  

Sunday, 20 December 2015

Heap Implementation in JAVA

In computer science, a heap is a specialized tree-based data structure that satisfies the heap property: If A is a parent node of B then the key of node A is ordered with respect to the key of node B with the same ordering applying across the heap. A heap can be classified further as either a "max heap" or a "min heap". In a max heap, the keys of parent nodes are always greater than or equal to those of the children and the highest key is in the root node. In a min heap, the keys of parent nodes are less than or equal to those of the children and the lowest key is in the root node. Heaps are crucial in several efficient graph algorithms such as Dijkstra's algorithm, and in the sorting algorithm heapsort. A common implementation of a heap is the binary heap, in which the tree is a complete binary tree (see figure).
In a heap, the highest (or lowest) priority element is always stored at the root, hence the name heap. A heap is not a sorted structure and can be regarded as partially ordered. As visible from the heap-diagram, there is no particular relationship among nodes on any given level, even among the siblings. When a heap is a complete binary tree, it has a smallest possible height—a heap with N nodes always has log N height. A heap is a useful data structure when you need to remove the object with the highest (or lowest) priority.







1:  package com.examples.ajay;  
2:  class Heap{  
3:       int[] array;  
4:       int count;  
5:       int capacity;  
6:       int heap_type;  
7:  }  
8:  public class HeapImplementation {  
9:       public static Heap createHeap(int capacity, int heap_type){  
10:            Heap heap = new Heap();  
11:            heap.array = new int[capacity];  
12:            if(heap.array == null) return null;  
13:            heap.heap_type = heap_type;  
14:            heap.count = 0;  
15:            heap.capacity = capacity;  
16:            return heap;  
17:       }  
18:       public static int getParent(Heap heap, int i){  
19:            if(i >= heap.count || i <= 0) return -1; //asking for parent of root or entry outside the amount of elements in heap  
20:            return (i-1)/2;  
21:       }  
22:       public static int leftChild(Heap heap, int i){  
23:            int left = 2*i + 1;  
24:            if(left >= heap.count) return -1;  
25:            else return left;  
26:       }  
27:       public static int rightChild(Heap heap, int i){  
28:            int right = 2*i + 2;  
29:            if(right >= heap.count) return -1;  
30:            else return right;  
31:       }  
32:       public static int getMaximum(Heap heap){  
33:            if(heap.count <= 0) return -1;  
34:            else return heap.array[0];  
35:       }  
36:       public static void heapify(Heap heap , int i){  
37:            int left, right, max;  
38:            left = leftChild(heap, i);  
39:            right = rightChild(heap, i);  
40:            //exchange parent with the maximum among both of left or right children  
41:            if(left != -1 && heap.array[left] > heap.array[i]) max = left;  
42:            else max = i;  
43:            if(right != -1 && heap.array[right] > heap.array[max]) max = right;  
44:            if(max != i){  
45:                 int temp = heap.array[max];  
46:                 heap.array[max] = heap.array[i];  
47:                 heap.array[i] = temp;  
48:                 heapify(heap, max);  
49:            }  
50:       }  
51:       public static int deleteMax(Heap heap){  
52:            int data;  
53:            if(heap.count <= 0) return -1;  
54:            data = heap.array[0];  
55:            heap.array[0] = heap.array[heap.count - 1];  
56:            heap.count--;  
57:            heapify(heap, 0);  
58:            return data;  
59:       }  
60:       public static void insert(Heap heap, int data){  
61:            if(heap.count == heap.capacity) resizeHeap(heap);  
62:            heap.count++;  
63:            int i = heap.count - 1;  
64:            //find location till data is greater than the parent of node which is inserted at count-1  
65:            while(i > 0 && data > heap.array[(i-1)/2]){  
66:                 heap.array[i] = heap.array[(i-1)/2];  
67:                 i = (i-1)/2;  
68:            }  
69:            heap.array[i] = data;  
70:       }  
71:       private static void resizeHeap(Heap heap) {  
72:            // TODO Auto-generated method stub  
73:            int i = 0;  
74:            int[] temp = heap.array;  
75:            heap.array = new int[heap.capacity * 2];  
76:            for (int element : temp) {  
77:                 heap.array[i++] = element;  
78:            }  
79:            heap.capacity *= 2;  
80:       }  
81:       public static void main(String[] args) {  
82:            // TODO Auto-generated method stub  
83:            int[] heapArray = {3, 1, 9, 8, 14, 12, 5, 7, 31, 10, 16};  
84:            Heap heap = createHeap(heapArray.length, 0);  
85:            /*for(int element : heapArray){  
86:                 insert(heap, element);  
87:            }*/  
88:            int i = 0;  
89:            for(int element : heapArray){  
90:                 heap.array[i++] = element;  
91:            }  
92:            heap.count = heapArray.length;  
93:            for(i = (heapArray.length - 1)/2; i >= 0 ; i--) heapify(heap, i);  
94:            System.out.println("Results: ");  
95:            for(i = 0; i < heap.count ; i++){  
96:                 System.out.print(heap.array[i] + " ");  
97:            }  
98:            System.out.println();  
99:            System.out.println("Deleing root ...");  
100:            deleteMax(heap);  
101:            System.out.println("Results: ");  
102:            for(i = 0; i < heap.count ; i++){  
103:                 System.out.print(heap.array[i] + " ");  
104:            }  
105:       }  
106:  }  
Output :


Results: 

31 16 12 9 14 3 5 1 7 8 10 



Deleting root ...

Results: 

16 14 12 9 10 3 5 1 7 8 

Sunday, 6 December 2015

Swap Nodes [Algo] Hackerrank




Problem Statement
A binary tree is a tree which is characterized by any one of the following properties:
  • It can be an empty (null).
  • It contains a root node and two subtrees, left subtree and right subtree. These subtrees are also binary tree.
Inorder traversal is performed as
  1. Traverse the left subtree.
  2. Visit root (print it).
  3. Traverse the right subtree.
(For an Inorder traversal, start from the root and keep visiting the left subtree recursively until you reach the leaf,then you print the node at which you are and then you visit the right subtree.)
We define depth of a node as follow:
  • Root node is at depth 1.
  • If the depth of parent node is d, then the depth of current node wll be d+1.
Swapping: Swapping subtrees of a node means that if initially node has left subtree L and right subtree R, then after swapping left subtree will be R and right subtree L.
Eg. In the following tree, we swap children of node 1.
                                Depth
    1               1            [1]
   / \             / \
  2   3     ->    3   2          [2]
   \   \           \   \
    4   5           5   4        [3]
 
Inorder traversal of left tree is 2 4 1 3 5 and of right tree is 3 5 1 2 4.

Swap operation: Given a tree and a integer, K, we have to swap the subtrees of all the nodes who are at depth h, where h ∈ [K, 2K, 3K,...].
You are given a tree of N nodes where nodes are indexed from [1..N] and it is rooted at 1. You have to perform T swap operations on it, and after each swap operation print the inorder traversal of the current state of the tree.

Input Format
First line of input contains N, number of nodes in tree. Then N lines follow. Here each of ith line (1 <= i <= N) contains two integers, a b, where a is the index of left child, and b is the index of right child of ith node. -1 is used to represent null node.
Next line contain an integer, T. Then again T lines follows. Each of these line contains an integer K.

Output Format
For each K, perform swap operation as mentioned above and print the inorder traversal of the current state of tree.

Constraints
1 <= N <= 1024
1 <= T <= 100
1 <= K <= N
Either a = -1 or 2 <= a <= N
Either b = -1 or 2 <= b <= N
Index of (non-null) child will always be greater than that of parent.
Sample Input #00
3
2 3
-1 -1
-1 -1
2
1
1
Sample Output #00
3 1 2
2 1 3
Sample Input #01
5
2 3
-1 4
-1 5
-1 -1
-1 -1
1
2
Sample Output #01
4 2 1 5 3
Sample Input #02
11
2 3
4 -1
5 -1
6 -1
7 8
-1 9
-1 -1
10 11
-1 -1
-1 -1
-1 -1
2
2
4
Sample Output #02
2 9 6 4 1 3 7 5 11 8 10
2 6 9 4 1 3 7 5 10 8 11
Explanation
**[s] represents swap operation is done at this depth.
Test Case #00: As node 2 and 3 has no child, swapping will not have any effect on it. We only have to swap the child nodes of root node.
    1   [s]       1    [s]       1   
   / \      ->   / \        ->  / \  
  2   3 [s]     3   2  [s]     2   3
Test Case #01: Swapping child nodes of node 2 and 3 we get
    1                  1  
   / \                / \ 
  2   3   [s]  ->    2   3
   \   \            /   / 
    4   5          4   5  
Test Case #02: Here we perform swap operations at the nodes whose depth is either 2 and 4 and then at nodes whose depth is 4.
         1                     1                          1             
        / \                   / \                        / \            
       /   \                 /   \                      /   \           
      2     3    [s]        2     3                    2     3          
     /      /                \     \                    \     \         
    /      /                  \     \                    \     \        
   4      5          ->        4     5          ->        4     5       
  /      / \                  /     / \                  /     / \      
 /      /   \                /     /   \                /     /   \     
6      7     8   [s]        6     7     8   [s]        6     7     8
 \          / \            /           / \              \         / \   
  \        /   \          /           /   \              \       /   \  
   9      10   11        9           11   10              9     10   11 



#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;

struct Node{
    int data;
    struct Node* left;
    struct Node* right;
};

Node* newnode(int data){
    Node* node = (Node*)malloc(sizeof(Node));
    node->data = data;
    node->left = NULL;
    node->right = NULL;
    return node;
}
void Inorder(Node *root) {
    if(root == NULL){
        return;
    }
    Inorder(root->left);
    cout<<root->data<<" ";
    Inorder(root->right);
}
void swapLevelK(int k, Node* root){
    queue<Node*> q;
    Node* temp;
    if(root == NULL){
        return;
    }
    q.push(root);
    q.push(NULL);
    int label = 1;
   
    while(!q.empty() && label <= k){
        temp = q.front();
        q.pop();
        if(temp == NULL){
            if(!q.empty()){
                q.push(NULL);
                label += 1;
            }
        }else{
            if(label != k){
                if(temp->left != NULL) q.push(temp->left);
                if(temp->right != NULL) q.push(temp->right);
            }else if(label == k){
                Node* dummy = temp->left;
                temp->left = temp->right;
                temp->right = dummy;
            }
        }
    }
}
int main() {
    /* Enter your code here. Read input from STDIN. Print output to STDOUT */
    Node* root = NULL;
    int N;
    cin>>N;
    int a, b;
    Node* temp;
    queue<Node*> q;
    if(N > 0){
        root = newnode(1);
        q.push(root);
        q.push(NULL);
    }
    int label = 1;
    while((N>0) && (!q.empty())){
        temp = q.front();
        q.pop();
        if(temp == NULL){
            if(!q.empty()){
                q.push(NULL);
                label += 1;
            }
        }else{
            cin>>a>>b;
            if(a != -1){
                temp->left = newnode(a);
                q.push(temp->left);
            }
            if(b != -1){
                temp->right = newnode(b);
                q.push(temp->right);
            }
            N--;
        }
    }
    int T;
    cin>>T;

    while(T > 0)
    {
        int k;
        cin>>k;
        int itr = 2;
        int lvl = k;
        while(lvl <= label )
        {
            swapLevelK(lvl, root);
            lvl = itr * k;
            itr++;
        }
        Inorder(root);
        cout<<endl;
        T--;
    }
    return 0;
}

Thursday, 3 December 2015

Binary Search Tree : Lowest Common Ancestor

Problem Statement
You are given pointer to the root of the binary search tree and two values v1 and v2. You need to return the lowest common ancestor (LCA) of v1 and v2 in the binary search tree. You only need to complete the function.
Input Format
You are given a function,
node * LCA (node * root ,int v1,int v2)
{

}
It is guaranteed that v1 and v2 are present in the tree.
Node is defined as :
struct node
{
int data;
node * left;
node * right;
}node;
Output Format
Return the LCA of v1 and v2.
Sample Input
         4
       /   \
      2     7
     / \   /
    1   3 6
v1=1 and v2=7.
Sample Output
LCA of 1 and 7 is 4 (which is the root). 
Return a pointer to the root in this case.

/*
Node is defined as 

typedef struct node
{
   int data;
   node * left;
   node * right;
}node;

*/


node * lca(node * root, int v1,int v2)
{
    if(root == NULL){
        return NULL;
    }else if(root->left == NULL && root->right == NULL){
        return NULL;
    }
    if(v1 < root->data && v2 < root->data){
        return lca(root->left, v1, v2);
    }else if(v1 > root->data && v2 > root->data){
        return lca(root->right, v1, v2);
    }
    return root;
}

Tree: Huffman Decoding

Problem Statement
Huffman coding assigns variable length codewords to fixed length input characters based on their frequencies. More frequent characters are assigned shorter codewords and less frequent characters are assigned longer codewords. A huffman tree is made for the input string and characters are decoded based on their position in the tree. We add a '0' to the codeword when we move left in the binary tree and a '1' when we move right in the binary tree. We assign codes to the leaf nodes which represent the input characters.
For example :
        {Ï•,5}
     0 /     \ 1
    {Ï•,2}   {A,3}
   0/   \1
{B,1}  {C,1}  
Input characters are only present on the leaves. Internal nodes have a character value of Ï•. Codewords:
A - 1
B - 00
C - 01
No codeword appears as a prefix of any other codeword. Huffman encoding is a prefix free encoding technique.
Encoded String "1001011" represents the string "ABACA"
You have to decode an encoded string using the huffman tree.
You are given pointer to the root of the huffman tree and a binary coded string. You need to print the actual string.
Input Format
You are given a function,
void decode_huff(node * root, string s)
{

}
The structure for node is defined as :
struct node
{
    int freq;
    char data;
    node * left;
    node * right;

}node;    
Note: 
Internal nodes have data='\0'(Ï• )
Output Format
Output the decoded string on a single line.
Sample Input
         {Ï•,5}
      0 /     \ 1
     {Ï•,2}   {A,3}
    0/   \1
{B,1}  {C,1}  

S="1001011"
Sample Output
ABACA
Explanation
S="1001011"
Processing the string from left to right.
S[0]='1' : we move to the right child of the root. We encounter a leaf node with value 'A'. We add 'A' to the decoded string.
We move back to the root.

S[1]='0' : we move to the left child. 
S[2]='0' : we move to the left child. We encounter a leaf node with value 'B'. We add 'B' to the decoded string.
We move back to the root.

S[3] = '1' : we move to the right child of the root. We encounter a leaf node with value 'A'. We add 'A' to the decoded string.
We move back to the root.

S[4]='0' : we move to the left child. 
S[5]='1' : we move to the right child. We encounter a leaf node with value C'. We add 'C' to the decoded string.
We move back to the root.

 S[6] = '1' : we move to the right child of the root. We encounter a leaf node with value 'A'. We add 'A' to the decoded string.
We move back to the root.

Decoded String = "ABACA"

/* 
The structure of the node is

typedef struct node
{
    int freq;
    char data;
    node * left;
    node * right;
    
}node;

*/
void decode_huff(node * root,string s)
{
    int i = 0;
    node* temp = root;
    if(root == NULL){
        return;
    }
   
    while(s[i] == '0' || s[i] == '1'){
        if(s[i] == '0' && temp->left != NULL){
            temp = temp->left;
        }else if(s[i] == '1' && temp->right != NULL){
            temp = temp->right;
        }
        if(temp->left == NULL && temp->right == NULL){
            cout<<temp->data;
            temp = root;
        }
        i++;
    }
}

Wednesday, 2 December 2015

Tree: Level Order Traversal

Problem Statement
You are given a pointer to the root of a binary tree. You need to print the level order traversal of this tree. In level order traversal, we visit the nodes level by level from left to right. 
You only have to complete the function. 
For example:
         3
       /   \
      5     2
     / \    /
    1   4  6
For the above tree, the level order traversal is 3 -> 5 -> 2 -> 1 -> 4 -> 6.
Input Format
You are given a function,
void level_order(node * root)
{

}
Output Format
Print the values in a single line seperated by a space.
Sample Input
         3
       /   \
      5     2
     / \    /
    1   4  6
Sample Output
3 5 2 1 4 6
Explanation
Level 1:        3
              /   \
Level 2:     5     2
            / \    /
Level 3:   1   4  6
We need to print the nodes level by level. We process each level from left to right. 
Level Order Traversal: 3 -> 5 -> 2 -> 1 -> 4 -> 6

/*
struct node
{
    int data;
    node* left;
    node* right;
}*/
node** createQueue(int *front, int *rear){
    *front = 0;
    *rear = 0;
    node** queue = (node**)malloc(sizeof(node*)*2500);
    return queue;
}
void enqueue(node** queue, int* rear, node* element){
    queue[*rear] = element;
    (*rear)++;
}
node* dequeue(node** queue, int* front){
    (*front)++;
    return queue[*front - 1];
}
void LevelOrder(node * root)
{
    int front,rear;
    if(root == NULL){
        return;
    }
    node* temp = root;
    node** queue = createQueue(&front, &rear);
    while(temp){
        cout<<temp->data<<" ";
        if(temp->left != NULL){
            enqueue(queue, &rear, temp->left);
        }
        if(temp->right != NULL){
            enqueue(queue, &rear, temp->right);
        }
        temp = dequeue(queue, &front);
    }
}