Top Banner
Master of Computer Application (MCA) – Semester 2 MC0068 – Data Structures using Assignment Set – 1 Que 1. Describe the usage of pointers in functions with a suitable example. Ans: - Pointers Definition of pointer “A pointer is a variable that can hold the address of the variables, structures and functions that are used in the program. It contains only the memory location of the variable rather than its containts”. Pointers are used with followings: 1. Basic data type variable. 2. Array Subscript variable. 3. Function names. 4. Structure and Union names. Advantages of Pointers: 1. Pointers are pointing to different data types and structures 2. Manipulation of data at different memory locations is easier. 3. To achieve a clarity and simplicity 4. More compact and efficient coding. 5. To return multiple value via functions. 1
27

(MC0068)data structure

Oct 14, 2014

Download

Documents

Hemant Soni

download MCA 2nd sem and 3rrd sem assignment (7737397502)
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: (MC0068)data structure

Master of Computer Application (MCA) – Semester 2MC0068 – Data Structures using

Assignment Set – 1

Que 1. Describe the usage of pointers in functions with a suitable example.

Ans: - Pointers

Definition of pointer

“A pointer is a variable that can hold the address of the variables, structures and functions that are used in the program. It contains only the memory location of the variable rather than its containts”.

Pointers are used with followings:

1. Basic data type variable.

2. Array Subscript variable.

3. Function names.

4. Structure and Union names.

Advantages of Pointers:

1. Pointers are pointing to different data types and structures

2. Manipulation of data at different memory locations is easier.

3. To achieve a clarity and simplicity

4. More compact and efficient coding.

5. To return multiple value via functions.

6. Dynamic memory allocations.

1.3 Declaring a pointer variable

Pointers are declared similar to normal variables, but we must specify when we declare them what they are going to point to it. We declare a pointer to point to an integer, then it cant be used to point a floating-point value etc.

1

Page 2: (MC0068)data structure

1.3.1 Pointer Operators:

To declare and refer a pointer variable, provides two special operators & and *.

1. Address Operator (ampersand) : &

2. Indirectional Operator: *

& ß (ampersand ) This Operator gives the memory Address of the variable.

* ß This Operator gives the value of the variable.

Example: if i = 100

Example:

Program to assign the pointer values. (using operator & and *)

#include< iostream.h>

#include<conio.h>

main( )

{

int *x, y; /* x is pointer to integer variable */

clrscr ( );

y = 10;

x = &y; /* y value stored in pointer x.*/

printf( “Address of y = %d n ” , &y);

printf (“value of y = %d n” , y);

printf( “Address of y = %d n ” , x);

printf( “value of y = %d n ”, *x);

}

Output

Address of y = 655552

Page 3: (MC0068)data structure

Value of y = 10

Address of y = 65555

Value of y = 10

Que 2. Demonstrate with your own programming example the usage of structures within an array.

Ans:-Structures

Definitions: Structure is a meaningful organized Collection of data items of different type under a unique name that name we called as structure name.

In ‘C’ declaration of such related data items or fields of different types by using reserve word ‘struct’.

Declaration of structure

Each and every structure must be defined or declared before it appears or using in program.

Syntax: struct <structure name>

{

<type1> <field/data1>

<type2> <field/data2>

<type3> <field/data3>

………………………

……………………….

<type n> <field/data n>

};

Structure used with an Array

We know that different type of data sets cannot be stored an array, so, to overcome this disadvantage structure can be stored along with its members in array structure.

3

Page 4: (MC0068)data structure

Example:-

/* array of data structure*/#include <iostream>#include <string>#include <sstream>using namespace std;

#define N_MOVIES 3

struct movies_t { string title; int year;} films [N_MOVIES];

void printmovie (movies_t movie);

int main (){ string mystr; int n;

for (n=0; n<N_MOVIES; n++) { cout << "Enter title: "; getline (cin,films[n].title); cout << "Enter year: "; getline (cin,mystr); stringstream(mystr) >> films[n].year; }

cout << "\nYou have entered these movies:\n"; for (n=0; n<N_MOVIES; n++) printmovie (films[n]); return 0;}

void printmovie (movies_t movie){ cout << movie.title; cout << " (" << movie.year << ")\n";}

Out put:-

Enter title: Blade RunnerEnter year: 1982Enter title: MatrixEnter year: 1999Enter title: Taxi Driver

4

Page 5: (MC0068)data structure

Enter year: 1976 You have entered these movies:Blade Runner (1982)Matrix (1999)Taxi Driver (1976)

Que 3. Explain the theory of non linear data structures.

Ans:-

