Top Banner
Vidyalankar Vidyalankar Vidyalankar Vidyalankar S.E. Sem. III [CMPN] Data Structures & Files Prelim Question Paper Solutions 1. (a) Recursion is the process of defining something in terms of itself. It is the attribute that allows a method to call itself. A method that calls itself is said to be recursive. Tower of Hanoi The problem can be defined as follows: - There are three pegs say A, B and C and n discs of different radii. All the n discs are stored in peg A with the increasing radii from top to bottom. The aim is to shift all n discs from peg A to peg B but by obeying the following rules: 1) Only one disc can be moved at a time. 2) Only disc at the top of the peg can be moved. 3) A disc with larger radii should not be kept on a disc with lower radii at any point of time. The problem can be conveniently solved using recursion as given below:- import java.util.*; class TowerOfHanoi { public void hanoi (int n, char from, char to, char aux) { if (n==1) System.out.println("Move a disc from peg "+from+" to peg "+to); else { hanoi(n-1, from, aux, to); hanoi(1, from, to, aux); hanoi(n-1, aux, to , from); } } } class TowerExp { public static void main(String args[ ]) { Scanner src=new Scanner(System.in); System.out.println("Enter no of discs"); int num=src.nextInt(); TowerOfHanoi obj=new TowerOfHanoi(); obj.hanoi(num,'A','B','C'); } } Here the user has to give the number of disc and depending on that the program will display the required moves. The sample output is shown for 3 discs. Sample Output : Enter no of discs 3 Move a disc from peg A to peg B Move a disc from peg A to peg C Move a disc from peg B to peg C Move a disc from peg A to peg B Move a disc from peg C to peg A
26
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: DSF

VidyalankarVidyalankarVidyalankarVidyalankar S.E. Sem. III [CMPN]

Data Structures & Files Prelim Question Paper Solutions

1. (a) Recursion is the process of defining something in terms of itself. It is the attribute that allows a

method to call itself. A method that calls itself is said to be recursive.

Tower of Hanoi

The problem can be defined as follows: - There are three pegs say A, B and C and n discs of different radii. All the n discs are stored in peg

A with the increasing radii from top to bottom. The aim is to shift all n discs from peg A to peg B

but by obeying the following rules: 1) Only one disc can be moved at a time.

2) Only disc at the top of the peg can be moved.

3) A disc with larger radii should not be kept on a disc with lower radii at any point of time.

The problem can be conveniently solved using recursion as given below:- import java.util.*;

class TowerOfHanoi

{ public void hanoi (int n, char from, char to, char aux)

{

if (n==1) System.out.println("Move a disc from peg "+from+" to peg "+to);

else

{

hanoi(n-1, from, aux, to); hanoi(1, from, to, aux);

hanoi(n-1, aux, to , from);

} }

}

class TowerExp

{ public static void main(String args[ ])

{

Scanner src=new Scanner(System.in); System.out.println("Enter no of discs");

int num=src.nextInt();

TowerOfHanoi obj=new TowerOfHanoi(); obj.hanoi(num,'A','B','C');

}

}

Here the user has to give the number of disc and depending on that the program will display the

required moves. The sample output is shown for 3 discs.

Sample Output : Enter no of discs

3

Move a disc from peg A to peg B Move a disc from peg A to peg C

Move a disc from peg B to peg C

Move a disc from peg A to peg B

Move a disc from peg C to peg A

Page 2: DSF

(2) Vidyalankar : S.E. – DSF

Move a disc from peg C to peg B

Move a disc from peg A to peg B

1. (b) Data Structure Data Structure is the way of organizing data in such a way that the retrieval of data becomes

convenient.

The journey of data structures start from fundamental−data types as they are the first facility provided by the language to store data. Due to the increasing needs and the size and variety of

data, data structures have gone ahead with derived data types, linear and finally non-linear data

structures. Let us take a brief look on the various types of data structures.

Types of Data Structures

1) Primitive Data Structures

These are the default data types provided by the specific language. For example, C language provides int, float, char etc., which can be used to store simple primary level data. For basic

programming, these data types are more than sufficient for the management of data but as the

level of programming increases, these data types normally are not used directly but are combined to form more complex data structures of the different types. We also form array

and structures from these primitive types that are known as derived data types.

2) Linear Data Structures The data structure where all the elements are stored in a linear sequence is known as Linear

Data Structures. Here all elements are of same hierarchy or level. For example, array and

structure falls under the linear category. Stack, queue, linked list which are also considered as linear data structures.

Such data structures are limited when the system only uses same level of data. But in many

situations we require to store data with hierarchy or level, for example directory structure. In such cases we need to take the help of non-linear data structures.

3) Non-Linear Data Structures

The data structure in which the data is stored with hierarchy is known as Non-Linear Data Structure. All elements in this are not at the same level. These are very useful when we have

to store data with precedence or hierarchy. Some non-linear data structures are binary tree

and graph. The various operations performed on the data structures are as follows:-

1) Traversing – The process of visiting each and every element of a data structure.

2) Insertion – Adding new elements to the set of existing elements of a data structure. 3) Deletion – Removing the existing elements from a data structure.

4) Sorting – Arranging the elements of the data structure in the given order or sequence.

5) Searching – Finding the required element in the set of elements of a data structure.

2. (a) Hashing

