# MCS-021 Data and File Structures

____________________________________________________________________________ Course Code : MCS-021 Course Title : Data and File Structures Assignment Number : MCA (2)/021/Assign/09 ___________________________________________________________________________ Question 1: How can the following operations implemented on an array so that the time taken for each of the operations does not depend on the size of the array ‘n’: (i) Delete the ith element of an array (1 < = i < = n) (ii) Delete the ith element of a sorted array. The remaining array has to stay sorted. Answer 1. i) to void delete (int pos) { int item; if ( pos < n) { item = a[ pos ]; printf(“ no deleted is = %d”, item); } else printf (“pos in out of array “); } ii) void delete ( int pos ) { int item; if ( pos < n ) { item = a [pos ]; printf (“ no deleted is = %d”, item ); } else printf (“ position is out of array”); for ( I = pos + 1; I < n; I ++) { a[i] = a [ I + 1]; } } }

Question 2: Map the operations on Stacks and Queues to operations on a Deque. Explain the merits of using a Deque to implement a Stack. Also, explain the merits of using a Deque to implement a Queue. Answer /* Program implement deque using an pointers*/ //include header files #include<stdio.h> #include<conio.h> #define SIZE 5//its value remains constant //Declaration of structure typedef struct deque { int Arr[SIZE]; int front; int rear; }deque; /* Declaration of functions */ //Function to display the menu void menu(); //Function to initialise the deque void initdeque(deque *); //Function to add an element in the beginning int enqueBeg(deque *,int ); //Function to add an element in the end int enqueEnd(deque *,int ); //Function to serve an element from the beginning int dequeueBeg(deque *,int *); //Function to serve an element from the end int dequeueEnd(deque *,int *); //Function to check if the deque is empty int IsEmpty(deque ); //Function to check if the deque is full int IsFull(deque ); //Function to display the deque elements void display (deque ); void main() { clrscr(); menu(); //Function call getch(); } void menu() { deque dq; int info,choice,call,flag; call=flag=0; //To initialise.. initdeque(&dq); //Function call while(1)//at least it will run for once { //Displaying menu clrscr(); printf(" MENU\n"); printf(" 1. En-queue/Append in the beginning\n");

