# DATA STRUCTURES AND ALGORITHMS LABORATORY

LAB MANUAL 2010-2011

INDEX
I II III LAB SYLLABUS LAB PLAN PSEUDO CODES FOR LAB EXPERIMENTS

1. (a) Implementation of Linked List
(b) Implementation of Doubly Linked list 2. Represent a polynomial as a linked list and write functions For polynomial addition. 3. Implementation of tree traversal 4. Implementation of stack ( infix to postfix conversion) 5. Implementation of Binary search Tree

2
6. Implementation of insertion in AVL trees 7. Implementation of hashing techniques 8. Implementation of backtracking algorithm for knapsack problem 9. Implementation of prim’s and kruskal’s algorithm 10. Implementation of dijktra’s algorithm using priority queues 11. Implementation of array based circular queue 12. Implementation of priority queues using heaps 13. Implementation of branch and bound algorithm 14. Implementation of Randomized algorithm 15. Implementation of Topological sort on a Directed graph to decide is it is cyclic

Experiments to be performed: Aim: To develop skills in design and implementation of data structures and their applications. 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. Implement singly and doubly linked lists. Represent a polynomial as a linked list and write functions for polynomial addition. Implement stack and use it to convert infix to postfix expression Implement array-based circular queue and use it to simulate a producer-consumer problem. Implement an expression tree. Produce its pre-order, in-order, and post-order traversals. Implement binary search tree. Implement insertion in AVL trees. Implement priority queue using heaps Implement hashing techniques Perform topological sort on a directed graph to decide if it is acyclic. Implement Dijkstra's algorithm using priority queues Implement Prim's and Kruskal's algorithms Implement a backtracking algorithm for Knapsack problem Implement a branch and bound algorithm for traveling salesperson problem Implement any randomized algorithm.

3

LAB PLAN SI.No 1 Name of the Experiment (a) Implementation of Linked List (b) Implementation of Doubly Linked List Represent a polynomial as a linked list and write functions for polynomial addition. Implementation of tree traversal Implementation of stack (converting infix to postfix expression) Implementation of Binary search tree Implementation of hashing techniques Implementation of insertion in AVL Tree Date

2

3 4 5 6 7

c) Find the node after which the new node is to be inserted. b) Get a new node and set DATA[NEWNODE] = ITEM. ALGORITHM: Step 1: Start the process. Step 3: Enter the choice.4 8 9 10 11 12 13 14 15 Implementation of Backtracking algorithm for Knapsack problem Implementation of Prim’s and Kruskal’s algorithm Implementation of Dijktra’s algorithm using priority queues Implementation of array based circular queue Implementation of priority queues using heaps Implementation of Branch and bound algorithm Implementation of Randomized algorithm Implementation of Topological sort on a Directed graph to decide is it is cyclic IMPLEMENTATION OF A LINKED LIST Ex. Step 2: Initialize and declare variables. INSERT / DELETE. . No : 1(a) AIM: To implement a linked list and do all operations on it. Step 4: If choice is INSERT then a) Enter the element to be inserted.