Hashing is one of the most efficient searching techniques. But it uses large amount of extra space.

It uses a hash function and creates its own hash table from the set of input values. Using the hash function, the position of the original value (key) within the hash table is calculated. While

searching, the search element is also hashed using hash function to get the hash key. Then the

corresponding hash table entry is checked. If the value is present then we declare success other

wise failure. But this can happen only in the absence of collision which is a rare case. A collision occurs when two or more keys hashed to same hash key. This problem is handled by any of the

collision handling techniques available. The important terms used in the concept of hashing

are : 1) Hash Table : - It is the array which stores the input elements according to their hash keys.

2) Hash Function : - It is the function used to convert an input value into its corresponding hash

key which indicates the place for that key in the hash table. So if k is the original key and ‘h’ is the hash function then h(k) is its hash key. One would like to have a hash function which is

easy to compute and even capable of generating non-colliding hash keys.

Page 3: DSF

Prelim Question Paper Solutions (3)

3) Collision : - The collision occurs when two or more keys are hashed to the same hash key.

Suppose k1 and k2 are two keys such that h(k1) = h(k2) then they result in collision. Its quite obvious that two keys cannot be stored at the same place in the hash table, hence the first key

arriving is stored at the proper place and the place of the second key is decided by the

‘Collision Handling Technique’ used.

Some examples of Hash Functions : 1) Mid square : This function is calculated by squaring the original key and then selecting

appropriate number of bits from the middle of the squared number to obtain the hash key. The

number of bits to select depends on the size of the hash table. If ‘k’ bits are selected then the size of hash table is required to be a minimum of 2

k. The size of the hash table has to be a

power of 2 if this procedure is adopted.

We can even select the middle digits to form the hash key. So if we decided to select ‘k’ digits then the hash table size should be 10

k.

For E.g.- Original Key = 23 Square = 529 Hash Key = 05

Original Key = 45 Square = 2025 Hash Key = 20

2) Modulo N: In this method we use a simple division technique. We decide a number N for

division. Each key is divided by N and the remainder obtained is used as the hash key. If k is

the original key then the function can be defined as follows. h(k) = h % N

This will result in hash keys ranging from 0 to N-1 and hence needs to have hash table with

size N. Preferably a prime number is selected as N. For E.g.- Suppose N = 13

Original Key = 23 Hash Key = 10

Original Key = 45 Hash Key = 06

3) Folding: In this method, the original element is partitioned into several equal parts except the

last one. These parts are then added together to form the hash key for that element. There are

two ways for doing that addition namely shift folding and folding at the boundaries. In shift folding, except the last; all parts are shifted so that the least significant bit of each part lines

up with the corresponding bit of the last part. The different parts are then added together to

form the hash key. In the folding at boundaries method, the original element is folded at the

boundaries and digits falling into the same position are added together. Let us take one example, suppose the number to be hashed is 234764365

Dividing it by equal parts of length 2.

P1= 23, P2= 47, P3= 64, P4= 36, P5= 5 Shift Folding Folding at the boundaries

23

47

64

36

5

23

74

64

63

5

Reverse of 47

Reverse of 36

175 229

For the above number, the hash key generated by Shift folding would be 175 and by Folding

at boundaries would be 229. As here the size of the table is difficult to predict, hence the hash key generated by this technique can be rehashed using some functions like Modulo N.

4) Digit Analysis: This method is very useful when all the elements to be stored are known in

advance. Each element is interpreted as a number using some radix. Using this radix all the digits of all elements are examined and the digits having very skewed representation are

deleted. This continues till the number of digits left is small enough to give an index of the

array which can be used as hash key. The digits to drop are selected such that the hash keys generated would be as non-conflicting as possible.

For e.g. :-

1205, 5287, 6247, 355, 7225, 6347, 7273, 23, 415, 347

Page 4: DSF

(4) Vidyalankar : S.E. – DSF

Dropping the hundredths place

105, 587, 647, 55, 725, 647, 773, 23, 15, 47

Dropping the unit place

10, 58, 64, 5, 72, 64, 77, 2, 1, 4

2. (b) Selection Sort

Algorithm

1) Create array a[0 … n-1] of n elements. 2) initialize i to 0

3) Set element at i as min and pos to i

4) initialize j to i+1 5) if element at j is less than min then

change min to x[j] and pos to i

6) increment j by 1

7) if j<n then goto step 4 8) Swap the element at i with element at pos.

9) increment i by 1

10) if i<n-1 then goto step 3 11) Return the sorted array.

Implementation import java.util.*;

class SelectionSort

{

private int x[],n; public SelectionSort(int n)

{

this.n=n; x=new int[n];

System.out.println("Enter "+n+" elements");

Scanner src=new Scanner(System.in);

for (int i=0; i<n; i++) x[i]=src.nextInt();

}

public void selection () {

int i,j,min,pos;

for (i=0;i<n-1; i++) {

min=x[i];

pos=i;

for (j=i+1; j<n; j++) if (x[j]<min)

{

min=x[j]; pos=j;

}

x[pos]=x[i]; x[i]=min;

System.out.println("After Pass "+(i+1));

for (int k=0; k<n; k++)

System.out.print(x[k]+" "); System.out.println();

}

}

Page 5: DSF

Prelim Question Paper Solutions (5)

public void display()

{ for (int i=0; i<n; i++)

System.out.print(x[i]+" ");

}

} class SelectionExp