printf(" 2. En-queue/Append in the end\n"); printf(" 3. De-queue/Serve from the beginning\n"); printf(" 4. De-queue/Serve from the end\n"); printf(" 5. IsEmpty\n"); printf(" 6. IsFull\n"); printf(" 7. Display\n"); printf(" 8. Exit\n"); printf("Your choice: "); scanf("%i",&choice); switch(choice) { case 1: printf("Enter the element to be added in the beginning:"); scanf("%i",&info); call=enqueBeg(&dq,info); //Function call for adding at the beginning. if(call)//if some value is returned other than zero. printf("Element added in the beginning!"); else printf("Element can't be added!"); getch(); break; case 2: printf("Enter the element to be added in the end: "); scanf("%i",&info); call=enqueEnd(&dq,info); //Function call[En-queue/Append in the end] if(call)//if some value is returned other than zero. printf("Element added in the end!"); else printf("Element can't be added!"); getch(); break; case 3: info=dequeueBeg(&dq,&flag); //Function call for deleitng from begining.[Dequeue/ Serve from the beginning] if(flag) printf("Popped out element is %i",info); else printf("Element can't be popped out from the beginning!"); getch(); break; case 4: info=dequeueEnd(&dq,&flag); //Function call for deleitng at the end.[Dequeue/ Serve from the end] if(flag) printf("Popped out element is %i",info); else printf("Element can't be popped out from the end!"); getch(); break; case 5: if(IsEmpty(dq)) //Function call printf("Deque is empty!"); else printf("Deque is not empty!"); getch(); break;

case 6: if(IsFull(dq)) //Function call printf("Deque is full!"); else printf("Deque is not full!"); //Note:We can implement isFull() and isEmpty() using bool concept also in which we return //true and false values only. getch(); break; case 7: display(dq); //Function call getch(); break; case 8: exit(); default: printf("You entered wrong choice!"); getch(); } } } void initdeque(deque *deq)//initialising the deque. { deq->front=deq->rear=-1; } int enqueBeg(deque *deq,int info) { int i; //To check if the queue is full if(deq->front==0 && deq->rear==SIZE-1) //If the queue is full... return 0; //...element can't be added in deque //If dequeue is empty then first element can be simply added if(deq->front==-1) { deq->front=deq->rear=0;//both fornt,rear point to first element. deq->Arr[deq->front]=info; return 1; //Flag success to the function } //If the deque is full from the front only... if(deq->front==0 && deq->rear!=SIZE-1) { //...shift the elements from 1 posn to it's right for(i=deq->rear;i>=deq->front;i--) deq->Arr[i+1]=deq->Arr[i]; //Index no. of last element should be incremented after shifting deq->rear++; //New element will be added in the front of deque deq->Arr[deq->front]=info; } //if the deque is empty from the front... else if(deq->front>0) { deq->front--; //...new element will be accomodated in the empty cell deq->Arr[deq->front]=info; } return 1; } int enqueEnd(deque *deq,int info)

{ int i; //To check if the queue is full if(deq->front==0 && deq->rear==SIZE-1) //If the queue is full... return 0; //...element can't be added in deque //If dequeue is empty then first element can be simply added if(deq->front==-1) { deq->front=deq->rear=0; deq->Arr[deq->front]=info; return 1; //Flag success to the function } //If the deque is full from the end only... if(deq->front!=0 && deq->rear==SIZE-1) { //...shift the elements from 1 posn to its left for(i=deq->front;i<=deq->rear;i++) deq->Arr[i-1]=deq->Arr[i]; //Index no. of first element should be decremented after shifting deq->front++; //New element will be added in the end of deque deq->Arr[deq->rear]=info; } //if the deque is empty from the end... else if(deq->rear<SIZE-1) { deq->rear++; //...new element will be accomodated in the empty cell deq->Arr[deq->rear]=info; } return 1; } int dequeueBeg(deque *deq,int *flag) { int info; //If the deque is empty... return 0; //...element can't be added in deque //If dequeue is empty then first element can be simply added if(deq->front==-1) { deq->front=deq->rear=0; deq->Arr[deq->front]=info; return 1; //Flag success to the function } //If the deque is full from the end only... if(deq->front!=0 && deq->rear==SIZE-1) { //...shift the elements from 1 posn to its left for(i=deq->front;i<=deq->rear;i++) deq->Arr[i-1]=deq->Arr[i]; //Index no. of first element should be decremented after shifting deq->front++; //New element will be added in the end of deque deq->Arr[deq->rear]=info; } //if the deque is empty from the end...

else if(deq->rear<SIZE-1) { deq->rear++; //...new element will be accomodated in the empty cell deq->Arr[deq->rear]=info; } return 1; } int dequeueBeg(deque *deq,int *flag) { int info; //If the deque is empty... *flag=1; //Success //Setting rear if(deq->front==deq->rear) deq->front=deq->rear=-1; //As the deque will become empty else deq->rear--; //Rear cell is unoccupied now return info; //Returning the info } int IsEmpty(deque deq) { if(deq.front==-1) return 1; //Is empty else return 0; //Is not empty } int IsFull(deque deq) { if(deq.front==0 && deq.rear==SIZE-1) return 1; //Is full else return 0; //Is not full } /*displays the curent position of the dqueue*/ void display (deque deq) { int i; //If the deque is empty... if(IsEmpty(deq)) { printf("The deque is empty!"); return; //...end of function } //Displaying the deque elments for(i=(deq.front);i<=(deq.rear);i++) printf("%i\t",deq.Arr[i]); } /*output of the program*/ MENU 1. En-queue/Append in the beginning 2. En-queue/Append in the end 3. De-queue/Serve from the beginning 4. De-queue/Serve from the end 5. IsEmpty 6. IsFull

7. Display 8. Exit your choice 1 enter the element to be added at the beginning 5 MENU 1. En-queue/Append in the beginning 2. En-queue/Append in the end 3. De-queue/Serve from the beginning 4. De-queue/Serve from the end 5. IsEmpty 6. IsFull 7. Display 8. Exit Your choice: 2 enter the element to be added at the end 50 MENU 1. En-queue/Append in the beginning 2. En-queue/Append in the end 3. De-queue/Serve from the beginning 4. De-queue/Serve from the end 5. IsEmpty Question 3: Implement a modified version of Dijkstra’s algorithm such that it finds the shortest paths from a given vertex to all other vertices in a network. Answer Dijkstra's algorithm solves the single-source shortest-path problem when all edges have nonnegative weights. It is a greedy algorithm and similar to Prim's algorithm. Algorithm starts at the source vertex, s, it grows a tree, T, that ultimately spans all vertices reachable from S. Vertices are added to T in order of distance i.e., first S, then the vertex closest to S, then the next closest, and so on. Following implementation assumes that graph G is represented by adjacency lists. DIJKSTRA (G, w, s) 1. INITIALIZE SINGLE-SOURCE (G, s) 2. S ‹ { } // S will ultimately contains vertices of final shortest-path weights from s 3. Initialize priority queue Q i.e., Q ‹ V[G] 4. while priority queue Q is not empty do 5. u ‹ EXTRACT_MIN(Q) // Pull out new vertex 6. S ‹ S {u} // Perform relaxation for each vertex v adjacent to u 7. for each vertex v in Adj[u] do 8. Relax (u, v, w) Analysis Like Prim's algorithm, Dijkstra's algorithm runs in O(|E|lg|V|) time. Example: Step by Step operation of Dijkstra algorithm. Step1. Given initial graph G=(V, E). All nodes nodes have infinite cost except the source node, s, which has 0 cost. Step 2. First we choose the node, which is closest to the source node, s. We initialize d[s] to 0. Add it to S. Relax all nodes adjacent to source, s. Update predecessor (see red arrow in diagram below) for all nodes updated.

Step 3. Choose the closest node, x. Relax all nodes adjacent to node x. Update predecessors for nodes u, v and y (again notice red arrows in diagram below). Step 4. Now, node y is the closest node, so add it to S. Relax node v and adjust its predecessor (red arrows remember!). Step 5. Now we have node u that is closest. Choose this node and adjust its neighbor node v. Step 6. Finally, add node v. The predecessor list now defines the shortest path from each node to the source node, s. Q4 A red-black tree is a binary search tree with one extra attribute for each node: the colour, which is either red or black. We also need to keep track of the parent of each node, so that a redblack tree's node structure would be: struct t_red_black_node { enum { red, black } colour; void *item; struct t_red_black_node *left, *right, *parent; } For the purpose of this discussion, the NULL nodes which terminate the tree are considered to be the leaves and are coloured black. Definition of a red-black tree A red-black tree is a binary search tree which has the following red-black properties: 1. Every node is either red or black. 2. Every leaf (NULL) is black. 3. If a node is red, then both its children are black. 4. Every simple path from a node to a descendant leaf contains the same number of black nodes. 3. Implies that on any path from the root to a leaf, red nodes must not be adjacent. However, any number of black nodes may appear in a sequence. A basic red-black Tree. Question 4: Show the effect of making the following insertions into an initially empty redblack tree: 30, 40,20,90,10,50,70,60,80 Answer Every node in a red black tree is colored either red or black . they gaurentee O(log n) time per access to adjusting tree structure so that the following projection are always maintained. - the root is always black. - Every path on the tree , from the root down to exterior , has the same number of black node. - No red node has a red child.