You are on page 1of 22
Course Code: MCS-021 Course Title: Data and File Structures Assignment Number: MCA(II/021/Assignment/2020-2, ‘Maximum Marks: 100 Weightage: 25% Last Dates for Submission: 31st October, 2020 (For July, 2020 Session} {15th Aptil, 2021 (For January, 2021 Session) Q1: Write an algorithm that accepts a Tree as input and converts it into a Binary Tree and then prints all the leaf nodes that are part of both Tree and Binary Tree. Ans ftinclude Hinchide using namespace sté; // Data structure to store 2 Binary Tree node struct Node { intdata; Node “lett, “right; Node(int data) { this >data= data; this left = this-right nullpte; struct Trunk { Trunk “prey; string str Trunk\Trunk *prev, string st) ‘ // Helper function to print branches of the binary tree \oid showTrunks|Trunk *p) showTrunks(a->prev); cout << postr: 1] Recursive function to print binary tree Ht uses inorder traversal void printTree(Node *root, Trunk *prev, bool isLeft) { if (root == nuliptr) retum; string prev_st Trunk *trunk = new Trunk(prev, prev_str) printTree(root->left, trunk, true}; it (Iprev) trunk->ste else if (isteft) preveostr = prev_str; showTrunks(trunk): cout << reat-sdata ce endl if (prev) iev->str = prev_str; trunkestr=" |" printTree|root->right, trunk, false); } int main() { Node* root = nullpte; 1/ Construct above tree root =new Node(1): roct-sleft = new Nade(2); root aright = new Node(3); root-aleft-left = new Node!4); root >ieft->right = new Node(5); root->right >left = new Node(6); yew Node(?); jew Node(8); root->ieft->left->right = new Node{9); root-Dleft->right->ieft = new Node(10); roct-Sieft-sright->right = new Node(22); root aight sleft->ieft = new Node(12); root->rightoleft->right = new Node(13); roct->rightoright-left =new Node(4); roct->right->right-rright = new Node(15); 1/ print constructed binary tree printTreetroot, nulltr, false); return; Q2:|Is it possible to implement multiple stacks in a Queue. If Yes, (ils there any limit on the number of Stacks that can be implemented in a Queue. (ii) Implement two Stacks in a Queue. Ans. We are given a stack data structure with push and pop operations, the task is to implement a queue using instances of stack data structure and operations on them, rat Stack is Last in, first out insertion and Deletion — Tapper on stmne end op Queue Insertion and Deletion . Rappen on different ends x, nese _ First in first out ‘Aqueve can be implemented using two stacks. Let queue to be implemented be q and stacks used to implement q be stackl and stack2. q can be implemented in two ways: ‘Method 1 (By making en Queue operation costly) This method makes sure that oldest entered element is always at the top of stack 1, so that de Queue operation just pops from stack1. To put the element at top of stactt, stack? is used. endueueta, x): + While stack is not empty, push everything from stackd to stack2, '* Push xto stackl (assuming size of stacks unlimited). ‘© Push everything back to stackl. Here time complexity wil be O(n) deQueue(q): + If stack is empty then error ‘= Pop anitem from stack and return it Here time complexity will be O(2) 11. C++ program to implement Queue using // two stacks with costly enQueue() include using namespace std struct Queve { stackeint> 1,82; void enQuevetint x) t 1/ Move all elements from sito s2 while (Is1.emptyi)) { s2.push(sh.top0); s1.p0p(); ) 1) Pushitem intost si.pushix); // Push everything back tos while (Is2.emptyi)) { s1.push(s2.top0)); 82.p0p(); ' {7 Dequeve an item from the queue int dequeue!) t 116 est stackis empty if(sLempty())1 cout << "Qis Empty"; exit(O); ) 1) Retum top of st int x= s1.top(); s1.pop(); return x: 1 river code Jt mind) { Queue; qenQueve( 1}; q.enQueve(2); a.enQueve(3) cout << qdeQuevel) <<"\n'; cout << qdeQueuel) << "\n'; cout << qdeQueuel) << \n'; return; Complexity Analysis: + Time Complexity: + Push operation: O(N). In the worst case we have empty whole of stack 1 into stack 2 ‘+ Pop operation: O(1), Sameas pop operation in stack ‘+ Ausiliary Space: O(N). Use of stack for storing values. (Method 2 (By making deQueue operation costly)in this method, inen-queue operation, the new element is entered at the top of stack1. In de-queue operation, if stack? is empty then all the elements are moved to stack? and finally top of stack? is returned. endueue(q, *) 1) Push x to stack (assuming size of stacks is unlimited). Here time complexity will be O(1) deQueue(q| 1) Ifboth stacks are empty then error. 2) Ifstack2 is empty While stack1 is not empty, push everything from stackl to stack2. 3) Pop the element from stack2 and return it. Here time complexity wil be O(n) Method 2 is definitely better than method 1 Method 1 moves all the elements twice in endueue operation, while method 2 (in deQueue operation) moves the elements once and moves elements only if stack? empty. So, the amortized complexity of the dequeue operation becomes (-) (2), Implementation of method 2 /*C Program to implement a queue using two stacks include include /* structure ofa stack node struct stlode { int data; struct sNode* next h 7 Functionto push an item tostack"/ void push(struct sNode** top_ref, int new_data); /* Function to pop an item from stack*/ int poplstruct sNode** top_ref}: /* structure of queue having two stacks * struct queve { struct sNode* stack); struct sNode* stack2; h /* Function to enqueue an item to queve */ void enQueue(struct queue’ a, int x) { push(&q->stackt, x); /* Function to deQueue anitem from queve */ int deQueue(struct queve* q) { inte: [* i both stacks are empty then error */ if (qr>stackl == NULL && q->stack2 == NULL) { rintt("Q is empty”); getcharl); } cexit(0}; i J? Move elements from stackl to stack 2 only if stack2 Is empty */ if (@->stack2 == NULL) ( while (q>stackd != NULL) { x= pop(&q-stackl); ush(8q->stack2, »); t = popl&q->stack2); return x; /* Function to push an item to stack*/ void pushistruct sNode** top_ref, int new_data) ( ) [allocate node */ steuet sNede* new_nede = (struct sNede*)malloc(sizeof{struct sNode); if (new_node == NULL ( print "Stack overtiow \n"); getchar); exit(0); i I? putin the data */ new_node->dato =new_date; {7 link the old list off tne new node */ new_node->next =(*top_rel); {* move the head to I*top_refi = new node; to the new node */ /* Funetion to pop an item from stack*/ int pop(struct sNode** top_rel) { intres; struct sNode* top; , /* Driver function to test anove functions, {if stackis empty then error */ if *top_eof == NULL) { pinti(Stock underflow \ getchart exit; else { top = *top_ret; res =top->data; “top_tef = top->next: freeitop); return res; int main)) { } Output: * Create a queue with items 123*/ struct queue® q= struct queue* )malloc(sizeof(struct queue) q->stock = NULL; q->stack2 = NULL; enqueve(a 1); endueue(a, 2); endueuela, 3); I* Dequeve items */ print ('%6 ", deQueuela): prine("% ", dedueuelq print ('%¢ ", deQuevelq) return; 123 Complesity Analysis: ‘= Time Complexity: + Push operation: (2), Sameas pop operation in stack, + Pop operation: O(N) In the worst case we have empty whole of stack 1 into stack 2 + Auxiliary Space: O(N) Use of stack for storing values. Q3: List the names of all Algorithms along with their Complexities that find Minimum Cost Spanning Tree. List as many names as possible. Also, write the source of your finding adjacent to each Algorithm found. Ans. There are two famous algorithms for finding the Minimum Cost Spanning Tree: (2) Kruskat’s Aigorithm, ‘Kruskal's Algorithm bullds the spanning tree by adding edges one by one into a growing spanning tree, Kruskal's algorithm follows greedy approach as in each iteration it finds an edge which has least weight and add it to the growing spanning tree. ‘Algorithm steps: + Sort the graph edges with respect to their weights. ‘+ start adding edges to the MST from the edge with the smallest weight until the edge of the largest weight. ‘= Only add edges which doesn't form a cycle , edges which connect only disconnected components. Program 1/.C program for Kruska's algorithm to find Minimum Spanning Tree // of given connected, undirected and weighted graph include finclude finclude Ha structure to represent a weighted edge ingraph struct Edge { int src, dest, weight; h UJ structure to represent a connected, undirected //and weighted graph struct Graph ( J/ V-> Number of vertices, €-> Number of edges intv, & 1/ graph is represented as an array of edges. 1/ Since the graph is undirected, the edge 1/ from ste to dest is also edge from dest 1/0 ste, Both are counted as 1 edge here. struct Edge* edge; k Ul Creates 2 graph with V verticesand E edges struct Graph® createGraphiintV, int €) ( struct Graph* graph = new Graph; graph >V=V5 graph =; graph->edge = new EdgelE]; return graph 1 U) A structure to represent a subset for union find struct subset { int parent; int rang; h 1] Aulilty function to find set of an element i Ji (uses path compression technique) Int find(struct subset subsets[L inti) { J/ find root and make root as parent of i J/ (path compression) if (subsets{i] parent subsets] parent = find\subsets, subsets parent); return subsets[il_parent; , /( A function that does union of two sets of x andy 11 (uses union by rank) void Union(struct subset subsets[|, { x, int y) int xroot = find(subsets, x); int yroot = find{subsets, y); ({/ Attach smaller rank tree under root of high J/ rank tree (Union by Rank) if (subsetsfxroot].rank < subsetslyroot}.rank| ‘subsets|xroot}.parent = yroot; else if |subsets{xroot].rank > subsets{yroot].rank) ‘subsets|yroot] parent =xroot; 1/16 ranks are same, then make one as root and 1/ increment its rank by one else i subsets|yroot] paren subsets[xroot] rank++; ) | Compare two edges according to their weights, // Used in gsont) for sorting an array of edges int myComp(const void a, const void* b) { struct Edge* ai struct Edge" bi return al->weight > bi->weight; ) // the main function to construct MST using Kruskalsaigonthm void KruskalMST (struct Graph* graph) { int =graph>¥; struct Edge result[VI; // This will store the resultant MST int e =0; // An index variable, used for resutt{] inti=0; An index variable, used for sorted edges J/ Step 1:Sort all the edges in non-decressing J/ order of their weight. Itwe are rot allowed to J/ change the given graph, we can create a copy of I/ array of edges qsortigraph->edge, graph >, sizeof{graph-Pedgel Ol), myComp); } 1/ Allocate memory for creating V ssubsets struct subset *subsets = {struct subset") malloc( V * sizeot(struct subset) ); J/ Create V subsets with single elements for (int =0;vE) i // Step 2: Pick the smallest edge. And increment 1/ the index for next iteration struct Edge next_edge = graph->edgeli+4l; int x= find\subsets, next_edge.sre); int y= find|subsets, next_edge.dest); //\tinclading this edge does't cause cyte, 7/ include tin cesult and increment the index //of result for next edge if(k Ey) ‘ resultle++] = next_edge; Unionjeubeet, x9) , 1/ Else discard the next_edge t J/ print the contents of result] to display the J) built MST brintf("Following are the edges in the constructed MST\n") for(i=O;iedge0] src= 0; araph->edge0] dest graph->edge(0] weight = 10; Jf add edge 0-2 araph->edgel1} src= 0; araph>edge!1} des araph->edge|1] weight = 6; J/ add edge 0-3 araph->edgel2] src= 0; graph->edgel2] dest = 3; graph->edge|2] weight = 5; J/ add edge 1-3 graph >edge(3] src= 3; graph->edget3] dest = 3; graph >edge|3] weight If add edge 2-3 araph->edge[4] sre= 2; araph->edgels] dest = 3; graph >edge!4] weight KruskalMMST( graph); return; } Output: Following are the edges in the constructed MST (2) Prim’s algorithn Prim’s Algorithm also use Greedy approach to find the minimum spanning tree. In Prim’s Algorithm we grow the spanning tree from @ starting position. Unike an edge in Kruskal's, we add vertex to the growing spanning tree in Prim’s Algorithm steps: ‘+ Maintain two disjoint sets of vertices. One containing vertices that are in the growing spanning tree and other that are not in the growing spanning tree. ‘© Select the cheapest vertex that is connected to the growing spanning tree and isnot in the growing spanning tree and add it into the growing spanning tree. This can be done using Priority Queues. Insert the vertices, that are connected to growing spanning tree, into the Priority Queue. ‘= Checkfor cycles. To do that, mark the nodes which have been already selected andiinsert only those nodes in the Priority Queue that are not marked. Program TAC program for Prim's Minimum 1 Spansing Tree (MST) algorithm. The program is //or aciacency matrix representation of the graph include include include ‘// Number of vertices in the graph fidefine VS 7] Autilty function to find the vertex with / minimum key valve, irom the set of vertices 1 90t yet included in MST int minkey(int key{], boo! mstSet{) { (/itialize min value Int min = INT_MAX, min_index forint v=0;v

You might also like