{

public static void main(String args[]) {

Scanner src=new Scanner(System.in);

System.out.println("Enter number of elements"); int n=src.nextInt();

SelectionSort obj=new SelectionSort(n);

obj.selection();

System.out.println("Sorted Array"); obj.display();

}

}

Analysis

Pass 1 :- n-1 comparisons Pass 2 :- n-2 comparisons … Pass i :- n-i comparisons

So the total will be the summation of n-i from i=1 to n-1. We get 1/2 [ n (n-1) ] which finally

leads to the worst case complexity of O(n2).

Even exchange mechanisms can not be devised for this algorithm. So irrespective of pattern of the set of input elements, the efficiency will always be O(n

2) for best and average case also.

Sample Output

Initial Array

7 54 29 41 12 5 78 35 22 18

5 54 29 41 12 7 78 35 22 18

5 7 29 41 12 54 78 35 22 18

5 7 12 41 29 54 78 35 22 18

5 7 12 18 29 54 78 35 22 41

5 7 12 18 22 54 78 35 29 41

5 7 12 18 22 29 78 35 54 41

5 7 12 18 22 29 35 78 54 41

5 7 12 18 22 29 35 41 54 78

5 7 12 18 22 29 35 41 54 78

3. (a) Converting Infix to Postfix

Rules:-

1) If the operand is encountered, display it (or store it in result). 2) If the operator is encountered and the stack is empty then push it on the stack.

3) If operator is encountered and the stack is not empty then compare the entering operator with

residing operator (the current top of the stack).

Page 6: DSF

(6) Vidyalankar : S.E. – DSF

(a) If the entering operator has higher precedence than the residing operator then push it on

the stack (b) If the entering operator has lower or equal precedence than the residing operator then the stack

is popped and elements are displayed till either the residing operator’s precedence becomes

higher or the stack becomes empty. Then the entering operator is pushed onto the stack.

(c) In case of brackets, the opening bracket has highest priority as an entering operator but the lowest priority as residing operator. Hence whenever opening bracket is encountered

it is pushed on to the stack (Highest Priority). If the residing operator is opening bracket

then any operator is pushed on the stack (Lowest Priority). (d) Whenever the closing bracket is encountered, the stack is popped till the opening bracket

is getting popped and all the popped elements are displayed. Both the closing and

opening brackets are discarded.

Implementation

import java.util.*;

class Stack {

private char s[];

int tos=-1,max; public Stack(int k)

{

max=k; s=new char[max];

}

public void push(char ele)

{ if (tos==max-1)

System.out.println("Stack Overflow");

else {

tos++;

s[tos]=ele;

} }

public boolean empty()

{ if (tos==-1)

return true;

else return false;

}

public char pop()

{ if (empty()!=true)

{

char z=s[tos]; tos--;

return z;

} else

return 0;

}

public char stackTop() {

return (s[tos]);

}

Page 7: DSF

Prelim Question Paper Solutions (7)

}

class In2Post {

private Stack s;

private String infix,postfix;

public In2Post(String v) {

infix=v;

postfix=null; }

public boolean isOperand(char ch)

{ if (ch>='A'&&ch<='Z'||ch>='a'&&ch<='z')

return true;

else

return false; }

public int ipr(char ch)

{ switch(ch)

{

case '+':; case '-':return 1;

case '*':;

case '/':;

case '%':return 2; case '(':return 3; // highest priority

}

return -1; }

public int rpr(char ch)

{

switch(ch) {

case '+':;

case '-':return 1; case '*':;

case '/':;

case '%':return 2; case '(':return 0; // lowest priority

}

return -1;

} public void convert()

{

s=new Stack(infix.length()); char in[]=infix.toCharArray();

char po[]=new char[in.length];

int c=0; int i=0;

while(i<in.length)

{

if(in[i]=='(') s.push(in[i]);

else if (in[i]==')')

while(true)

Page 8: DSF

(8) Vidyalankar : S.E. – DSF

{

char z=s.pop(); if (z=='(')

break;

po[c++]=z;

} else if (isOperand(in[i]))

po[c++]=in[i];

else if (s.empty()) s.push(in[i]);

else if (ipr(in[i])>rpr(s.stackTop()))

s.push(in[i]); else

{

while(s.empty()==false && ipr(in[i])<=rpr(s.stackTop()))

{ char z=s.pop();

po[c++]=z;

} s.push(in[i]);

}

i++; }

while(s.empty()==false)

{

char z=s.pop(); po[c++]=z;

}

postfix=String.valueOf(po); }

public void display()

{

System.out.println("The postfix expression = "+postfix); }

public static void main(String args[])

{ Scanner src=new Scanner (System.in);

System.out.println("Enter the infix expression");

String input=src.nextLine(); In2Post obj=new In2Post(input);

obj.convert();

obj.display();

} }

3. (b) Array Implementation of Queue

import java.util.*; class Queue