Non Linear Data Structures

Trees

A tree Is often used to represent a hierarchy. This is because the relationships between the Items In the hierarchy suggest the branches of a botanical tree.

a tree-like organization charts often used to represent the lines of responsibility in a business as shown in Figure. The president of the company is shown at the top of the tree and the vice-presidents are indicated below her. Under the vice-presidents we find the managers and below the managers the rest of the clerks. Each clerk reports to a manager. Each manager reports to a vice-president, and each vice-president reports to the president.

The tree is upside-down. However, this is the usual way the data structure is drawn. The president is called the root of the tree and the clerks are the leaves.

A tree is extremely useful for certain kinds of computations. For example. Suppose we wish to determine the total salaries paid to employees by division or by department. The total of the salaries in division A can be found by computing the sum of the salaries paid in departments Al and A2 plus the salary of the vice-president of division A. Similarly. The

5

Page 6: (MC0068)data structure

total of the salaries paid in department Al is the sum of the salaries of the manager of department Al and of the two clerks below her.

Clearly, in order to compute all the totals. It is necessary to consider the salary of every employee. Therefore, an implementation of this computation must visit all the employees in the tree. An algorithm that systematically visits all the items in a tree is called a tree traversal.

In the same chapter we consider several different kinds of trees as well as several different tree traversal algorithms. In addition. We show how trees can be used to represent arithmetic expressions and how we can evaluate an arithmetic expression by doing a tree traversal. The following is a mathematical definition of a tree:

Definition (Tree) A tree T is a finite. Non-empty set of nodes ,

T = {r} U TI, U T2 U …U Tn with the following properties:

3. A designated node of the set, r, is called the root of the tree: and

4. The remaining nodes are partitioned into n≥ O subsets T, T. …Tn each of which is a tree for convenience, we shall use the notation T= {r. T, T, …T} denote the tree T.

Binary Tree

Each element in a binary tree is stored in a "node" class (or struct). Each node contains pointers to a left child node and a right child node. In some implementations, it may also contain a pointer to the parent node. A tree may also have an object of a second "tree" class (or struct) which as a header for the tree. The "tree" object contains a pointer to the root of the tree (the node with no parent) and whatever other information the programmer wants to squirrel away in it (e.g. number of nodes currently in the tree).

In a binary tree, elements are kept sorted in left to right order across the tree. That is if N is a node, then the value stored in N must be larger than the value stored in left-child(N) and less than the value stored in right-child(N). Variant trees may have the opposite order (smaller values to the right rather than to the left) or may allow two different nodes to contain equal values.

Hash Tables

A very common paradigm in data processing involves storing information in a table and then later retrieving the information stored there. For example, consider a database of driver’s license records. The database contains one record for each driver’s license issued. Given a driver’s license number. we can look up the information associated with that number. Similar operations are done by the C compiler. The compiler uses a symbol table to keep track of the user-defined symbols in a Java program. As it compiles a program, the compiler inserts an entry in the symbol table every time a new symbol is declared. In

6

Page 7: (MC0068)data structure

addition, every time a symbol is used, the compiler looks up the attributes associated with that symbol to see that it is being used correctly.

Typically the database comprises a collection of key-and-value pairs. Information is retrieved from the database by searching for a given key. In the case of the driver’~ license database, the key is the driver’s license number and in the case of the symbol table, the key is the name of the symbol.

In general, an application may perform a large number of insertion and/ or look-up operations. Occasionally it is also necessary to remove items from the database. Because a large number of operations will be done we want to do them as quickly as possible.

Hash tables are a very practical way to maintain a dictionary. As with bucket sort, it assumes we know that the distribution of keys is fairly well-behaved.

Once you have its index. A hash function is a mathematical function which maps keys to integers.

In bucket sort, our hash function mapped the key to a bucket based on the first letters of the key. "Collisions" were the set of keys mapped to the same bucket. If the keys were uniformly distributed. Then each bucket contains very few keys!

The resulting short lists were easily sorted, and could just as easily be searched

We examine data structures which are designed specifically with the objective of providing efficient insertion and find operations. In order to meet the design objective certain concessions are made. Specifically, we do not require that there be any specific ordering of the items in the container. In addition, while we still require the ability to remove items from the container, it is not our primary objective to make removal as efficient as the insertion and find operations.

Ideally we would’ build a data structure for which both the insertion and find operations are 0(1) in the worst case. However, this kind of performance can only be achieved with complete a priori knowledge. We need to know beforehand specifically which items are to be inserted into the container. Unfortunately, we do not have this information in the general case. So, if we cannot guarantee 0(1) performance in the worst case, then we make it our design objective to achieve 0(1) performance in the average case.