IMPLEMENTATION OF DOUBLY LINKED LIST Ex.5 d) Adjust the link fields. No : 1(b) AIM: To implement a doubly linked list and do all operations on it. ie LINK [PAR] = LINK [LOC]. ALGORITHM: Step 1: Data type declarations record Node { data prev } record List { Node firstNode // points to first node of list. b) Find the node containing the element (LOC) and its preceding node (PAR). Step 5: If choice is DELETE then a) Enter the element to be deleted. null for empty list } . Step 6: Stop the process. e) Print the linked list after deletion. null for empty list Node lastNode // points to last node of list. e) Print the linked list after insertion. d) Adjust the link fields so that PAR points to the next element. c) Set ITEM = DATA [LOC] and delete the node LOC.

data> node := node.lastNode.lastNode := newNode newNode.prev is null list. list. newNode) else insertAfter(list. Node newNode) newNode.next := node. list.next := null else insertBefore(list.firstNode := newNode else node. newNode) A symmetric function inserts at the end: function insertEnd(List list.prev newNode. Node node.6 Step 2: Iterating over the nodes Iterating through a doubly linked list can be done in either direction. only requiring care with the firstNode and lastNode: .next == null list.data> node := node.next := node if node.prev := newNode node.prev. Node newNode) if list. Node node.lastNode := newNode else node. direction can change many times. node := list.next.next if node.firstNode := newNode list.prev := null newNode. if desired.lastNode while node ≠ null <do something with node.next := newNode function insertBefore(List list.prev := node. In fact. newNode) Step 5:Deleting a node Removing a node is easier. Node newNode) if list.prev := newNode Function to insert a node at the beginning of a possibly-empty list: function insertBeginning(List list. Node newNode) newNode.firstNode while node ≠ null <do something with node.next := newNode node.firstNode == null list.prev Step 3:Inserting a node function insertAfter(List list.prev := node newNode.lastNode == null insertBeginning(list.next node := list.firstNode.

So all those terms have to be appended to end of list3. phead3) . p3 -> coff = p2 -> coff . p2 = p2 -> next. then we must add the coefficients to get the term for the final list */ while (p1 ->exp = p2 -> exp ) { p3-> exp = p1-> exp. phead3) . p3 -> coff = p1 -> coff . as p1 is already pointing to remaining terms. } /* now consider the possibility that both exponents are same . } / * if p2 exponent turns out to be higher then make p3 same as p2 and append to final list * / while (p1 ->exp < p2 -> exp ) { p3 -> exp = p2 -> exp. /* now move to the next term in list 1*/ p1 = p1 -> next. phead3). else append (p2. append (p3. so simply append the pointer p1 to phead3 */ if ( p1 != NULL) append (p1. . p1 = p1->next . you do not have to do it term by term. phead3). append (p3. } } /* now consider the possibility that list2 gets exhausted. append (p3.. /* now traverse the lists till one list gets exhausted */ while ((p1 != NULL) || (p2 != NULL)) { / * if the exponent of p1 is higher than that of p2 then the next term in final list is going to be the node of p1* / while (p1 ->exp > p2 -> exp ) { p3 -> exp = p1 -> exp. and there are terms remaining only in list1. However. phead3). p2 = p2->next .9 third list p3 = phead3. p3->coff = p1->coff + p2-> coff .

:3 Date AIM: To implement tree traversals using linked list. Step 2: Initialize and declare variables. No. ALGORITHM: Step 1: Start the process. Inorder / Preorder / Postorder. Step 4: If choice is Inorder then : . Step 3: Enter the choice.10 IMPLEMENTATION OF TREE TRAVERSALS Ex.

Step 6: If choice is postorder then a) Traverse the left subtree in postorder. No. Step7: Print the Inorder / Preorder / Postorder traversal. What is a balanced tree Do a breadth first traversal of a tree. How would you print out the data in a binary tree. 3. What is a spanning Tree? STACK IMPLEMENTATION FOR CONVERTING INFIX TO POSTFIX EXPRESSION Ex. starting at the top? Write a function to find the depth of a binary tree. c) Process the root node.11 a) Traverse the left subtree in inorder. . or lesser precedence than the top most operator on the stack? If the operator is greater than the top most operator. level by level. 2. How do you represent an n-ary tree? Write a program to print the nodes of such a tree in breadth first order. equal. normally a operator. and push the operator to the stack. Read the next object in the string. Step 8: Stop the process. Viva Questions: • • • • • • • Write a function and the node data structure to visit all of the nodes in a binary tree. b) Traverse the left subtree in preorder. b) Traverse the right subtree in postorder. b) Process the root node. Read the string. :4 AIM: To implement stack for converting infix to postfix expression ALGORITHM: 1. push the current operator and continue. getting the first operand and add it to the postfix string. Step 5: If choice is Preorder then a) Process the root node. Is the operator of greater. Start by initializing an empty stack. This will be for holding our operators. c) Traverse the right subtree in preorder. c) Traverse the right subtree in inorder.