{

private int q[],f=-1,r=-1,max;

public Queue(int max) {

this.max=max;

q=new int[max]; }

Page 9: DSF

Prelim Question Paper Solutions (9)

public void insert(int ele)throws Exception

{ if (r==max-1)

throw new Exception("Queue Overflow");

else

{ r++;

q[r]=ele;

if (f == - 1) f++;

display();

} }

public boolean empty()

{

if (f==-1||f>r) return true;

else

return false; }

public int delete()throws Exception

{ if (empty())

throw new Exception("Queue Underflow");

else

{ int z=q[f];

f++;

display(); return z;

}

}

public int queueFront() {

return (q[f]);

} public void display()

{

for (int i=f; i<=r; i++) System.out.println(q[i]+" ");

System.out.println();

}

boolean search(int ele) {

for(int i=f; i<=r; i++)

if (q[i]==ele) return true;

return false;

} }

class QueueExp

{

public static void main(String args[]) {

Scanner src=new Scanner (System.in);

System.out.println("Enter the capacity of the queue");

Page 10: DSF

(10) Vidyalankar : S.E. – DSF

int k=src.nextInt();

Queue obj1=new Queue(k); int ch;

while(true)

{

System.out.println("Enter the choice"); System.out.println("1:Insert 2:Delete 3:QueueFront 4:Display 5:Search 6:Exit");

ch=src.nextInt();

if (ch==6) break;

switch(ch)

{ case 1: System.out.println("Enter the element to push");

int ele=src.nextInt();

try

{ obj1.insert(ele);

}

catch(Exception e) {

System.out.println(e);

} break;

case 2: try

{

int pele=obj1.delete(); System.out.println("The deleted element is "+pele);

}

catch(Exception e) {

System.out.println(e);

}

break; case 3: if (obj1.empty()==true)

System.out.println("Queue is empty");

else {

int t=obj1.queueFront();

System.out.println("The current front element of Queue is "+t); }

break;

case 4: if (obj1.empty()==true)

System.out.println("Queue is empty"); else obj1.display();

break;

case 5: System.out.println("Enter the element to search"); ele=src.nextInt();

if (obj1.search(ele))

System.out.println(ele+" is present in the queue"); else System.out.println(ele+" is not present in the queue");

}

}

} }

Page 11: DSF

Prelim Question Paper Solutions (11)

4. (a) Queue is defined as the collection of elements stored sequentially such that the elements can be

deleted from one end known as front end and can be added at another end known as rear end. Queue follows the concept of FIFO (First In First Out). Hence unlike stack, in queue the first

element to be deleted will be the first element inserted.

Operations on Queue

There are mainly two operations performed on queues known as ‘insert’ and ‘delete’.

Queue is like a both end open pipe. One end is known as ‘front’ end at which the deletion takes

place and other is ‘rear’ where the insertion takes place. The queue ADT keeps two pointers namely front and rear. The ‘front’ pointer points to the frontmost element in the queue or the

element which is to be deleted first. The ‘rear’ pointer points to the last (rear most) element in the

queue or the element after which the insertion is to be done.

Initially both front and rear pointer will point to zero. When the deletion is to be done then the

element at front pointer is deleted and front is incremented by one. Whereas insertion is done at

the position next to the rear pointer and then rear pointer is also incremented to point to the newly

stored value.

Algorithm for Queue Implementation

Variables used :- 1) queue is a collection of sequential memory of size MAX

2) eltype is the type of elements of the stacks.

3) ‘f’ is data pointer which points to the front most element of the queue whereas ‘r’ is the data pointer which points to the rear most element of the queue

4) a constant initpos which is the initial position of the f and r pointers of the queue (as array

starts from 0, generally initpos is initialized to -1)

5) a constant maxpos which is the maximum position till the r pointer can go upto ( if the array size is MAX, then the elements can be stored upto MAX-1 hence maxpos is generally

initialized to MAX-1 )

Function insert (queue q, eltype x)

1) Start

2) If r = maxpos then return with “overflow error” 3) Increment r

4) Place x at position r in q

5) If (f = initpos) then increment f 6) Return

Function delete (queue q) returns eltype 1) Start

2) If (f = initpos) then return with “underflow error”

3) Store the element at f in temporary variable z. (deleted element)

4) Increment f 5) Return z

Function empty (queue q) returns boolean

1) Start

2) If f = initpos or f > r then return TRUE

3) Return FALSE

Front Rear

Insertion Deletion

Fig.: Representation of a queue.

Page 12: DSF

(12) Vidyalankar : S.E. – DSF

Function queueFront(queue q) returns eltype

1) Start 2) Return element at f in q

Function display (queue q)

1) Start 2) Initialize i with f

3) Display the element at i

4) Increment i 5) If i<=r then goto step 3

6) Return

Function search (queue q, eltype x) returns boolean

1) Start

2) Initialize i with f

3) If the element at i in q is equal to x then return TRUE 4) Increment i

5) If i<=r then goto step 3

6) Return FALSE

4. (b) Priority Queues :

A queue in which we are able to insert items or remove items from any position based on some priority (such as priority of the task to be processed) is often referred to as a priority queue.

Figure (a) represents a priority queue of jobs waiting to use a computer. Priorities of 1, 2 and 3

have been attached to jobs of type real-time, on-line and batch respectively. Therefore, if a job is

initiated with priority i, it is inserted immediately at the end of the list of other jobs with priority i, for i = 1, 2 or 3. In this example, jobs are always removed from the front of the queue. (In

general, this is not a necessary restriction on a priority queue.)

A priority queue can be conceptualized as a series of queue representing situations in which it is

known what priorities are associated with queue items. Figure (b) shows how the single-priority