7

Page 8: (MC0068)data structure

The constant time performance objective immediately leads us to the following conclusion: Our implementation must be based in some way Kh element of an array in constant time, whereas the same operation in a linked list takes O{k) time.

In the previous section, we consider two searchable containers-the ordered list and the sorted list. In the case of an ordered list, the cost of an insertion is 0(1) and the cost of the find operation is O(n). For a sorted list the cost of insertion is O(n) and the cost of the find operation is O(log n) for the array implementation.

Clearly, neither the ordered list nor the sorted list meets our performance objectives. The essential problem is that a search, either linear or binary, is always necessary. In the ordered list, the find operation uses a linear search to locate the item. In the sorted list, a binary search can be used to locate the item because the data is sorted. However, in order to keep the data sorted, insertion becomes O(n).

In order to meet the performance objective of constant time insert and find operations. we need a way to do them without performing a search. That is, given an item x, we need to be able to determine directly from x the array position where it is to be stored.

Que 4. Write a program in C showing the implementation of stack operations using structures.

Ans:-

// Stack Implementation using arrays to Insert element in the Stack

#include<stdio.h>

#include<conio.h>

#define Max 5

int Staff (Max] , top=-l;

void display( )

{

if ((top= =-l) || (top= =0))

{

printf{"n Stack is full n");

}

8

Page 9: (MC0068)data structure

else

{

printf{"n Stack elements are n”);

for(int i=top-1;i>=0;i–)

printf("%5d", Staff([i]);

}

}

void push ( )

{

int ele;

char ch;

if(top-=-l)

top=0;

do

{ if(top>=5)

{

printf(“n STACK IS FULL”);

break;

}

else

{ clrscr( );

printf ("nENTER THE ELEMENT TO BE INSERTEDn") ;

scanf("%d",&ele) ;

Staff(top++]=ele;

display ( ) ; 9

Page 10: (MC0068)data structure

}

printf ("nDO U WANT 2 ADD MORE ELEMENTS:?n");

scanf ( "n%c" , &ch);

} while ( (ch= =’y’ ) || (ch==’Y’ ) );

}

void pop ( )

{

if ( (top= =-l) || (top= =0))

{

printf ("nstack is under flown");

}

else

{

printf{"n %d is deleed from stackn",Staff(–top]) ;

display( );

}

}

Que 5. Describe the theory and applications of Double Ended Queues (Deque) and circular queues.Ans:

Double ended queue (Deque)

Deque is a special type of data structure in which insertions and deletions will be done either at the front end or at the rear end of the queue. The operations that can be performed on deques are

10

Page 11: (MC0068)data structure

· Insert an item from front end

· Insert an item from rear end

· Delete an item from front end

· Delete an item from rear end

· Display the contents of queue

The three operations insert rear, delete front and display and the associated operations to check for an underflow and overflow of queue have already been discussed in ‘ordinary queue’. In this section, other two operations i.e., insert an item at the front end and delete an item from the rear end are discussed.

Function to insert an item at the front end

void insert_front(int item, int q[ ], int *f, int *r)

{

if( *f= = 0 && *r = = -1)

q[++(*r)] = item;

11

Page 12: (MC0068)data structure

else if ( *f ! = 0)

q[--(*f)]=item;

else

printf("Front insertion not possiblen");

}

b) Delete from the rear end

To delete an element from the rear end, first access the rear element and then decrement rear end identified by r. As an element is deleted, queue may become empty. If the queue is empty, reset the front pointer f to 0 and rear pointer r to -1 as has been done in an ordinary queue. We delete an element only if queue is not empty. The complete C function to delete an item from the rear end is shown in below example.

Function to delete an item from the rear end of queue

void delete_rear(int q[],int *f, int *r)

{

if ( qempty(*f,*r) )

{

printf("Queue underflown");

return;

}

printf("The element deleted is %dn".q[(*r)--]);

if (*f > *r)

{

*f = 0, *r = -1 ;

}

}

C program to Implement double-ended queue

#include <stdio.h> 12

Page 13: (MC0068)data structure

#include <process.h>

#define QUEUE_SIZE 5

void main()

{

int choice,item,f,r,q [10];

f=0; r = -1;

for (;;)

{

printf(" 1:Insert_front 2:lnsert_rearn");

printf("3: Delete_front 4: Delete_rearn" );

printf("5: Display 6:Exitn");

printf("Enter the choicen");

scanf("%d" ,&choice );

switch ( choice )

{

case 1:

printf("Enter the item to be insertedn");

scanf("%d",& item);

insert_ front(item, q, &f, &r);

break;

case 2:

printf("Enter the item to be insertedn");

scanf("%d",& item);

insert_rear(item, q, &r);

break; case 3: 13

Page 14: (MC0068)data structure

delete _front(q, &f, &r);

break;

case 4:

delete_rear(q, &f, &r);

break;

cases 5:

display(q, f, r);

break;

default: .

exit(0);

}

}

}

Circular queue

In an ordinary queue, as an item is inserted, the rear end identified by r is incremented by 1. Once r reaches QUEUE_SIZE -1, we say queue is full. Note that even if some elements are deleted from queue, because the rear end identified by r is still equal to QUEUE_SIZE-l, item cannot be inserted. Pot details refer in Disadvantage of ordinary queue. This disadvantage is overcome using circular queue. The pictorial representation of a circular queue and its equivalent representation using an array are given side by side in below fig in next page.

Assume that circular queue contains only one item as shown in below fig. (a). In this case, the rear end identified by r is 0 and front end identified by f is also 0. Since rear end is incremented while insertion, just before inserting the first item, the value ‘of r should be -1 (Note: An item is inserted only at the rear end and so, only r is incremented by 1 and not f) so that after insertion, f and r points to an item 10. So, naturally, the initial values of f and r should be 0 and -1.

The configuration shown in below fig. (b) is obtained after inserting 20 and 30. To insert an item, the rear pointer r has to be incremented first. For this, any of the two statements shown below can be used.

14

Page 15: (MC0068)data structure

r = r + l or r = (r + 1) %QUEUE_SIZE

Both statements will increment r by 1. But, we prefer the second statement. We see why this method is preferred instead of a simple statement

r= r+1

The queue shown in fig.(c) is obtained after inserting 40 and 50. Note that at this point, the queue is full. Suppose we delete two items 10 and 20 one after the other. The resulting queue is shown in fig. (d). Now try to insert an item 60. If the statement

r= r+1

is used to increment rear pointer, the value of r will be 5. But because this is a circular queue r should point to 0. This can be achieved using the statement

15

Page 16: (MC0068)data structure

r = (r + 1) % QUEUE_SIZE

}