If the operator is equal to the top most operator pop the top of the stack adding it to the postfix string and then push the current operator to the stack. Stop the process. write the program to give equivalent infix expression with parentheses inserted where necessary. 4. :5 AIM: To implement binary search tree and to do BST operations ALGORITHM: find() Operation //Purpose: find Item X in the Tree //Inputs: data object X (object to be found). NULL otherwise. If not continue.12 If the operator is lesser to the top most operator. node)f if(node = NULL) . 6. Afterwards look at the stack one last time to see if any operators remain. How would you implement a queue from a stack? What is stack? List the difference between queue and stack. \ Viva questions: • • • • • Given an expression tree with no parentheses in it. How would you implement a queue from a stack? IMPLEMENTATION OF BINARY SEARCH TREE Ex. pop the stack adding it to the postfix string. find(X. and then push the current operator to the stack. Repeat these steps until all of the operands and operators are taken care of. No. binary-search-tree node node // Output: bst-node n containing X. pop them all and add them to the end of the postfix string. if it exists. 5. Test the next operator to see if it is also lesser and repeat step 2.

NULL otherwise. // otherwise. node:leftChild) else // X > node:data insert(X. update binary search tree by adding a new node containing data object X insert(X.node:rightChild) { findMinimum() Operation //Purpose: return least data object X in the Tree //Inputs: binary-search-tree node node // Output: bst-node n containing least data object X. binary-search-tree node node //Effect: do nothing if tree does not contain X. findMin(node)f if(node = NULL) //empty tree return NULL if(node:leftChild = NULL) return node return findMin(node:leftChild) } insert() Operation //Purpose: insert data object X into the Tree //Inputs: data object X (to be inserted).node:leftChild) else // X > node:data return find(X. // otherwise. node)f if(node = NULL)f node = new binaryNode(X.NULL) return {if(X = node:data) return else if(X < node:data) insert(X.NULL. node:rightChild) } delete() Operation //Purpose: delete data object X from the Tree //Inputs: data object X (to be deleted).13 return NULL if(X = node:data) return node else if(X < node:data) return find(X. update binary search tree by deleting the node containing data object X delete(X. if it exists. binary-search-tree node node //Effect: do nothing if tree already contains X. node)f if(node = NULL) //nothing to do .

value_t target) { . node:leftChild) else if(X > node:data) delete(X.14 return if(X < node:data) delete(X. No.node:rightChild) }}} Viva questions: • • What is tree? What are the advantages of BST? • Write a function and the node data structure to visit all of the nodes in a binary tree. ALGORITHM: int avl_insert(node *treep.rightChild) node:data = tempNode:data delete(node:data. :6 AIM: To implement Insertion in AVL tree. IMPLEMENTATION OF INSERTION IN AVL TREE Ex. node:rightChild) else f // found the node to be deleted! Take action based on number of node children if(node:leftChild = NULL and node:rightChild = NULL)f delete node node = NULL return {else if(node:leftChild = NULL)f tempNode = node node = node:rightChild delete tempNode {else if(node:rightChild = NULL)f (similar to the case when node:leftChild = NULL) {else f //replace node:data with minimum data from right subtree tempNode = findMin(node.