queue can be visualized as three separate queues each exhibiting a strictly FIFO behavior. Elements in the second queue are removed only when the first queue is empty, and elements from

the third queue are removed only when the first and second queues are empty. This separation of

a single-priority queue into a series of queues also suggests an efficient storage representation of a priority queue. When elements are inserted, they are always added at the end of one of the

queues as determined by the priority. Alternatively, if a single sequential storage structure is used

for the priority queue then insertion may mean that the new element must be placed in the middle

of the structure. This can require the movement of several items. It is better to split the priority queue into several queues, each having its own storage structure.

Task identification

R1 R2 … Ri-1 O1 O2 … Oi−1 B1 B2 … Bk−1 …

1 1 … 1 2 2 … 2 3 4 … 3 …

Priority ↑ ↑ ↑

Ri Rj Rk

Fig. (a) : A priority queue viewed as a single queue with insertion allowed at any position.

Priority 1

R1 R2 … Ri−1 … ↑ Ri

Priority 2

O1 O2 … Oi−1 … ↑ Oj

Page 13: DSF

Prelim Question Paper Solutions (13)

Priority 3

B1 B2 … Bk−1 … ↑ Bk

Fig. (b) : A priority queue viewed as a setoff queue.

4. (c) Descending Priority Queue In this, the elements are considered in the descending order of their priority. Hence on deleting,

the element with the highest priority is deleted first. Processors keep such queues for processes,

hence the process having higher priority is executed first irrespective of the arrival time.

There can be two methods of implementing the priority in the priority queue.

Method 1:

It would be to have normal insertion and adjusting on delete. Hence while inserting it follows the rules of normal queue and elements are kept in the order of their arrival. But while deleting the

smallest or the largest element is searched and deleted. In this type, the queue will never be in

sorted position but deletion is done by selecting the appropriate element.

Method 2:

In this delete takes place in normal fashion i.e. by following the rules of the queue. But while inserting we have to search for the proper place of the element for inserting so that the queue will

remain in the required sequence. Hence while deleting the largest or the smallest element it would

be available in the beginning only. In this type, at each point the queue would be in required

sorted position.

Let us go for the implementation of Priority Queue with above two methods.

Method 1 import java.util.*;

/********* Descending PQ with normal insert ************/

class PQ

{ final int MAX=10;

private int q[],f=-1,r=-1;

public PQ() {

q=new int[MAX];

System.out.println("Queue is initialized"); }

public void insert(int x)

{

if(r==MAX-1) System.out.println("Overflow Error");

else

{ q[++r]=x;

if(f==-1)

f++; }

}

public void del()

{ int pos,ele,i,k;

if(r==-1||f>r)

System.out.println("Underflow Error"); else

{

Page 14: DSF

(14) Vidyalankar : S.E. – DSF

pos=f;

for (i=pos+1; i<=r; i++) if (q[i]>q[pos])

pos=i;

ele =q[pos];

for (k=pos; k<r; k++) q[k]=q[k+1];

r--;

System.out.println("Deleted Element is "+ele); }

}

public void display() {

int i;

if(f>r||r==-1)

System.out.println("Queue is empty"); else

{

System.out.println("Queue is"); for(i=f;i<=r;i++)

System.out.print(q[i]+" ");

} System.out.println();

}

}

class PQExp1 {

public static void main(String args[])

{ int choice,x;

PQ obj=new PQ();

while(true)

{ System.out.println("1.Insert 2.Remove 3.Display");

System.out.println("4.Exit Enter your choice :");

Scanner src=new Scanner(System.in); choice=src.nextInt();

if (choice==4)

break; switch(choice)

{

case 1 :System.out.println("Enter element to insert");

x=src.nextInt(); obj.insert(x);

break;

case 2 :obj.del(); break;

case 3 :obj.display();

break; }

}

}

}

Method 2

import java.util.*;

/********* Descending PQ with normal delete ************/

Page 15: DSF

Prelim Question Paper Solutions (15)

class PQ2

{ final int MAX=10;

private int q[],f=-1,r=-1;

public PQ2()

{ q=new int[MAX];

System.out.println("Queue is initialized");

} public void insert(int x)

{

int pos,i,k; if(r==MAX-1)

System.out.println("Overflow Error");

else

{ if (r==-1)

{

q[++r]=x; f++;

}

else {

pos=f;

for (i=f;i<=r;i++)

if (q[i]<x) break;

for (k=r;k>=i; k--)

q[k+1]=q[k]; q[i]=x;

r++;

}

} }

public void del()

{ int ele,i,k;

if(r==-1||f>r)

System.out.println("Underflow Error"); else

{

ele=q[f];

f++; System.out.println("Deleted Element is "+ele);

}

} public void display()

{

int i; if(f>r||r==-1)

System.out.println("Queue is empty");

else

{ System.out.println("Queue is");

for(i=f;i<=r;i++)

System.out.print(q[i]+" ");

Page 16: DSF

(16) Vidyalankar : S.E. – DSF

}

System.out.println(); }

}

class PQExp2