a) To insert from the front end

Note that insertion is done only when queue is not full. So, if queue is not full, to insert an item, increment rear end identified by r by 1 and then insert. Also, as an item is inserted update the value of count by 1. The variable count is used to check for overflow or underflow. The function to insert an item into the queue is shown in the above example 3.

b) To delete from front end

As in an ordinary queue, the element at the front end of the queue has to be deleted. ‘So, access an item which is at the front end by specifying q[f] and update the front end identified f to point to next front item. The front end identified by f can be incremented using the following statement

f= (f+ 1) % QUEUE_SIZE

c) To display queue contents

If queue is not empty, elements in the queue should be displayed from the front end identified by f to the rear end identified by r. The total number of items to be displayed can be obtained from the variable count. This can be achieved by initializing the index variable i to the front end identified by f and incrementing i each time using the statement

i= (i + 1)% QUEUE_SIZE;

count number of times. As the index variable i point to the each item in the queue, the queue contents can be accessed and displayed one by one.

Que 6. With the help of a suitable numerical example, describe the following concepts of a Binary Search Tree: A) Analysis of BST

16

Page 17: (MC0068)data structure

B) Insertion of Nodes into a BSTAns:

Analyzing the BST Search Algorithm

For finding a node in a BST, at each stage we ideally reduce the number of nodes we have to check by half. For example, consider the BST in Figure 1.3, which contains 15 nodes. When starting our search algorithm at the root, our first comparison will take us to either the root’s left or right child. In either case, once this step is made the number of nodes that need to be considered has just halved, from 15 down to 7. Similarly, at the next step the number is halved again, from 7 down to 3, and so on.

Figure: BST with 15 nodes

The important concept to understand here is that ideally at each step in the algorithm the number of nodes that have to be considered has been cut in half. Compare this to searching an array. When searching an array we have to search all elements, one element at a time. That is, when searching an array with n elements, after we check the first element, we still have n – 1 elements to check. With a BST of n nodes, however, after checking the root we have whittled the problem down to searching a BST with n/2 nodes.

Searching a binary tree is similar in analysis to searching a sorted array. For example, imagine you wanted to find if there is a John King in the phonebook. You could start by flipping to the middle of the phone book. Here, you’d likely find people with last names starting with the letter M. Because K comes before M alphabetically, you would then flip halfway between the start of the phonebook and the page you had reached in the Ms. Here, you might end up in the Hs. Since K comes after H, you’d flip half way between the Hs and the Ms. This time you might hit the Ks, where you could quickly see if James King was listed.