returning 1 on success or 0 if it * already existed */ node tree = *treep. tree->longer = NEITHER. node *path_top = treep.15 /* insert the target into the tree. tree->value = target. if (!Balanced(tree)) path_top = treep. tree->next[0] = tree->next[1] = NULL. value_t target) { /* Each node in path is currently balanced. tree = malloc(sizeof(*tree)). while (tree && target != tree->value) { direction next_step = (target > tree->value). treep = &tree->next[next_step]. mark each node as longer * in the direction of target because we know we have * inserted target there */ . tree = *treep. target). return 1. } if (tree) return 0. *treep = tree. avl_rebalance(path_top. } void avl_rebalance_path(node path. * Until we find target.

direction dir) { node B. C = D->next[1-dir]. E = D->next[dir]. F = B->next[dir]. direction third) { node B. } else { /* C holds the insertion so F is unbalanced */ F->longer = dir. } node avl_rotate_3(node *path_top. D. B->longer = NEITHER. D->longer = NEITHER. . if (third == dir) { /* E holds the insertion so B is unbalanced */ B->longer = 1-dir. F->next[1-dir] = E. if (third == NEITHER) return NULL. B = *path_top. E = D->next[dir]. direction dir. return C. *path_top = D. B = *path_top. D = F->next[1-dir]. /* assume both trees are balanced */ B->longer = F->longer = NEITHER. E. D->next[1-dir] = B. /* node: C and E can be NULL */ C = D->next[1-dir]. F. E. B->next[dir] = C. D = B->next[dir]. C. C. B->next[dir] = C. in nonrecursive style. } } and there you have an AVL insertion. path->longer node avl_rotate_2(node *path_top. return E. but sometimes performing more comparisons that absolutely needed. *path_top = D. D->next[1-dir] = B. D>longer = NEITHER. D. using only constant space.16 while (path && target != path->value) { direction next_step = (target > path->value). D->next[dir] = F. return E.

h(k. i) if Y[j] = NIL .17 IMPLEMENTATION OF HASHING TECHNIQUES Ex. :7 AIM: To implement hashing techniques ALGORITHM: For insertion: HASH-INSERT (T. No. k) i=0 Repeat j <-.

r[32. 11. 9.47] := {4. 23. 10. 7. 20. not byte */ length of unpadded message as 64-bit little-endian integer to message //Process the message in successive 512-bit chunks: for each 512-bit chunk of message break chunk into sixteen 32-bit little-endian words w[i]. 23. 22.31] := {5. 21. k) i=0 Repeat j <-. 9. 7. 21} //Use binary integer part of the sines of integers (Radians) as constants: for i from 0 to 63 k[i] := floor(abs(sin(i + 1)) × (2 pow 32)) //Initialize variables: var int h0 := 0x67452301 var int h1 := 0xEFCDAB89 var int h2 := 0x98BADCFE var int h3 := 0x10325476 //Pre-processing: append "1" bit to message append "0" bits until message length in bits ≡ 448 (mod 512) append bit /* bit. i) if T[j] = k then return j i = i +1 until T[j] = NIL or i = m Return NIL MD5 – PSEUDO CODE: //Note: All variables are unsigned 32 bits and wrap modulo 2^32 when calculating var int[64] r. 16. 11. 15. 4. 10. 20. 12. 22} 5. 17. 9.18 then T[j] = k Return j use i = i +1 until i = m error "table overflow" For Searching: HASH-SEARCH (T. 22. 23. 17. 7.h(k.15] := {7. 0 ≤ i ≤ 15 //Initialize hash value for this chunk: var int a := h0 . 15. 6.. 20} 4. 21. 9. 11. 10.63] := {6. 12. 16. 14. r[16. 17. 21. 4. 12. 14. 16. 15. 12. k //r specifies the per-round shift amounts r[ 0.. 5. 15. 23} 6. 14.. 14. 20.. r[48. 5. 10. 22. 17. 6. 11. 16.

var int b := h1 var int c := h2 var int d := h3 //Main loop: for i from 0 to 63 if 0 ≤ i ≤ 15 then f := (b and c) or ((not b) and d) g := i else if 16 ≤ i ≤ 31 f := (d and b) or ((not d) and c) g := (5×i + 1) mod 16 else if 32 ≤ i ≤ 47 f := b xor c xor d g := (3×i + 5) mod 16 else if 48 ≤ i ≤ 63 f := c xor (b or (not d)) g := (7×i) mod 16 temp d := c := b := a := //Add h0 := h1 := h2 := h3 := := d c b b + leftrotate((a + f + k[i] + w[g]) . r[i]) temp chunk's hash to result so far: a b c d 19 this h0 + h1 + h2 + h3 + var int digest := h0 append h1 append h2 append h3 Viva questions: • • • • • Define hashing. How can a data be inserted in to the hash table? What is hash table? What are the applications of hashing techniques? . List the hashing techniques.

:8 AIM:To implement backtracking algorithm for Knapsack problem.20 IMPLEMENTATION OF BACKTRACKING ALGORITHM FOR KNAPSACK PROBLEM Ex. No. ALGORITHM:function backtracking (current depth) if solution is valid return / print the solution .

cost.right_child.bound > max_cost) PQ <. update best_solution. max_cost := root. What is the significance of backtracking algorithm? . if (current. end if. end if. while PQ not equal do current <.left_child.bound > max_cost) then create left_child := next item. Viva questions: • • Describe knapsack problem.root.cost. end while. return best_solution and its cost.cost > max_cost) max_cost := left_child.21 else for each element from A[] source array let X[current depth] ß element if possible candidate (current depth + 1) backtracking (current depth + 1) end if end for end if end function (OR) Procedure knapsack: Initialize root. PQ <.PQ. // it skips packing the next item if (right_child. end if.bound > max_cost) PQ <. end if. if (left_child. if (left_child. create right_child. end procedure.

E(2) is the set of the remaining sides.22 IMPLEMENTATION OF PRIM'S AND KRUSKAL'S ALGORITHMS Ex. ALGORITHM:Prim’s Algorithm: E(1) is the set of the sides of the minimum genetic tree. :9 AIM:To implement prim's and kruskal's algorithms. . No.

union C(v) and C(u).v) ← Q.v is the minimum weighted route from/to v 9 (u. If this distance is less than the previously recorded distance (infinity in the beginning. :10 AIM:To implement Dijkstra's algorithm using priority queues. 14 if C(v) ≠ C(u) then 15 Add edge (v. ALGORITHM:1. and let C(u) be the cluster containing u. For example. consider all its unvisited neighbours and calculate their distance (from the initial node). end (If) end (While)  End Of Algorithm. 5 Define a tree T ← Ø //T will ultimately contain the edges of the MST 6 // n is total number of vertices 7 while T has fewer than n-1 edges do 8 // edge u. Mark all nodes as unvisited.V(j) do not belong in the same tree then o unite the trees of V(i) and V(j) to one tree. and an edge connecting it with another node (B) is 2. overwrite the distance. Set initial node as current.E(2)=E  While E(1) contains less then n-1 sides and E(2)=0 do • • • • • 23 From the sides of E(2) choose one with minimum cost-->e(ij) E(2)=E(2)-{e(ij) } If V(i).u) to T. Set it to zero for our initial node and to infinity for all other nodes. zero for the initial node). 3. add u. No.v only if T does not already contain a path between u and v. Kruskal’s Algorithm: 1 function Kruskal(G) 2 for each vertex v in G do 3 Define an elementary cluster C(v) ← {v}. that is. 11 // Note that the cluster contains more than one vertex only if an edge containing a pair of 12 // the vertices has been added to the tree. 17 return tree T Viva questions: • What is prim’s algorithm? Where is it used? What is the Significance of prim’s algorithm? IMPLEMENTATION OF DIJKSTRA'S ALGORITHM USING PRIORITY QUEUES Ex. Assign to every node a distance value. if current node (A) has distance of 6. the distance to B through A will be 6+2=8. 4 Initialize a priority queue Q to contain all edges in G. E(1)=0.removeMin() 10 // prevent cycles in T. 13 Let C(v) be the cluster containing v. using the weights as keys. 2. • . For current node. 16 Merge C(v) and C(u) into one cluster.

its distance recorded now is final and minimal. v) if alt < dist[v]: dist[v] := alt previous[v] := u return previous[] // Relax (u. A visited node will not be checked ever again. 1 function Dijkstra(Graph.a) OUTPUT: Viva Questions: • What is queue? . When we are done considering all neighbours of the current node. mark it as visited.24 4. 5. source): 2 3 4 5 6 for each vertex v in Graph: dist[v] := infinity previous[v] := undefined dist[source] := 0 // Initializations // Unknown distance function from source to v // Previous node in optimal path from source // Distance from source to source Q := the set of all nodes in Graph // All nodes in the graph are unoptimized . // all remaining vertices are inaccessible alt := dist[u] + dist_between(u. Set the unvisited node with the smallest distance (from the initial node) as the next "current node" and continue from step 3 .v.thus are in Q 7 8 9 10 11 12 13 14 15 16 17 while Q is not empty: // The main loop u := vertex in Q with smallest dist[] if dist[u] = infinity: break remove u from Q for each neighbor v of u: // where v has not yet been removed from Q.

You can have some data-structure separate for each queue. Implementation of array based circular queue Ex. :11 Aim: To implement array based circular queue and to use the same for solving producer consumer problem Algorithm: .. Try to use at least 90% of the memory space. No. What is the cost of enqueue and dequeue? Can you improve this? What if the queue is full (I was using an looping array)? What kind of mechanism would you use to increase its size? • Give a good data structure for having n queues ( n not fixed) in a finite memory segment.25 • You know what a queue is ... Implement a queue class with Java.

:12 AIM:To implement priority queue using heaps. No. . Write any one application of array based circular queue. IMPLEMENTATION OF PRIORITY QUEUE USING HEAPS Ex.26 Viva questions: • • • What is an array? Write the Significance of array based circular queue.

count-1) start := start .27 ALGORITHM:function heapSort(a.1 while end > 0 do (swap the root(maximum value) of the heap with the last element of the heap) swap(a[end]. What is priority queue? Difference between calloc and malloc? • . root := start while root * 2 + 1 ≤ end do (While the root has at least one child) child := root * 2 + 1 (root*2+1 points to the left child) (If the child has a sibling and the child's value is less than its sibling's. a[child]) root := child (repeat to continue sifting down the child now) else return Viva questions: • • • What is malloc()? Define heap data structure.2) / 2 while start ≥ 0 do (sift down the node at index start to the proper place such that all nodes below the start index are in heap order) siftDown(a. a[0]) (decrease the size of the heap by one so that the previous max value will stay in its proper placement) end := end .. 0. end) function heapify(a. count) end := count ...1 (after sifting down the root all nodes/elements are in heap order) function siftDown(a.count) is (start is assigned the index in a of the last parent node) start := (count . count) is input: an unordered array a of length count (first place a in max-heap order) heapify(a.1 (put the heap back in max-heap order) siftDown(a. end) is input: end represents the limit of how far down the heap to sift. start.) if child + 1 ≤ end and a[child] < a[child + 1] then child := child + 1 (. start. then point to the right child instead) if a[root] < a[child] then (out of max-heap order) swap(a[root]..

No.28 IMPLEMENTATION OF BRANCH AND BOUND ALGORITHM Ex. :13 AIM:To implement the BRANCH AND BOUND ALGORITHM ALGORITHM:- .

:14 . No.29 Viva questions: • • What is traveling sales man problem? What is the significance of branch and bound algorithm? IMPLEMENTATION OF RANDOMIZED ALGORITHM (MINIMUM CUT) Ex.

.v) at random in G contract the edge.30 AIM:To implement the randomized algorithm of Minimum Cut. ALGORITHM:find_min_cut(undirected graph G) { while there are more than 2 nodes in G do { pick an edge (u. while preserving multi-edges remove all loops } output the remaining edges } Viva questions: • • What is minimum cut method? What is the Significance of randomized algorithm? IMPLEMENTATION OF TOPOLOGICAL SORT ON A DIRECTED GRAPH TO DECIDE IF IT IS ACYCLIC Ex No :15 AIM:To perform topological sort on a directed graph to decide if it is acyclic.

31 ALGORITHM:L ← Empty list that will contain the sorted elements S ← Set of all nodes with no incoming edges while S is non-empty do remove a node n from S insert n into L for each node m with an edge e from n to m do remove edge e from the graph if m has no other incoming edges then insert m into S if graph has edges then output error message (graph has at least one cycle) else output message (proposed topologically sorted order: L) .