{ public static void main(String args[])

{

int choice,x; PQ2 obj=new PQ2();

while(true)

{ System.out.println("1.Insert 2.Remove 3.Display");

System.out.println("4.Exit Enter your choice :");

Scanner src=new Scanner(System.in);

choice=src.nextInt(); if (choice==4)

break;

switch(choice) {

case 1 : System.out.println("Enter element to insert");

x=src.nextInt(); obj.insert(x);

break;

case 2 : obj.del();

break; case 3 : obj.display();

break;

} }

}

}

5. (a) Array Implementation of Linked List Sometimes we need to implement a linked list using array. So we can use a two dimensional array

of n x 2 where n denotes maximum number of elements the linked list can store. The first column is used to store data and the second column stores the index of the next element. Using array

implementation of linked list, we can achieve the advantages like easy insertion and deletion

without shifting elements.

2 0 4 1

The diagram shows the diagrammatic representation of a linked list. Instead of address, each node is assigned the index of the array where it is stored. The contents of array storing the above linked

list will be as follows.

start 2

32 0 41 4 8 1 21

2

start

Page 17: DSF

Prelim Question Paper Solutions (17)

From the above information, it is clear that the linked list starts at index 2, so the first element is 32. It’s next stores 0, so the next element is at index 0 i.e. 41 then 8 and then 21. As the next of 21 is

marked as ‘-1’, it is taken as null and the linked list terminates. The nodes having next marked as -2

are considered to be unallocated irrespective of whatever data is stored in it. The concept is implemented in the following program.

import java.util.*;

class ArrayLL {

private int a[][],max;

private final int data=0, next=1, NULL=-1,empty=-2; private int start=-1;

public ArrayLL(int cap)

{ max=cap;

a=new int[max][2];

for (int i=0; i<max; i++)

a[i][next]=-2; }

public void show()

{ System.out.println("The memory map");

for (int i=0; i<max; i++)

System.out.println(i+" "+a[i][data]+" "+a[i][next]);

} public int allocate()

{

for (int i=0; i<max; i++) if (a[i][next]==empty)

return i;

return -1; }

public boolean empty()

{

if (start==NULL) return true;

else

return false; }

public void create(int n)

{ Scanner src=new Scanner(System.in);

for (int i=0; i<n; i++)

{

int k=allocate(); if (k==-1)

System.out.println("Memory Full");

else

Index Data Next

0 41 4

1 21 -1

2 32 0

3 0 -2

4 8 1

5 0 -2

Page 18: DSF

(18) Vidyalankar : S.E. – DSF

{

System.out.println("Enter data"); a[k][data]=src.nextInt();

a[k][next]=NULL;

if (start==NULL)

start=k; else

{

int q=start; while(a[q][next]!=NULL)

q=a[q][next];

a[q][next]=k; }

}

}

} public void insertBeg(int ele)

{

int k=allocate(); if (k==-1)

System.out.println("Memory Full");

else {

a[k][data]=ele;

a[k][next]=start;

start=k; }

}

public void insertEnd(int ele) {

int k=allocate();

if (k==-1)

System.out.println("Memory Full"); else

{

a[k][data]=ele; a[k][next]=NULL;

int q=start;

while(a[q][next]!=NULL) q=a[q][next];

a[q][next]=k;

}

} public int deleteBeg()

{

int p=start; if (start==NULL)

return -1;

if (a[start][next]==NULL) start=NULL;

else start=a[start][next];

int z=a[p][data];

a[p][next]=empty; return z;

}

public int deleteEnd()

Page 19: DSF

Prelim Question Paper Solutions (19)

{

int p,q=start; if (start==NULL)

return -1;

if (a[start][next]==NULL)

{ p=start;

start=NULL;

} else

{

while(a[a[q][next]][next]!=NULL) q=a[q][next];

p=a[q][next];

a[q][next]=NULL;

} int z=a[p][data];

a[p][next]=empty;

return z; }

public void deleteEle(int ele)

{ int q=start;

if (a[q][data]==ele)

{

System.out.println(ele+" is deleted"); start=a[start][next];

return;

} while(a[q][next]!=NULL)

{

if(a[a[q][next]][data]==ele)

break; q=a[q][next];

}

if(a[q][next]==NULL) System.out.println(ele+" is not found");

else

{ System.out.println(ele+" is deleted");

a[q][next]=a[a[q][next]][next];

}

} public void display()

{

int q=start; while(q!=NULL)

{

System.out.print(a[q][data]+" "); q=a[q][next];

}

System.out.println();

show(); // to display contents of array (optional) }

}

class ArrayLLExp

Page 20: DSF

(20) Vidyalankar : S.E. – DSF

{

public static void main(String args[]) {

int ch,pele;

Scanner src=new Scanner(System.in);

System.out.println("Enter capacity"); int cap=src.nextInt();

ArrayLL x=new ArrayLL(cap);

System.out.println("Enter no of elements"); int n=src.nextInt();

x.create(n);

while(true) {

System.out.println("Enter choice 1:Insert Beg 2:Insert End");

System.out.println("3:Delete Beg 4:Delete End 5:Delete Element");

System.out.println("6:Display 7:Exit"); ch=src.nextInt();

if (ch==7)

break; switch(ch)

{

case 1: System.out.println("Enter the element to insert"); int ele=src.nextInt();

x.insertBeg(ele);

break;

case 2: System.out.println("Enter the element to insert"); ele=src.nextInt();

x.insertEnd(ele);

break; case 3: if (x.empty())

System.out.println("Linked List is empty");

else

{ pele=x.deleteBeg();

System.out.println("Deleted Element is "+pele);

} break;

case 4: if (x.empty())

System.out.println("Linked List is empty"); else

{

pele=x.deleteEnd();

System.out.println("Deleted Element is "+pele); }

break;

case 5: if (x.empty()) System.out.println("Linked List is empty");

else

{ System.out.println("Enter element to delete");

ele=src.nextInt();

x.deleteEle(ele);

} break;

case 6: if (x.empty())

System.out.println("Linked List is empty");

Page 21: DSF

Prelim Question Paper Solutions (21)

else

x.display(); break;

}

}

} }

5. (b) import java.util.*; class Node

{

int data; Node next;

public Node(int k)

{

data=k; next=null;

}

} class LinkedList

{

private Node start=null; public void create(int n)

{

Node p,q;

for (int i=0; i<n; i++) {

Scanner src=new Scanner(System.in);

System.out.println("Enter data"); int ele=src.nextInt();

p=new Node(ele);

if (start==null)

start=p; else

{

q=start; while(q.next!=null)

q=q.next;

q.next=p; }

}

}

public void display() {

Node q=start;

while(q!=null) {

System.out.print(q.data+" ");

q=q.next; }

System.out.println();

}

public void rev() {

Node p,q,r;

q=null;

Page 22: DSF

(22) Vidyalankar : S.E. – DSF

p=start;

while(p!=null) {

r=p.next;

p.next=q;

q=p; p=r;

}

start=q; }

}

class LRev {

public static void main(String args[])

{

int ch,pele; Scanner src=new Scanner(System.in);

System.out.println("Enter no of elements to create");

int n=src.nextInt(); LinkedList obj=new LinkedList();

obj.create(n);

System.out.println("Original Linked List"); obj.display();

obj.rev();

System.out.println("\nReversed Linked List");

obj.display(); }

}

6. (a) The tree T is drawn from its root downward as follows :

(i) The root of T is obtained by choosing the first node in its preorder. Thus, F is the root of T.

(ii) The left child of the node F is obtained as follows. First use the inorder of T to find the nodes

in the left subtree T1 of F. Thus, T1 consists of the nodes E, A, C and K. Then the left child of F is obtained by choosing the first node in the preorder of T1 (which appears in the

preorder of T). Thus A is the left son of F.

(iii) Similarly, the right subtree T2 of F consists of the nodes H, D, B and G and D is the root of T2 i.e. D is the right child of F.

Repeating the above process with each now node, we finally obtain the required tree.

1) Inorder :- In this root is traversed in between the left and right sub tree.