Inserting Nodes into a BST

We’ve seen how to search a BST to determine if a particular node exists, but we’ve yet to look at how to add a new node. When adding a new node we can’t arbitrarily add the new

17

Page 18: (MC0068)data structure

node; rather, we have to add the new node such that the binary search tree property is maintained.

When inserting a new node we will always insert the new node as a leaf node. The only challenge, then, is finding the node in the BST which will become this new node’s parent. Like with the searching algorithm, we’ll be making comparisons between a node c and the node to be inserted, n. We’ll also need to keep track of c’s parent node. Initially, c is the BST root and parent is a null reference. Locating the new parent node is accomplished by using the following algorithm:

Step 1: If c is a null reference, then parent will be the parent of n. If n’s value is less than parent’s value, then n will be parent’s new left child; otherwise n will be parent’s new right child.

Step 2: Compare c and n’s values.

Step 3: If c’s value equals n’s value, then the user is attempting to insert a duplicate node. Either simply discard the new node, or raise an exception. (Note that the nodes’ values in a BST must be unique.)

Step 4: If n’s value is less than c’s value, then n must end up in c’s left subtree. Let parent equal c and c equal c’s left child, and return to step 1.

Step 5: If n’s value is greater than c’s value, then n must end up in c’s right subtree. Let parent equal c and c equal c’s right child, and return to step 1.

18

Page 19: (MC0068)data structure

19

Page 20: (MC0068)data structure

Que 7. Explain the Bellman Ford algorithm with respect to Minimum Spanning Trees.

Ans:

Bellman-Ford Algorithm

It is a more generalized single-source shortest path algorithm which can find the shortest path in a graph with negative weighted edges. If there is no negative cycle in the graph, this algorithm will updates each d[v] with the shortest path from s to v, fill up the predecessor list "pi", and return TRUE. However, if there is a negative cycle in the given graph, this algorithm will return FALSE.

BELLMAN_FORD(Graph G,double w[ ][ ],Node s)

  initialize_single_source(G,s)

  for i=1 to |V[G]|-1

    for each edge (u,v) in E[G]

      relax(u,v,w)

  for each edge (u,v) in E[G]

    if d[v] > d[u] + w(u, v) then

      return FALSE

  return TRUE

Que 8. Explain the following graph problems: A) Telecommunication problem B) Knight Moves

Ans:A) Telecommunication problem :-

Given a set of computers and a set of wires running between pairs of computers, what is the minimum number of machines whose crash causes two given machines to be unable to communicate? (The two given machines will not crash.)

20

Page 21: (MC0068)data structure

Graph: The vertices of the graph are the computers. The edges are the wires between the computers. Graph problem: minimum dominating sub-graph.

B) Sample Problem: Riding The FencesC)

D) Farmer John owns a large number of fences, which he must periodically check for integrity. He keeps track of his fences by maintaining a list of points at which fences intersect. He records the name of the point and the one or two fence names that touch that point. Every fence has two end points, each at some intersection point, although the intersection point may be the end point of only one fence.

E) Given a fence layout, calculate if there is a way for Farmer John to ride his horse to all of his fences without riding along a fence more than once. Farmer John can start and finish anywhere, but cannot cut across his fields (i.e., the only way he can travel between the intersection points is along a fence). If there is a way, find one way.

F) Graph: Farmer John starts at intersection points and travels between the points along fences. Thus, the vertices of the underlying graph are the intersection points, and the fences represent edges. Graph problem: Traveling Salesman Problem.

B) Knight Moves

G) Given: Two squares on an 8×8 chessboard. Determine the shortest sequence of knight moves from one square to the other.

H)

I) Graph: The graph here is harder to see. Each location on the chessboard represents a vertex. There is an edge between two positions if it is a legal knight move. Graph Problem: Single Source Shortest Path.

J)

K) Overfencing

L) Farmer John created a huge maze of fences in a field. He omitted two fence segments on the edges, thus creating two “exits” for the maze. The maze is a “perfect” maze; you can find a way out of the maze from any point inside it.

M) Given the layout of the maze, calculate the number of steps required to exit the maze from the “worst” point in the maze (the point that is “farther” from either exit when walking optimally to the closest exit).

N) Here’s what one particular W=5, H=3 maze looks like:

21

Page 22: (MC0068)data structure

Graph: The vertices of the graph are positions in the grid. There is an edge between two vertices if they represent adjacent positions that are not separated by a wall. Graph problem: Shortest Path.

22