2) Preorder :- In this root is traversed prior to both the sub trees.

The algorithm can be given as follows.

Function inorder (root) 1) start

2) if root is not null then

a) call inorder with left pointer of root (root->left)

b) display the data in root. c) call inorder with right pointer of root. (root->right)

3) stop

F

A D

G E K H

C C

Page 23: DSF

Prelim Question Paper Solutions (23)

Function preorder (root)

1) start 2) if root is not null then

a) display the data in root.

b) call preorder with left pointer of root (root->left)

c) call preorder with right pointer of root. (root->right) 3) stop

6. (b) Difference between B- tree and B + tree.

B-tree B+ tree

1 Every key is stored only once either in leaf node or non leaf node

Values stored in a non-leaf node are repeated again in one of the leaf node. i.e. leaf nodes

can contain all the keys

2 All leaf nodes are at same node but are

isolated from each other

All leaves are at same level and are

connected by using an additional pointer.

3. Records are stored inside the B-tree i.e.

every key is associated with its Record

∴B− tree is larger in size and it cannot fit

in RAM.

Records are stored outside B+ tree and the

addition of these records are stored by the

pointer of the leaf node.

∴B+ tree smaller in size and can fit in RAM.

4. B- tree supports Random traversal only B+ tree supports both Random & sequential

traversal.

6. (c) AVL Trees: Any binary search tree T that satisfies the height balance property is called as AVL tree.

Height−Balance property states that for every internal node v of T, the heights of the children of v differ by at most 1.

r| h h | 1− ≤�

h� = height of left subtree

rh = height of right subtree

The consequence of the height balance property is that a subtree of an AVL tree is itself an AVL tree.

AVL gives 4 Rotation Algorithm for 4 different cases, which are useful for Balancing the tree.

Case I − Left − Left Case

100 is not balanced due to left−left case. So rotate 100 to right. This is Right rotation.

Case 2 − Right − Right case

100 is not balanced due to right−right case. So rotate 100 to left. This is left rotation.

100 root

50

25

100 root

200

300

root

200

100 300

Page 24: DSF

(24) Vidyalankar : S.E. – DSF

Case 3 : − Left − Right case

100 is not balanced due to left-right case. So rotate left child of 100. i.e. so this is left rotation.

Case 4 : − Right − Left case

100 is not balanced due to right-left case. So rotate right child of 100. i.e. 150 this is right rotation.

7. (a) (i) Threaded binary tree : Because of the importance of linked binary trees, it is worthwhile to

develop nonrecursive algorithms to manipulate them and to study the time and space

requirements of these algorithms. We shall find that by changing the NULL links in a binary tree to special links called threads, it is possible to perform traversals, insertions, and

deletions without using either a stack or recursion.

A Threaded Binary Tree is a binary tree in which every node that does not have a right child

has a THREAD (in actual sense, a link) to its INORDER successor. By doing this threading

we avoid the recursive method of traversing a Tree which makes use of stacks and consumes

a lot of memory and time. For example :

To make the Threaded Binary tree out of a

normal binary tree as shown in figures:

The INORDER traversal for the above tree is -- D B A E C. So, the respective Threaded

Binary tree will be –

B has no right child and its inorder successor is A so a thread has been made in between them. Similarly, for D and E, C has no right child but it has no inorder successor so it has a

hanging thread.

A binary tree is threaded by making all right child pointers that would normally be null point to the inorder successor of the node and all left child pointers that would normally be null

point to the inorder predecessor of the node."

A threaded binary tree makes it possible to traverse the values in the binary tree via a linear

traversal that is more rapid than a recursive in-order traversal.

100

50

75

75

50 100

100

75

50

Left − left case

150

100 200

100

200

150

100

150

200

Page 25: DSF

Prelim Question Paper Solutions (25)

It is also possible to discover the parent of a node from a threaded binary tree without explicit

use of parent pointers or a stack, albeit slowly. This can be useful where stack space is limited or where a stack of parent pointers is unavailable.

(ii) Huffman Codes

The most common way to represent characters internally in a computer is by using fixed−length bit strings. For example, ASCII (American Standard Code for Information Interchange) represents each character by a string of seven bits. Examples are given in table:

Character ASCII Code

A 100 0001

B 100 0010

C 100 0011

1 011 0001

2 011 0010

1 010 0001

∗ 010 1010

Huffman codes which represent characters by variable−length bit strings provide alternatives to

ASCII and other fixed−length codes. The idea is to use short bit strings to represent the most frequently used characters. In this way it is generally possible to represent strings of characters

such as text and programs in less space than if ASCII were used.

A Huffman code is most easily defined by a rooted tree. To decode a bit

string, we begin at the root and move down the tree until a character is

encountered. The bit, 0 or 1, tells us whether to move right or left.

As an example, let us decode the string : 01010111

We begin at the root. Since the first bit is 0, the first move is right. Next, we move left and then

right. At this point, we encounter the first character R. To decode the next character, we begin

again at the root. The next bit is 1 so we move left and encounter the next character A. The last bits 0111 decode as T. Therefore, the bit string represents the word RAT.

Huffman gave an algorithm to construct a Huffman code from a table giving the frequency of

occurrence of the characters to be represented so that the code constructed represents strings of

characters in minimal space, provided that the strings to be represented have character

frequencies identical to the character frequencies in the table.

Constructing an Optimal Huffman Code

This algorithm constructs an optimal Huffman code from a table giving the frequency of occurrence of the characters to be represented. The output is a rooted tree with the vertices at the

lowest levels labeled with the frequencies and with the edges labeled with bits as in the above

figure. The coding tree is obtained by replacing each frequency by a character having that frequency.

Input: A sequence of n frequencies, n ≥ 2 Output: A rooted tree that defines an optimal Huffman code

Procedure Huffman (f, n) If n = 2 then

begin

let f1 and f2 denote the frequencies

let T be as in figure

return (T)

end

let fi and fj denote the smallest frequencies

replace fi and fj in the list f by fi + fj

T′ := Huffman (f, n−1)

Root 1 0

0

0

0

1

1

1

T S

R

O

A

1 0

f2 f1

1 0

fi fj The case n > 2 for Algorithm

The case n = 2 for Algorithm

Page 26: DSF

(26) Vidyalankar : S.E. – DSF

replace a vertex in T′ labeled fi + fj by the tree shown in figure to obtain the tree T

return (T)

end Huffman

7. (b) Graphs Graph consists of two sets V and E of vertices and edges respectively. So G = (V,E) represents a graph.

In Un-directed Graph, the pairs (V1, V2) and (V2, V1) are same.

In Directed graph, (V1, V2) = V1 � V2

(V2, V1) = V2 � V1

The graph shown in figure is an undirected graph and can be represented as,

V(G1) = {1,2,3,4}

E(G1) = {(1,2), (1,3), (1,4), (2,3), (2,4), (3,4)}

In un-directed graph of n nodes (vertices),

Maximum number of edges = n(n-1)/2

Implementation import java.util.*;

class DFS

{

private int adj[ ][ ], visited[ ], n;

public DFS(int n)

{

this.n=n;

adj=new int[n][n]; visited=new int[n];

Scanner src=new Scanner(System.in);

System.out.println("Enter the adjacency matrix of "+n+"x"+n);

for (int i=0; i<n; i++)

for (int j=0; j<n; j++)

adj[i][j]=src.nextInt();

for (int i=0; i<n; i++)

visited[i]=0;

}

public void dfs(int node)

{ int i;

System.out.print((node+1)+" ");

visited[node]=1;

for (i=0; i<n; i++)

if (adj[node][i]!=0 && visited[i]!=1)

dfs(i);

}

}

class DFSExp

{

public static void main(String args[ ])

{ Scanner src=new Scanner(System.in);

System.out.println("Enter number of nodes");

int n=src.nextInt();

DFS obj=new DFS(n);

System.out.println("Enter the starting node");

int node=src.nextInt();

obj.dfs(node-1);

}

}

� � � � �

1

2 4

3