sem_2_mc0068_ data structures using c

25
Master of Computer Application (MCA) – Semester 2 MC0068 – Data Structures using C Assignment Set – 1 1. Describe the usage of pointers in functions with a suitable example. Ans:- Regarding their syntax, there are two different types of function pointers: On the one hand there are pointers to ordinary C functions or to static C++ member functions. On the other hand there are pointers to non-static C++ member functions. The basic difference is that all pointers to non-static member functions need a hidden argument: The this-pointer to an instance of the class. Always keep in mind: These two types of function pointers are incompatible with each other. Since a function pointer is nothing else than a variable, it must be defined as usual. In the following example we define three function pointers named pt2Function, pt2Member and pt2ConstMember. They point to functions, which take one float and two char and return an int. In the C+ + example it is assumed, that the functions, our pointers point to, are (non-static) member functions of TMyClass. int (*pt2Function)(float, char, char) = NULL; if(pt2Function >0){ if(pt2Function == &DoIt) printf("Pointer points to DoIt\n"); } else printf("Pointer not initialized!!\n"); 2. Demonstrate with your own programming example the usage of structures within an array. Ans:- Just as arrays of basic types such as integers and floats are allowed in C, so are arrays of structures. An array of structures is declared in the usual way: 1 struct personal_data my_struct_array[100]; 1

Upload: meetraunak2212

Post on 24-Oct-2014

117 views

Category:

Documents


4 download

TRANSCRIPT

Page 1: SEM_2_MC0068_ Data Structures Using C

Master of Computer Application (MCA) ndash Semester 2

MC0068 ndash Data Structures using C

Assignment Set ndash 1

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

Ans- Regarding their syntax there are two different types of function pointers On the one hand there are pointers to ordinary C functions or to static C++ member functions On the other hand there are pointers to non-static C++ member functions The basic difference is that all pointers to non-static member functions need a hidden argument The this-pointer to an instance of the class Always keep in mind These two types of function pointers are incompatible with each other

Since a function pointer is nothing else than a variable it must be defined as usual In the following example we define three function pointers named pt2Function pt2Member and pt2ConstMember They point to functions which take one float and two char and return an int In the C++ example it is assumed that the functions our pointers point to are (non-static) member functions of TMyClass

int (pt2Function)(float char char) = NULLif(pt2Function gt0) if(pt2Function == ampDoIt) printf(Pointer points to DoItn) else printf(Pointer not initializedn)

2 Demonstrate with your own programming example the usage of

structures within an array

Ans- Just as arrays of basic types such as integers and floats are allowed in C so are arrays of structures An array of structures is declared in the usual way

1 struct personal_data my_struct_array[100]

The members of the structures in the array are then accessed by statements such as the following

The value of a member of a structure in an array can be assigned to another variable or the value of a variable can be assigned to a member For example the following code assigns the number 1974 to the year_of_birth member of the fourth element of my_struct_array

1 my_struct_array[3]year_of_birth = 1974

1

Example-include ltstdiohgt

struct matrix int rows int cols int val a = rows=3 cols=1 val = (int[3]) (int[1])1 (int[1])2 (int[1])3

b = rows=3 cols=4 val = (int[3]) (int[4])1 2 3 4 (int[4])5 6 7 8 (int[4])9101112

void print_matrix( char name struct matrix m ) for( int row=0rowltm-gtrowsrow++ ) for( int col=0colltm-gtcolscol++ ) printf( s[i][i] in name row col m-gtval[row][col] ) puts()

int main() print_matrix( a ampa ) print_matrix( b ampb )

3 Explain the theory of non linear data structures

Ans- Linear data structure A linear data structure traverses the data elements sequentially in

which only one data element can directly be reached in which insertion and deletion is possible in

linearsequential fashion example- arrays linked listsNon linear data structures-in which sequential

updation addition is not possible example- trees stacksLinear data structures Arrays Linked

ListNon-Linear data strctures trees GraphsIn Linear data structures traversals are linear are

multidimensional arrays and graphs In the next few lessons we will examine these data structures to

see how they are represented using the computers linear memoryIn a non-linear the data items are

not arrangedNon-Linear container classes represent trees and graphs Each node or item may be

connected with two or more other nodes or items in a non-linear arrangement Moreover removing one

of the links could

Ex Arrays Linked Lists

4 Write a program in C showing the implementation of stack operations

using structures

Ans- Stack operations-

2

Push and pop are the operations that are provided for insertion of an element into the stack and the removal of an element from the stackExample-include ltstdiohgt include ltstdlibhgt include stackh define size 3 void main() int topelement int stack[size] init(amptop) while(full(amptopsize)) element = rand() printf(push element d into stacknelement) push(stackamptopelement) getchar() printf(stack is fulln) while(empty(amptop)) element = pop(stackamptop) printf(pop element d from stacknelement) getchar() printf(stack is emptyn) getchar()

5 Describe the theory and applications of Double Ended Queues (Deque) and

circular queues

Ans-

Double Ended Queues (Deque)- Like an ordinary queue a double-ended queue is a container It supports the following operations enq_front enq_back deq_front deq_back and empty

By choosing a subset of these operations you can make the double-ended queue behave like a stack or like a queue For instance if you use only enq_front and deq_front you get a stack and if you use only enq_front and deq_back you get a queue

By now the reader should be used to using header objects in order to obtain uniform reference semantics We will therefore go directly to a version of the double-ended queue with a separate header file and implementation file

Example-

3

include dqueueh include dlisth include lt stdlibhgt

struct dqueue dlist head dlist tail

dqueue dq_create(void) dqueue q = malloc(sizeof(struct dqueue)) q -gt head = q -gt tail = NULL return q

int dq_empty(dqueue q) return q -gt head == NULL

void dq_enq_front(dqueue q void element) if(dq_empty(q)) q -gt head = q -gt tail = dcons(element NULL NULL) else q -gt head -gt prev = dcons(element NULL q -gt head)

q -gt head -gt prev -gt next = q -gt head

q -gt head = q -gt head -gt prev

void dq_enq_back(dqueue q void element) if(dq_empty(q)) q -gt head = q -gt tail = dcons(element NULL NULL)

else q -gt tail -gt next = dcons(element q -gt tail NULL)

q -gt tail -gt next -gt prev = q -gt tail

q -gt tail = q -gt tail -gt next

void dq_deq_front(dqueue q) assert(empty(q)) dqueue temp = q -gt head void element = temp -gt element q -gt head = q -gt head -gt next free(temp) if(q -gt head == NULL) q -gt tail = NULL else q -gt head -gt prev = NULL return element

void dq_deq_back(dqueue q) assert(empty(q)) dqueue temp = q -gt tail void element = temp -gt element q -gt tail = q -gt tail -gt prev free(temp) if(q -gt tail == NULL) q -gt head = NULL else q -gt tail -gt next = NULL return element

circular queues- A circular queue is a particular implementation of a queue It is very efficient It is also quite useful in low level code because insertion and deletion are totally independant which

4

means that you dont have to worry about an interrupt handler trying to do an insertion at the same time as your main code is doing a deletion

Example-include ltstdiohgtinclude ltstdlibhgt

define MAX 10

void insert(int queue[] int rear int front int value) rear= (rear +1) MAX if(rear == front) printf(The queue is full can not insert a valuen) exit(0) queue[rear] = value

void delete(int queue[] int front int rear int value) if(front == rear) printf(The queue is empty can not delete a valuen) exit(0) front = (front + 1) MAX value = queue[front]

void main() int queue[MAX] int frontrear int nvalue front=0 rear=0

insert(queueamprearfront1) insert(queueamprearfront2) insert(queueamprearfront3) insert(queueamprearfront4) delete(queueampfrontrearampvalue) printf(The value deleted is dnvalue)

delete(queueampfrontrearampvalue) printf(The value deleted is dnvalue)

delete(queueampfrontrearampvalue) printf(The value deleted is dnvalue)

5

6 With the help of a suitable numerical example describe the following

concepts of a Binary Search Tree

A) Analysis of BST - carry out an Analysis of this method to determine its time complexity Since there are no ldquoforrdquo loops we can not use summations to express the total number ofoperations Let us examine the operations for a specific case where the number ofelements in the array n is 64When n= 64 BinarySearch is called to reduce size to n=32When n= 32 BinarySearch is called to reduce size to n=16When n= 16 BinarySearch is called to reduce size to n=8When n= 8 BinarySearch is called to reduce size to n=4When n= 4 BinarySearch is called to reduce size to n=2When n= 2 BinarySearch is called to reduce size to n=1

int BinarySearch (int A[ ] int n int K)int L=0 Mid R= n-1while (Llt=R)Mid = (L +R)2if ( K= =A[Mid] )return Midelse if ( K gt A[Mid] )L = Mid + 1elseR = Mid ndash 1 return ndash1

B) Insertion of Nodes into a BST - To insert a node into a BST

1 find a leaf st the appropriate place and 2 connect the node to the parent of the leaf

TREE-INSERT (T z)

y larr NILx larr root [T]while x ne NIL do y larr x if key [z] lt key[x] then x larr left[x] else x larr right[x]p[z] larr yif y = NIL then root [T] larr z else if key [z] lt key [y]

6

then left [y] larr z else right [y] larr z

Like other primitive operations on search trees this algorithm begins at the root of the tree and traces a path downward Clearly it runs in O(h) time on a tree of height h

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

Ans-include ltstdiohgt

The input file (weighttxt) look something like this

40 0 0 210 0 8 170 8 0 1621 17 16 0

The first line contains n the number of nodesNext is an nxn matrix containg the distances between the nodesNOTE The distance between a node and itself should be 0

int n The number of nodes in the graph

int weight[100][100] weight[i][j] is the distance between node i and node j

if there is no path between i and j weight[i][j] should

be 0

char inTree[100] inTree[i] is 1 if the node i is already in the minimum

spanning tree 0 otherwise

int d[100] d[i] is the distance between node i and the minimum spanning

tree this is initially infinity (100000) if i is already in

the tree then d[i] is undefinedthis is just a temporary variable Its not necessary

but speedsup execution considerably (by a factor of n)

int whoTo[100] whoTo[i] holds the index of the node i would have to be

linked to in order to get a distance of d[i]

updateDistances(int target)

7

should be called immediately after target is added to the tree

updates d so that the values are correct (goes through targets

neighbours making sure that the distances between them and the tree

are indeed minimum)void updateDistances(int target)

int ifor (i = 0 i lt n ++i)

if ((weight[target][i] = 0) ampamp (d[i] gt weight[target][i]))

d[i] = weight[target][i]whoTo[i] = target

int main(int argc char argv[]) FILE f = fopen(disttxt r)fscanf(f d ampn)int i jfor (i = 0 i lt n ++i)

for (j = 0 j lt n ++j)fscanf(f d ampweight[i][j])

fclose(f)

Initialise d with infinity for (i = 0 i lt n ++i)

d[i] = 100000

Mark all nodes as NOT beeing in the minimum spanning tree

for (i = 0 i lt n ++i)inTree[i] = 0

Add the first node to the tree printf(Adding node cn 0 + A)inTree[0] = 1updateDistances(0)

int total = 0int treeSizefor (treeSize = 1 treeSize lt n ++treeSize)

Find the node with the smallest distance to the tree

int min = -1for (i = 0 i lt n ++i)

if (inTree[i])if ((min == -1) || (d[min] gt d[i]))

min = i

8

And add it printf(Adding edge c-cn whoTo[min] + A min +

A)inTree[min] = 1total += d[min]

updateDistances(min)

printf(Total distance dn total)

return 0

8 Explain the following graph problems

A) Telecommunication problem - Subscription con_guration problem and is taken (with slight modi_cation) from [4]Let F denote a _nite set of features For fi fj 2 F a precedence constraint(figtfj) indicates that fi is after fj An exclusion constraint (filtgtfj) between fiand fj indicates that fi and fj cannot appear together in a sequence of featuresand is equivalent to the pair (figtfj ) (fjgtfi) A catalog is a pair hF Pi with F aset of features and P a set of precedence constraints on F A feature subscriptionS of a catalog hFc Pci is a tuple hFCUWF WUi where F _ Fc is the set offeatures selected from Fc C is the projection of Pc on F U is a set of user de_nedprecedence constraints on F and WF F N and WUU N are maps whichassign weights to features and user precedence constraints The value of S isde_ned by V alue(S) = _f2FWF (f) + _p2UWU(p) The weight associated witha feature or a precedence constraint signi_es its importance for the userA feature subscription hFCUWF WUi is consistent i_ the directed graphhFC[Ui is acyclic Checking for consistency is straightforward using topologicalsort as described in [4] If a feature subscription is inconsistent then the task isto relax it and to generate a consistent one with maximum value A relaxationof a feature subscription S = hFCUWF WUi is a consistent subscriptionS0 = hF0C0U0WF0 WU0 i such that F0 _ F C0 is the projection of C on F0U0 is a subset of the projection of U on F0 WF0 is the restriction of WF to F0and WU0 is the restriction of WU to U0 We say that S0 is an optimal relaxationof S if there does not exist another relaxation S00 of S such that V alue(S00) gtV alue(S0) In [4] the authors prove that _nding an optimal relaxation of afeature subscription is NP-hard This is the problem addressed in this paper

B) Knight Moves - A knight is a chess piece that can move either two spaces horizontally and one space vertically or one space horizontally and two spaces vertically That is a knight on square (xy) can move to any of the eight squares (x plusmn 2y plusmn 1) (x plusmn 1y plusmn 2) if these squares exist on the chessboard (which is normally 8 times 8) A knightrsquos tour is a sequence of legal moves by a knight starting at some square and visiting each square exactly once A knightrsquos tour is called reentrant if there is a legal move that takes the knight from the last square of the tour back to where the tour began We can model knightrsquos tours using the graph that has a vertex for each square

9

on the boardwith an edge connecting two vertices if a knight can legally move between the squares represented by these vertices (a) Show that finding a reentrant knightrsquos tour on an m times n chessboard is equivalent to finding a Hamilton circuit on the corresponding graph (b) Show that the graph representing the legal moves of a knight on a mtimesn chessboard wherever m and n are positive integers is bipartite (c) Deduce that there is no reentrant knightrsquos tour on an m times n chessboard when m

and n are both odd

10

August 2010

Master of Computer Application (MCA) ndash Semester 2

MC0068 ndash Data Structures using C

Assignment Set ndash 2

1 Describe the theory of circular singly linked lists

Ans- The linked lisis that we have seen so far are often known as linear linked

lists The elements of such a linked list can be accessed first by setting up a

pointer pointing to the first node in the list and then traversing the entire list using

this pointer Although a linear linked list is a useful data structure it has several

shortcomings For example given a pointer p to a node in a linear list we cannot

reach any of the nodes that precede the node to which p is pointing This

disadvantage can be overcome by making a small change to the structure of a

linear list such that the link field in the last node contains a pointer back to the

first node rather than a NULL Such a list is called a circular linked list

2 Describe following Binary Trees

A) Strictly Binary trees - A binary tree is a finite set of elements that is either

empty or is partitioned into three disjoint subsets The first subset contains a

single element called the root of the tree The other two subsets are themselves

binary trees called the left and rightsubtrees of the original tree A left or right

subtree can be empty Each element of a binary tree is called a node of the tree

and the tree consists of nine nodes with A as its root Its left subtree is rooted at B

and its right subtree is rooted at C This is indicated by the two branches

emanating from A to B on the left and to C on the right The absence of a branch

indicates an empty subtree For example the left subtree of the binary tree rooted

at C and the right subtree of the binary tree rooted at E are both empty The

binary trees rooted at D G H and I have empty right and left subtrees Following

figure illustrates some structures that are not binary trees Be sure that you

understand why each of them is not a binary tree as just defined

B) Complete Binary trees - A binary tree is made of nodes where each node contains a

left pointer a right pointer and a data element The root pointer points to the topmost

node in the tree The left and right pointers recursively point to smaller subtrees on either

side A null pointer represents a binary tree with no elements -- the empty tree The formal

11

recursive definition is a binary tree is either empty (represented by a null pointer) or is made

of a single node where the left and right pointers (recursive definition ahead) each point to a

binary tree

C) Almost Complete Binary Trees - All leafs at lowest and next-tolowest levels onlyAll

except the lowest level is fullNo gaps except at the end of a level A perfectly balanced tree with

leaves at the last level all in the leftmost position A tree which can be represented

without any vacant space in the array representation

3 With the help of a program and an example explain Breadth First Tree

Traversal

Ans- Certain programming problems are easier to solve using multiple data structures

For example testing a sequence of characters to determine if it is a palindrome (ie reads the same forward and backward like radar) can be accomplished easily with one stack and one queue The solution is to enter the sequence of characters into both data structures then remove letters from each data structure one at a time and compare them making sure that the letters match

In this palindrome example the user (person writing the main program) has access to both data structures to solve the problem Another way that 2 data structures can be used in concert is to use one data structure to help implement another

treeh treec------ ------ include treeh include queueh

typedef char treeElementT typedef struct treeNodeTag treeElementT element struct treeNodeTag left right treeNodeT

typedef struct treeCDT typedef struct treeCDT treeADT treeNodeT root treeCDT

4 Write a program to perform a binary search on an unsorted list of n integers

Ans-

Program Example-

includeltstdiohgt

includeltconiohgt

12

includeltmathhgt

int main()

int a[20]= 0

int n i j temp

int beg end mid target

printf( enter the total integers you want to enter (make it less

then 20)n)

scanf(d ampn)

if (n gt= 20) return 0

printf( enter the integer array elementsn )

for(i = 0 i lt n i++)

scanf(d ampa[i])

for(i = 0 i lt n-1 i++)

for(j = 0 j lt n-i-1 j++)

if (a[j+1] lt a[j])

temp = a[j]

a[j] = a[j+1]

a[j+1] = temp

13

printf( the sorted numbers are)

for(i = 0 i lt n i++)

printf(d a[i])

beg = ampa[0]

end = ampa[n]

mid = beg += n2

printf(n enter the number to be searched)

scanf(damptarget)

while((beg lt= end) ampamp (mid = target))

if (target lt mid)

end = mid ndash 1

n = n2

mid = beg += n2

else

beg = mid + 1

n = n2

mid = beg += n2

14

if (mid == target)

printf(n d found target)

else

printf(n d not found target)

getchar()

getchar()

return 0

5 With the help of a numerical example explain the working of Insertion Sort

Ans- When sorting an array with insertion sort we conceptually separate it into two parts

The list of elements already inserted which is always in sorted order and is found at the

beginning of the arrayThe list of elements we have yet to insert following

In outline our primary function looks like thisltltinsertion_sortgtgt=void insertion_sort(int a[] int length) int i for (i=0 i lt length i++) insert a[i] into sorted sublist

To insert each element we need to create a hole in the array at the place where the element

belongs then place the element in that hole We can combine the creation of the hole with the

searching for the place by starting at the end and shifting each element up by one until we find

15

the place where the element belongs This overwrites the element were inserting so we have

to save it in a variable firstltltinsert a[i] into sorted sublistgtgt=int j v = a[i]

for (j = i - 1 j gt= 0 j--) if (a[j] lt= v) break a[j + 1] = a[j]

a[j + 1] = v

6 Describe Depth First search algorithm and analyze its complexity

Ans- Formally DFS is an uninformed search that progresses by expanding the first child node of the search tree that appears and thus going deeper and deeper until a goal node is found or until it hits a node that has no children Then the search backtracks returning to the most recent node it hasnt finished exploring In a non-recursive implementation all freshly expanded nodes are added to a stack for exploration

The time and space analysis of DFS differs according to its application area In theoretical computer science DFS is typically used to traverse an entire graph and takes time O(|V| + |E|) linear in the size of the graph In these applications it also uses space O(|V|) in the worst case to store the stack of vertices on the current search path as well as the set of already-visited vertices Thus in this setting the time and space bounds are the same as for breadth first search and the choice of which of these two algorithms to use depends less on their complexity and more on the different properties of the vertex orderings the two algorithms produce

a depth-first search starting at A assuming that the left edges in the shown graph are chosen before right edges and assuming the search remembers previously-visited nodes and will not repeat them (since this is a small graph) will visit the nodes in the following order A B D F E C G

Performing the same search without remembering previously visited nodes results in visiting nodes in the order A B D F E A B D F E etc forever caught in the A B D F E cycle and never reaching C or G

16

7 Explain the following theorems of Splay trees

A) Working Set Theorem - A splay tree is a self-adjusting binary search tree with the additional property that recently accessed elements are quick to access again It performs basic operations such as insertion look-up and removal in O(log n) amortized time For many sequences of operations splay trees perform better than other search trees even when the specific pattern of the sequence is unknown

All normal operations on a binary search tree are combined with one basic operation called splaying Splaying the tree for a certain element rearranges the tree so that the element is placed at the root of the tree One way to do this is to first perform a standard binary tree search for the element in question and then use tree rotations in a specific fashion to bring the element to the top Alternatively a top-down algorithm can combine the search and the tree reorganization into a single phase

When a node x is accessed a splay operation is performed on x to move it to the root To perform a splay operation we carry out a sequence of splay steps each of which moves x closer to the root By performing a splay operation on the node of interest after every access the recently accessed nodes are kept near the root and the tree remains roughly balanced so that we achieve the desired amortized time bounds

B) Sequential Access Theorem - When a node x is accessed a splay operation is

performed on x to move it to the root To perform a splay operation we carry out a

sequence of splay steps each of which moves x closer to the root By performing a splay

operation on the node of interest after every access the recently accessed nodes are kept

near the root and the tree remains roughly balanced so that we achieve the desired

amortized time boundsEach particular step depends on three factors

Whether x is the left or right child of its parent node p

whether p is the root or not and if not

whether p is the left or right child of its parent g (the grandparent of x)

The three types of splay steps are

Zig Step This step is done when p is the root The tree is rotated on the edge between x

and p Zig steps exist to deal with the parity issue and will be done only as the last step in

a splay operation and only when x has odd depth at the beginning of the operation

Zig-zig Step This step is done when p is not the root and x and p are either both right

children or are both left children The picture below shows the case where x and p are both

left children The tree is rotated on the edge joining p with its parent g then rotated on the

17

edge joining x with p Note that zig-zig steps are the only thing that differentiate splay

trees from the rotate to root method introduced by Allen and Munro prior to the

introduction of splay trees

Zig-zag Step This step is done when p is not the root and x is a right child and p is a left

child or vice versa The tree is rotated on the edge between x and p then rotated on the

edge between x and its new parent g

C) Dynamic Finger Theorem - A simple amortized analysis of static splay trees can be carried out using the potential method Suppose that size(r) is the number of nodes in the subtree rooted at r (including r) and rank(r) = log2(size(r)) Then the potential function P(t) for a splay tree t is the sum of the ranks of all the nodes in the tree This will tend to be high for poorly-balanced trees and low for well-balanced trees We can bound the amortized cost of any zig-zig or zig-zag operation by

amortized cost = cost + P(tf) - P(ti) le 3(rankf(x) - ranki(x))

where x is the node being moved towards the root and the subscripts f and i indicate after and before the operation respectively When summed over the entire splay operation this telescopes to 3(rank(root)) which is O(log n) Since theres at most one zig operation this only adds a constant

Dynamic Finger Theorem The cost of performing S is O(m+n log n + sum mi=1 log( |Ij+1 ndash Ij + 1 ))

8 Explain the following in the context of files

A) Sequential Files - True random access file handling however only accesses the file at the point at which the data should be read or written rather than having to process it sequentially A hybrid approach is also possible whereby a part of the file is used for sequential access to locate something in the random access portion of the file in much the same way that a File Allocation Table (FAT) worksThe three main functions that this article will deal with are

rewind() ndash return the file pointer to the beginning fseek() ndash position the file pointer ftell() ndash return the current offset of the file pointer

Each of these functions operates on the C file pointer which is just the offset from the start of the file and can be positioned at will All readwrite operations take place at the current position of the file pointer The rewind() Function The rewind() function can be used in sequential or random access C file programming and simply tells the file system to position the file pointer at the start of the file Any error flags will also be cleared and no value is returned While useful the companion function fseek() can also be used to reposition the file pointer at will including the same behavior as rewind() Using fseek() and ftell() to Process Files

18

The fseek() function is most useful in random access files where either the record (or block) size is known or there is an allocation system that denotes the start and end positions of records in an index portion of the file The fseek() function takes three parameters

FILE f ndash the file pointer long offset ndash the position offset int origin ndash the point from which the offset is applied

B) Inverted Files - The inverted index data structure is a central component of a typical search engine indexing algorithm A goal of a search engine implementation is to optimize the speed of the query find the documents where word X occurs Once a forward index is developed which stores lists of words per document it is next inverted to develop an inverted index Querying the forward index would require sequential iteration through each document and to each word to verify a matching document The time memory and processing resources to perform such a query are not always technically realistic Instead of listing the words per document in the forward index the inverted index data structure is developed which lists the documents per word

With the inverted index created the query can now be resolved by jumping to the word id (via random access) in the inverted index

In pre-computer times concordances to important books were manually assembled These were effectively inverted indexes with a small amount of accompanying commentary that required a tremendous amount of effort to produce

There are two main variants of inverted indexes A record level inverted index (or inverted file index or just inverted file) contains a list of references to documents for each word A word level inverted index (or full inverted index or inverted list) additionally contains the positions of each word within a document The latter form offers more functionality (like phrase searches) but needs more time and space to be created

19

  • Ans- Stack operations-
Page 2: SEM_2_MC0068_ Data Structures Using C

Example-include ltstdiohgt

struct matrix int rows int cols int val a = rows=3 cols=1 val = (int[3]) (int[1])1 (int[1])2 (int[1])3

b = rows=3 cols=4 val = (int[3]) (int[4])1 2 3 4 (int[4])5 6 7 8 (int[4])9101112

void print_matrix( char name struct matrix m ) for( int row=0rowltm-gtrowsrow++ ) for( int col=0colltm-gtcolscol++ ) printf( s[i][i] in name row col m-gtval[row][col] ) puts()

int main() print_matrix( a ampa ) print_matrix( b ampb )

3 Explain the theory of non linear data structures

Ans- Linear data structure A linear data structure traverses the data elements sequentially in

which only one data element can directly be reached in which insertion and deletion is possible in

linearsequential fashion example- arrays linked listsNon linear data structures-in which sequential

updation addition is not possible example- trees stacksLinear data structures Arrays Linked

ListNon-Linear data strctures trees GraphsIn Linear data structures traversals are linear are

multidimensional arrays and graphs In the next few lessons we will examine these data structures to

see how they are represented using the computers linear memoryIn a non-linear the data items are

not arrangedNon-Linear container classes represent trees and graphs Each node or item may be

connected with two or more other nodes or items in a non-linear arrangement Moreover removing one

of the links could

Ex Arrays Linked Lists

4 Write a program in C showing the implementation of stack operations

using structures

Ans- Stack operations-

2

Push and pop are the operations that are provided for insertion of an element into the stack and the removal of an element from the stackExample-include ltstdiohgt include ltstdlibhgt include stackh define size 3 void main() int topelement int stack[size] init(amptop) while(full(amptopsize)) element = rand() printf(push element d into stacknelement) push(stackamptopelement) getchar() printf(stack is fulln) while(empty(amptop)) element = pop(stackamptop) printf(pop element d from stacknelement) getchar() printf(stack is emptyn) getchar()

5 Describe the theory and applications of Double Ended Queues (Deque) and

circular queues

Ans-

Double Ended Queues (Deque)- Like an ordinary queue a double-ended queue is a container It supports the following operations enq_front enq_back deq_front deq_back and empty

By choosing a subset of these operations you can make the double-ended queue behave like a stack or like a queue For instance if you use only enq_front and deq_front you get a stack and if you use only enq_front and deq_back you get a queue

By now the reader should be used to using header objects in order to obtain uniform reference semantics We will therefore go directly to a version of the double-ended queue with a separate header file and implementation file

Example-

3

include dqueueh include dlisth include lt stdlibhgt

struct dqueue dlist head dlist tail

dqueue dq_create(void) dqueue q = malloc(sizeof(struct dqueue)) q -gt head = q -gt tail = NULL return q

int dq_empty(dqueue q) return q -gt head == NULL

void dq_enq_front(dqueue q void element) if(dq_empty(q)) q -gt head = q -gt tail = dcons(element NULL NULL) else q -gt head -gt prev = dcons(element NULL q -gt head)

q -gt head -gt prev -gt next = q -gt head

q -gt head = q -gt head -gt prev

void dq_enq_back(dqueue q void element) if(dq_empty(q)) q -gt head = q -gt tail = dcons(element NULL NULL)

else q -gt tail -gt next = dcons(element q -gt tail NULL)

q -gt tail -gt next -gt prev = q -gt tail

q -gt tail = q -gt tail -gt next

void dq_deq_front(dqueue q) assert(empty(q)) dqueue temp = q -gt head void element = temp -gt element q -gt head = q -gt head -gt next free(temp) if(q -gt head == NULL) q -gt tail = NULL else q -gt head -gt prev = NULL return element

void dq_deq_back(dqueue q) assert(empty(q)) dqueue temp = q -gt tail void element = temp -gt element q -gt tail = q -gt tail -gt prev free(temp) if(q -gt tail == NULL) q -gt head = NULL else q -gt tail -gt next = NULL return element

circular queues- A circular queue is a particular implementation of a queue It is very efficient It is also quite useful in low level code because insertion and deletion are totally independant which

4

means that you dont have to worry about an interrupt handler trying to do an insertion at the same time as your main code is doing a deletion

Example-include ltstdiohgtinclude ltstdlibhgt

define MAX 10

void insert(int queue[] int rear int front int value) rear= (rear +1) MAX if(rear == front) printf(The queue is full can not insert a valuen) exit(0) queue[rear] = value

void delete(int queue[] int front int rear int value) if(front == rear) printf(The queue is empty can not delete a valuen) exit(0) front = (front + 1) MAX value = queue[front]

void main() int queue[MAX] int frontrear int nvalue front=0 rear=0

insert(queueamprearfront1) insert(queueamprearfront2) insert(queueamprearfront3) insert(queueamprearfront4) delete(queueampfrontrearampvalue) printf(The value deleted is dnvalue)

delete(queueampfrontrearampvalue) printf(The value deleted is dnvalue)

delete(queueampfrontrearampvalue) printf(The value deleted is dnvalue)

5

6 With the help of a suitable numerical example describe the following

concepts of a Binary Search Tree

A) Analysis of BST - carry out an Analysis of this method to determine its time complexity Since there are no ldquoforrdquo loops we can not use summations to express the total number ofoperations Let us examine the operations for a specific case where the number ofelements in the array n is 64When n= 64 BinarySearch is called to reduce size to n=32When n= 32 BinarySearch is called to reduce size to n=16When n= 16 BinarySearch is called to reduce size to n=8When n= 8 BinarySearch is called to reduce size to n=4When n= 4 BinarySearch is called to reduce size to n=2When n= 2 BinarySearch is called to reduce size to n=1

int BinarySearch (int A[ ] int n int K)int L=0 Mid R= n-1while (Llt=R)Mid = (L +R)2if ( K= =A[Mid] )return Midelse if ( K gt A[Mid] )L = Mid + 1elseR = Mid ndash 1 return ndash1

B) Insertion of Nodes into a BST - To insert a node into a BST

1 find a leaf st the appropriate place and 2 connect the node to the parent of the leaf

TREE-INSERT (T z)

y larr NILx larr root [T]while x ne NIL do y larr x if key [z] lt key[x] then x larr left[x] else x larr right[x]p[z] larr yif y = NIL then root [T] larr z else if key [z] lt key [y]

6

then left [y] larr z else right [y] larr z

Like other primitive operations on search trees this algorithm begins at the root of the tree and traces a path downward Clearly it runs in O(h) time on a tree of height h

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

Ans-include ltstdiohgt

The input file (weighttxt) look something like this

40 0 0 210 0 8 170 8 0 1621 17 16 0

The first line contains n the number of nodesNext is an nxn matrix containg the distances between the nodesNOTE The distance between a node and itself should be 0

int n The number of nodes in the graph

int weight[100][100] weight[i][j] is the distance between node i and node j

if there is no path between i and j weight[i][j] should

be 0

char inTree[100] inTree[i] is 1 if the node i is already in the minimum

spanning tree 0 otherwise

int d[100] d[i] is the distance between node i and the minimum spanning

tree this is initially infinity (100000) if i is already in

the tree then d[i] is undefinedthis is just a temporary variable Its not necessary

but speedsup execution considerably (by a factor of n)

int whoTo[100] whoTo[i] holds the index of the node i would have to be

linked to in order to get a distance of d[i]

updateDistances(int target)

7

should be called immediately after target is added to the tree

updates d so that the values are correct (goes through targets

neighbours making sure that the distances between them and the tree

are indeed minimum)void updateDistances(int target)

int ifor (i = 0 i lt n ++i)

if ((weight[target][i] = 0) ampamp (d[i] gt weight[target][i]))

d[i] = weight[target][i]whoTo[i] = target

int main(int argc char argv[]) FILE f = fopen(disttxt r)fscanf(f d ampn)int i jfor (i = 0 i lt n ++i)

for (j = 0 j lt n ++j)fscanf(f d ampweight[i][j])

fclose(f)

Initialise d with infinity for (i = 0 i lt n ++i)

d[i] = 100000

Mark all nodes as NOT beeing in the minimum spanning tree

for (i = 0 i lt n ++i)inTree[i] = 0

Add the first node to the tree printf(Adding node cn 0 + A)inTree[0] = 1updateDistances(0)

int total = 0int treeSizefor (treeSize = 1 treeSize lt n ++treeSize)

Find the node with the smallest distance to the tree

int min = -1for (i = 0 i lt n ++i)

if (inTree[i])if ((min == -1) || (d[min] gt d[i]))

min = i

8

And add it printf(Adding edge c-cn whoTo[min] + A min +

A)inTree[min] = 1total += d[min]

updateDistances(min)

printf(Total distance dn total)

return 0

8 Explain the following graph problems

A) Telecommunication problem - Subscription con_guration problem and is taken (with slight modi_cation) from [4]Let F denote a _nite set of features For fi fj 2 F a precedence constraint(figtfj) indicates that fi is after fj An exclusion constraint (filtgtfj) between fiand fj indicates that fi and fj cannot appear together in a sequence of featuresand is equivalent to the pair (figtfj ) (fjgtfi) A catalog is a pair hF Pi with F aset of features and P a set of precedence constraints on F A feature subscriptionS of a catalog hFc Pci is a tuple hFCUWF WUi where F _ Fc is the set offeatures selected from Fc C is the projection of Pc on F U is a set of user de_nedprecedence constraints on F and WF F N and WUU N are maps whichassign weights to features and user precedence constraints The value of S isde_ned by V alue(S) = _f2FWF (f) + _p2UWU(p) The weight associated witha feature or a precedence constraint signi_es its importance for the userA feature subscription hFCUWF WUi is consistent i_ the directed graphhFC[Ui is acyclic Checking for consistency is straightforward using topologicalsort as described in [4] If a feature subscription is inconsistent then the task isto relax it and to generate a consistent one with maximum value A relaxationof a feature subscription S = hFCUWF WUi is a consistent subscriptionS0 = hF0C0U0WF0 WU0 i such that F0 _ F C0 is the projection of C on F0U0 is a subset of the projection of U on F0 WF0 is the restriction of WF to F0and WU0 is the restriction of WU to U0 We say that S0 is an optimal relaxationof S if there does not exist another relaxation S00 of S such that V alue(S00) gtV alue(S0) In [4] the authors prove that _nding an optimal relaxation of afeature subscription is NP-hard This is the problem addressed in this paper

B) Knight Moves - A knight is a chess piece that can move either two spaces horizontally and one space vertically or one space horizontally and two spaces vertically That is a knight on square (xy) can move to any of the eight squares (x plusmn 2y plusmn 1) (x plusmn 1y plusmn 2) if these squares exist on the chessboard (which is normally 8 times 8) A knightrsquos tour is a sequence of legal moves by a knight starting at some square and visiting each square exactly once A knightrsquos tour is called reentrant if there is a legal move that takes the knight from the last square of the tour back to where the tour began We can model knightrsquos tours using the graph that has a vertex for each square

9

on the boardwith an edge connecting two vertices if a knight can legally move between the squares represented by these vertices (a) Show that finding a reentrant knightrsquos tour on an m times n chessboard is equivalent to finding a Hamilton circuit on the corresponding graph (b) Show that the graph representing the legal moves of a knight on a mtimesn chessboard wherever m and n are positive integers is bipartite (c) Deduce that there is no reentrant knightrsquos tour on an m times n chessboard when m

and n are both odd

10

August 2010

Master of Computer Application (MCA) ndash Semester 2

MC0068 ndash Data Structures using C

Assignment Set ndash 2

1 Describe the theory of circular singly linked lists

Ans- The linked lisis that we have seen so far are often known as linear linked

lists The elements of such a linked list can be accessed first by setting up a

pointer pointing to the first node in the list and then traversing the entire list using

this pointer Although a linear linked list is a useful data structure it has several

shortcomings For example given a pointer p to a node in a linear list we cannot

reach any of the nodes that precede the node to which p is pointing This

disadvantage can be overcome by making a small change to the structure of a

linear list such that the link field in the last node contains a pointer back to the

first node rather than a NULL Such a list is called a circular linked list

2 Describe following Binary Trees

A) Strictly Binary trees - A binary tree is a finite set of elements that is either

empty or is partitioned into three disjoint subsets The first subset contains a

single element called the root of the tree The other two subsets are themselves

binary trees called the left and rightsubtrees of the original tree A left or right

subtree can be empty Each element of a binary tree is called a node of the tree

and the tree consists of nine nodes with A as its root Its left subtree is rooted at B

and its right subtree is rooted at C This is indicated by the two branches

emanating from A to B on the left and to C on the right The absence of a branch

indicates an empty subtree For example the left subtree of the binary tree rooted

at C and the right subtree of the binary tree rooted at E are both empty The

binary trees rooted at D G H and I have empty right and left subtrees Following

figure illustrates some structures that are not binary trees Be sure that you

understand why each of them is not a binary tree as just defined

B) Complete Binary trees - A binary tree is made of nodes where each node contains a

left pointer a right pointer and a data element The root pointer points to the topmost

node in the tree The left and right pointers recursively point to smaller subtrees on either

side A null pointer represents a binary tree with no elements -- the empty tree The formal

11

recursive definition is a binary tree is either empty (represented by a null pointer) or is made

of a single node where the left and right pointers (recursive definition ahead) each point to a

binary tree

C) Almost Complete Binary Trees - All leafs at lowest and next-tolowest levels onlyAll

except the lowest level is fullNo gaps except at the end of a level A perfectly balanced tree with

leaves at the last level all in the leftmost position A tree which can be represented

without any vacant space in the array representation

3 With the help of a program and an example explain Breadth First Tree

Traversal

Ans- Certain programming problems are easier to solve using multiple data structures

For example testing a sequence of characters to determine if it is a palindrome (ie reads the same forward and backward like radar) can be accomplished easily with one stack and one queue The solution is to enter the sequence of characters into both data structures then remove letters from each data structure one at a time and compare them making sure that the letters match

In this palindrome example the user (person writing the main program) has access to both data structures to solve the problem Another way that 2 data structures can be used in concert is to use one data structure to help implement another

treeh treec------ ------ include treeh include queueh

typedef char treeElementT typedef struct treeNodeTag treeElementT element struct treeNodeTag left right treeNodeT

typedef struct treeCDT typedef struct treeCDT treeADT treeNodeT root treeCDT

4 Write a program to perform a binary search on an unsorted list of n integers

Ans-

Program Example-

includeltstdiohgt

includeltconiohgt

12

includeltmathhgt

int main()

int a[20]= 0

int n i j temp

int beg end mid target

printf( enter the total integers you want to enter (make it less

then 20)n)

scanf(d ampn)

if (n gt= 20) return 0

printf( enter the integer array elementsn )

for(i = 0 i lt n i++)

scanf(d ampa[i])

for(i = 0 i lt n-1 i++)

for(j = 0 j lt n-i-1 j++)

if (a[j+1] lt a[j])

temp = a[j]

a[j] = a[j+1]

a[j+1] = temp

13

printf( the sorted numbers are)

for(i = 0 i lt n i++)

printf(d a[i])

beg = ampa[0]

end = ampa[n]

mid = beg += n2

printf(n enter the number to be searched)

scanf(damptarget)

while((beg lt= end) ampamp (mid = target))

if (target lt mid)

end = mid ndash 1

n = n2

mid = beg += n2

else

beg = mid + 1

n = n2

mid = beg += n2

14

if (mid == target)

printf(n d found target)

else

printf(n d not found target)

getchar()

getchar()

return 0

5 With the help of a numerical example explain the working of Insertion Sort

Ans- When sorting an array with insertion sort we conceptually separate it into two parts

The list of elements already inserted which is always in sorted order and is found at the

beginning of the arrayThe list of elements we have yet to insert following

In outline our primary function looks like thisltltinsertion_sortgtgt=void insertion_sort(int a[] int length) int i for (i=0 i lt length i++) insert a[i] into sorted sublist

To insert each element we need to create a hole in the array at the place where the element

belongs then place the element in that hole We can combine the creation of the hole with the

searching for the place by starting at the end and shifting each element up by one until we find

15

the place where the element belongs This overwrites the element were inserting so we have

to save it in a variable firstltltinsert a[i] into sorted sublistgtgt=int j v = a[i]

for (j = i - 1 j gt= 0 j--) if (a[j] lt= v) break a[j + 1] = a[j]

a[j + 1] = v

6 Describe Depth First search algorithm and analyze its complexity

Ans- Formally DFS is an uninformed search that progresses by expanding the first child node of the search tree that appears and thus going deeper and deeper until a goal node is found or until it hits a node that has no children Then the search backtracks returning to the most recent node it hasnt finished exploring In a non-recursive implementation all freshly expanded nodes are added to a stack for exploration

The time and space analysis of DFS differs according to its application area In theoretical computer science DFS is typically used to traverse an entire graph and takes time O(|V| + |E|) linear in the size of the graph In these applications it also uses space O(|V|) in the worst case to store the stack of vertices on the current search path as well as the set of already-visited vertices Thus in this setting the time and space bounds are the same as for breadth first search and the choice of which of these two algorithms to use depends less on their complexity and more on the different properties of the vertex orderings the two algorithms produce

a depth-first search starting at A assuming that the left edges in the shown graph are chosen before right edges and assuming the search remembers previously-visited nodes and will not repeat them (since this is a small graph) will visit the nodes in the following order A B D F E C G

Performing the same search without remembering previously visited nodes results in visiting nodes in the order A B D F E A B D F E etc forever caught in the A B D F E cycle and never reaching C or G

16

7 Explain the following theorems of Splay trees

A) Working Set Theorem - A splay tree is a self-adjusting binary search tree with the additional property that recently accessed elements are quick to access again It performs basic operations such as insertion look-up and removal in O(log n) amortized time For many sequences of operations splay trees perform better than other search trees even when the specific pattern of the sequence is unknown

All normal operations on a binary search tree are combined with one basic operation called splaying Splaying the tree for a certain element rearranges the tree so that the element is placed at the root of the tree One way to do this is to first perform a standard binary tree search for the element in question and then use tree rotations in a specific fashion to bring the element to the top Alternatively a top-down algorithm can combine the search and the tree reorganization into a single phase

When a node x is accessed a splay operation is performed on x to move it to the root To perform a splay operation we carry out a sequence of splay steps each of which moves x closer to the root By performing a splay operation on the node of interest after every access the recently accessed nodes are kept near the root and the tree remains roughly balanced so that we achieve the desired amortized time bounds

B) Sequential Access Theorem - When a node x is accessed a splay operation is

performed on x to move it to the root To perform a splay operation we carry out a

sequence of splay steps each of which moves x closer to the root By performing a splay

operation on the node of interest after every access the recently accessed nodes are kept

near the root and the tree remains roughly balanced so that we achieve the desired

amortized time boundsEach particular step depends on three factors

Whether x is the left or right child of its parent node p

whether p is the root or not and if not

whether p is the left or right child of its parent g (the grandparent of x)

The three types of splay steps are

Zig Step This step is done when p is the root The tree is rotated on the edge between x

and p Zig steps exist to deal with the parity issue and will be done only as the last step in

a splay operation and only when x has odd depth at the beginning of the operation

Zig-zig Step This step is done when p is not the root and x and p are either both right

children or are both left children The picture below shows the case where x and p are both

left children The tree is rotated on the edge joining p with its parent g then rotated on the

17

edge joining x with p Note that zig-zig steps are the only thing that differentiate splay

trees from the rotate to root method introduced by Allen and Munro prior to the

introduction of splay trees

Zig-zag Step This step is done when p is not the root and x is a right child and p is a left

child or vice versa The tree is rotated on the edge between x and p then rotated on the

edge between x and its new parent g

C) Dynamic Finger Theorem - A simple amortized analysis of static splay trees can be carried out using the potential method Suppose that size(r) is the number of nodes in the subtree rooted at r (including r) and rank(r) = log2(size(r)) Then the potential function P(t) for a splay tree t is the sum of the ranks of all the nodes in the tree This will tend to be high for poorly-balanced trees and low for well-balanced trees We can bound the amortized cost of any zig-zig or zig-zag operation by

amortized cost = cost + P(tf) - P(ti) le 3(rankf(x) - ranki(x))

where x is the node being moved towards the root and the subscripts f and i indicate after and before the operation respectively When summed over the entire splay operation this telescopes to 3(rank(root)) which is O(log n) Since theres at most one zig operation this only adds a constant

Dynamic Finger Theorem The cost of performing S is O(m+n log n + sum mi=1 log( |Ij+1 ndash Ij + 1 ))

8 Explain the following in the context of files

A) Sequential Files - True random access file handling however only accesses the file at the point at which the data should be read or written rather than having to process it sequentially A hybrid approach is also possible whereby a part of the file is used for sequential access to locate something in the random access portion of the file in much the same way that a File Allocation Table (FAT) worksThe three main functions that this article will deal with are

rewind() ndash return the file pointer to the beginning fseek() ndash position the file pointer ftell() ndash return the current offset of the file pointer

Each of these functions operates on the C file pointer which is just the offset from the start of the file and can be positioned at will All readwrite operations take place at the current position of the file pointer The rewind() Function The rewind() function can be used in sequential or random access C file programming and simply tells the file system to position the file pointer at the start of the file Any error flags will also be cleared and no value is returned While useful the companion function fseek() can also be used to reposition the file pointer at will including the same behavior as rewind() Using fseek() and ftell() to Process Files

18

The fseek() function is most useful in random access files where either the record (or block) size is known or there is an allocation system that denotes the start and end positions of records in an index portion of the file The fseek() function takes three parameters

FILE f ndash the file pointer long offset ndash the position offset int origin ndash the point from which the offset is applied

B) Inverted Files - The inverted index data structure is a central component of a typical search engine indexing algorithm A goal of a search engine implementation is to optimize the speed of the query find the documents where word X occurs Once a forward index is developed which stores lists of words per document it is next inverted to develop an inverted index Querying the forward index would require sequential iteration through each document and to each word to verify a matching document The time memory and processing resources to perform such a query are not always technically realistic Instead of listing the words per document in the forward index the inverted index data structure is developed which lists the documents per word

With the inverted index created the query can now be resolved by jumping to the word id (via random access) in the inverted index

In pre-computer times concordances to important books were manually assembled These were effectively inverted indexes with a small amount of accompanying commentary that required a tremendous amount of effort to produce

There are two main variants of inverted indexes A record level inverted index (or inverted file index or just inverted file) contains a list of references to documents for each word A word level inverted index (or full inverted index or inverted list) additionally contains the positions of each word within a document The latter form offers more functionality (like phrase searches) but needs more time and space to be created

19

  • Ans- Stack operations-
Page 3: SEM_2_MC0068_ Data Structures Using C

Push and pop are the operations that are provided for insertion of an element into the stack and the removal of an element from the stackExample-include ltstdiohgt include ltstdlibhgt include stackh define size 3 void main() int topelement int stack[size] init(amptop) while(full(amptopsize)) element = rand() printf(push element d into stacknelement) push(stackamptopelement) getchar() printf(stack is fulln) while(empty(amptop)) element = pop(stackamptop) printf(pop element d from stacknelement) getchar() printf(stack is emptyn) getchar()

5 Describe the theory and applications of Double Ended Queues (Deque) and

circular queues

Ans-

Double Ended Queues (Deque)- Like an ordinary queue a double-ended queue is a container It supports the following operations enq_front enq_back deq_front deq_back and empty

By choosing a subset of these operations you can make the double-ended queue behave like a stack or like a queue For instance if you use only enq_front and deq_front you get a stack and if you use only enq_front and deq_back you get a queue

By now the reader should be used to using header objects in order to obtain uniform reference semantics We will therefore go directly to a version of the double-ended queue with a separate header file and implementation file

Example-

3

include dqueueh include dlisth include lt stdlibhgt

struct dqueue dlist head dlist tail

dqueue dq_create(void) dqueue q = malloc(sizeof(struct dqueue)) q -gt head = q -gt tail = NULL return q

int dq_empty(dqueue q) return q -gt head == NULL

void dq_enq_front(dqueue q void element) if(dq_empty(q)) q -gt head = q -gt tail = dcons(element NULL NULL) else q -gt head -gt prev = dcons(element NULL q -gt head)

q -gt head -gt prev -gt next = q -gt head

q -gt head = q -gt head -gt prev

void dq_enq_back(dqueue q void element) if(dq_empty(q)) q -gt head = q -gt tail = dcons(element NULL NULL)

else q -gt tail -gt next = dcons(element q -gt tail NULL)

q -gt tail -gt next -gt prev = q -gt tail

q -gt tail = q -gt tail -gt next

void dq_deq_front(dqueue q) assert(empty(q)) dqueue temp = q -gt head void element = temp -gt element q -gt head = q -gt head -gt next free(temp) if(q -gt head == NULL) q -gt tail = NULL else q -gt head -gt prev = NULL return element

void dq_deq_back(dqueue q) assert(empty(q)) dqueue temp = q -gt tail void element = temp -gt element q -gt tail = q -gt tail -gt prev free(temp) if(q -gt tail == NULL) q -gt head = NULL else q -gt tail -gt next = NULL return element

circular queues- A circular queue is a particular implementation of a queue It is very efficient It is also quite useful in low level code because insertion and deletion are totally independant which

4

means that you dont have to worry about an interrupt handler trying to do an insertion at the same time as your main code is doing a deletion

Example-include ltstdiohgtinclude ltstdlibhgt

define MAX 10

void insert(int queue[] int rear int front int value) rear= (rear +1) MAX if(rear == front) printf(The queue is full can not insert a valuen) exit(0) queue[rear] = value

void delete(int queue[] int front int rear int value) if(front == rear) printf(The queue is empty can not delete a valuen) exit(0) front = (front + 1) MAX value = queue[front]

void main() int queue[MAX] int frontrear int nvalue front=0 rear=0

insert(queueamprearfront1) insert(queueamprearfront2) insert(queueamprearfront3) insert(queueamprearfront4) delete(queueampfrontrearampvalue) printf(The value deleted is dnvalue)

delete(queueampfrontrearampvalue) printf(The value deleted is dnvalue)

delete(queueampfrontrearampvalue) printf(The value deleted is dnvalue)

5

6 With the help of a suitable numerical example describe the following

concepts of a Binary Search Tree

A) Analysis of BST - carry out an Analysis of this method to determine its time complexity Since there are no ldquoforrdquo loops we can not use summations to express the total number ofoperations Let us examine the operations for a specific case where the number ofelements in the array n is 64When n= 64 BinarySearch is called to reduce size to n=32When n= 32 BinarySearch is called to reduce size to n=16When n= 16 BinarySearch is called to reduce size to n=8When n= 8 BinarySearch is called to reduce size to n=4When n= 4 BinarySearch is called to reduce size to n=2When n= 2 BinarySearch is called to reduce size to n=1

int BinarySearch (int A[ ] int n int K)int L=0 Mid R= n-1while (Llt=R)Mid = (L +R)2if ( K= =A[Mid] )return Midelse if ( K gt A[Mid] )L = Mid + 1elseR = Mid ndash 1 return ndash1

B) Insertion of Nodes into a BST - To insert a node into a BST

1 find a leaf st the appropriate place and 2 connect the node to the parent of the leaf

TREE-INSERT (T z)

y larr NILx larr root [T]while x ne NIL do y larr x if key [z] lt key[x] then x larr left[x] else x larr right[x]p[z] larr yif y = NIL then root [T] larr z else if key [z] lt key [y]

6

then left [y] larr z else right [y] larr z

Like other primitive operations on search trees this algorithm begins at the root of the tree and traces a path downward Clearly it runs in O(h) time on a tree of height h

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

Ans-include ltstdiohgt

The input file (weighttxt) look something like this

40 0 0 210 0 8 170 8 0 1621 17 16 0

The first line contains n the number of nodesNext is an nxn matrix containg the distances between the nodesNOTE The distance between a node and itself should be 0

int n The number of nodes in the graph

int weight[100][100] weight[i][j] is the distance between node i and node j

if there is no path between i and j weight[i][j] should

be 0

char inTree[100] inTree[i] is 1 if the node i is already in the minimum

spanning tree 0 otherwise

int d[100] d[i] is the distance between node i and the minimum spanning

tree this is initially infinity (100000) if i is already in

the tree then d[i] is undefinedthis is just a temporary variable Its not necessary

but speedsup execution considerably (by a factor of n)

int whoTo[100] whoTo[i] holds the index of the node i would have to be

linked to in order to get a distance of d[i]

updateDistances(int target)

7

should be called immediately after target is added to the tree

updates d so that the values are correct (goes through targets

neighbours making sure that the distances between them and the tree

are indeed minimum)void updateDistances(int target)

int ifor (i = 0 i lt n ++i)

if ((weight[target][i] = 0) ampamp (d[i] gt weight[target][i]))

d[i] = weight[target][i]whoTo[i] = target

int main(int argc char argv[]) FILE f = fopen(disttxt r)fscanf(f d ampn)int i jfor (i = 0 i lt n ++i)

for (j = 0 j lt n ++j)fscanf(f d ampweight[i][j])

fclose(f)

Initialise d with infinity for (i = 0 i lt n ++i)

d[i] = 100000

Mark all nodes as NOT beeing in the minimum spanning tree

for (i = 0 i lt n ++i)inTree[i] = 0

Add the first node to the tree printf(Adding node cn 0 + A)inTree[0] = 1updateDistances(0)

int total = 0int treeSizefor (treeSize = 1 treeSize lt n ++treeSize)

Find the node with the smallest distance to the tree

int min = -1for (i = 0 i lt n ++i)

if (inTree[i])if ((min == -1) || (d[min] gt d[i]))

min = i

8

And add it printf(Adding edge c-cn whoTo[min] + A min +

A)inTree[min] = 1total += d[min]

updateDistances(min)

printf(Total distance dn total)

return 0

8 Explain the following graph problems

A) Telecommunication problem - Subscription con_guration problem and is taken (with slight modi_cation) from [4]Let F denote a _nite set of features For fi fj 2 F a precedence constraint(figtfj) indicates that fi is after fj An exclusion constraint (filtgtfj) between fiand fj indicates that fi and fj cannot appear together in a sequence of featuresand is equivalent to the pair (figtfj ) (fjgtfi) A catalog is a pair hF Pi with F aset of features and P a set of precedence constraints on F A feature subscriptionS of a catalog hFc Pci is a tuple hFCUWF WUi where F _ Fc is the set offeatures selected from Fc C is the projection of Pc on F U is a set of user de_nedprecedence constraints on F and WF F N and WUU N are maps whichassign weights to features and user precedence constraints The value of S isde_ned by V alue(S) = _f2FWF (f) + _p2UWU(p) The weight associated witha feature or a precedence constraint signi_es its importance for the userA feature subscription hFCUWF WUi is consistent i_ the directed graphhFC[Ui is acyclic Checking for consistency is straightforward using topologicalsort as described in [4] If a feature subscription is inconsistent then the task isto relax it and to generate a consistent one with maximum value A relaxationof a feature subscription S = hFCUWF WUi is a consistent subscriptionS0 = hF0C0U0WF0 WU0 i such that F0 _ F C0 is the projection of C on F0U0 is a subset of the projection of U on F0 WF0 is the restriction of WF to F0and WU0 is the restriction of WU to U0 We say that S0 is an optimal relaxationof S if there does not exist another relaxation S00 of S such that V alue(S00) gtV alue(S0) In [4] the authors prove that _nding an optimal relaxation of afeature subscription is NP-hard This is the problem addressed in this paper

B) Knight Moves - A knight is a chess piece that can move either two spaces horizontally and one space vertically or one space horizontally and two spaces vertically That is a knight on square (xy) can move to any of the eight squares (x plusmn 2y plusmn 1) (x plusmn 1y plusmn 2) if these squares exist on the chessboard (which is normally 8 times 8) A knightrsquos tour is a sequence of legal moves by a knight starting at some square and visiting each square exactly once A knightrsquos tour is called reentrant if there is a legal move that takes the knight from the last square of the tour back to where the tour began We can model knightrsquos tours using the graph that has a vertex for each square

9

on the boardwith an edge connecting two vertices if a knight can legally move between the squares represented by these vertices (a) Show that finding a reentrant knightrsquos tour on an m times n chessboard is equivalent to finding a Hamilton circuit on the corresponding graph (b) Show that the graph representing the legal moves of a knight on a mtimesn chessboard wherever m and n are positive integers is bipartite (c) Deduce that there is no reentrant knightrsquos tour on an m times n chessboard when m

and n are both odd

10

August 2010

Master of Computer Application (MCA) ndash Semester 2

MC0068 ndash Data Structures using C

Assignment Set ndash 2

1 Describe the theory of circular singly linked lists

Ans- The linked lisis that we have seen so far are often known as linear linked

lists The elements of such a linked list can be accessed first by setting up a

pointer pointing to the first node in the list and then traversing the entire list using

this pointer Although a linear linked list is a useful data structure it has several

shortcomings For example given a pointer p to a node in a linear list we cannot

reach any of the nodes that precede the node to which p is pointing This

disadvantage can be overcome by making a small change to the structure of a

linear list such that the link field in the last node contains a pointer back to the

first node rather than a NULL Such a list is called a circular linked list

2 Describe following Binary Trees

A) Strictly Binary trees - A binary tree is a finite set of elements that is either

empty or is partitioned into three disjoint subsets The first subset contains a

single element called the root of the tree The other two subsets are themselves

binary trees called the left and rightsubtrees of the original tree A left or right

subtree can be empty Each element of a binary tree is called a node of the tree

and the tree consists of nine nodes with A as its root Its left subtree is rooted at B

and its right subtree is rooted at C This is indicated by the two branches

emanating from A to B on the left and to C on the right The absence of a branch

indicates an empty subtree For example the left subtree of the binary tree rooted

at C and the right subtree of the binary tree rooted at E are both empty The

binary trees rooted at D G H and I have empty right and left subtrees Following

figure illustrates some structures that are not binary trees Be sure that you

understand why each of them is not a binary tree as just defined

B) Complete Binary trees - A binary tree is made of nodes where each node contains a

left pointer a right pointer and a data element The root pointer points to the topmost

node in the tree The left and right pointers recursively point to smaller subtrees on either

side A null pointer represents a binary tree with no elements -- the empty tree The formal

11

recursive definition is a binary tree is either empty (represented by a null pointer) or is made

of a single node where the left and right pointers (recursive definition ahead) each point to a

binary tree

C) Almost Complete Binary Trees - All leafs at lowest and next-tolowest levels onlyAll

except the lowest level is fullNo gaps except at the end of a level A perfectly balanced tree with

leaves at the last level all in the leftmost position A tree which can be represented

without any vacant space in the array representation

3 With the help of a program and an example explain Breadth First Tree

Traversal

Ans- Certain programming problems are easier to solve using multiple data structures

For example testing a sequence of characters to determine if it is a palindrome (ie reads the same forward and backward like radar) can be accomplished easily with one stack and one queue The solution is to enter the sequence of characters into both data structures then remove letters from each data structure one at a time and compare them making sure that the letters match

In this palindrome example the user (person writing the main program) has access to both data structures to solve the problem Another way that 2 data structures can be used in concert is to use one data structure to help implement another

treeh treec------ ------ include treeh include queueh

typedef char treeElementT typedef struct treeNodeTag treeElementT element struct treeNodeTag left right treeNodeT

typedef struct treeCDT typedef struct treeCDT treeADT treeNodeT root treeCDT

4 Write a program to perform a binary search on an unsorted list of n integers

Ans-

Program Example-

includeltstdiohgt

includeltconiohgt

12

includeltmathhgt

int main()

int a[20]= 0

int n i j temp

int beg end mid target

printf( enter the total integers you want to enter (make it less

then 20)n)

scanf(d ampn)

if (n gt= 20) return 0

printf( enter the integer array elementsn )

for(i = 0 i lt n i++)

scanf(d ampa[i])

for(i = 0 i lt n-1 i++)

for(j = 0 j lt n-i-1 j++)

if (a[j+1] lt a[j])

temp = a[j]

a[j] = a[j+1]

a[j+1] = temp

13

printf( the sorted numbers are)

for(i = 0 i lt n i++)

printf(d a[i])

beg = ampa[0]

end = ampa[n]

mid = beg += n2

printf(n enter the number to be searched)

scanf(damptarget)

while((beg lt= end) ampamp (mid = target))

if (target lt mid)

end = mid ndash 1

n = n2

mid = beg += n2

else

beg = mid + 1

n = n2

mid = beg += n2

14

if (mid == target)

printf(n d found target)

else

printf(n d not found target)

getchar()

getchar()

return 0

5 With the help of a numerical example explain the working of Insertion Sort

Ans- When sorting an array with insertion sort we conceptually separate it into two parts

The list of elements already inserted which is always in sorted order and is found at the

beginning of the arrayThe list of elements we have yet to insert following

In outline our primary function looks like thisltltinsertion_sortgtgt=void insertion_sort(int a[] int length) int i for (i=0 i lt length i++) insert a[i] into sorted sublist

To insert each element we need to create a hole in the array at the place where the element

belongs then place the element in that hole We can combine the creation of the hole with the

searching for the place by starting at the end and shifting each element up by one until we find

15

the place where the element belongs This overwrites the element were inserting so we have

to save it in a variable firstltltinsert a[i] into sorted sublistgtgt=int j v = a[i]

for (j = i - 1 j gt= 0 j--) if (a[j] lt= v) break a[j + 1] = a[j]

a[j + 1] = v

6 Describe Depth First search algorithm and analyze its complexity

Ans- Formally DFS is an uninformed search that progresses by expanding the first child node of the search tree that appears and thus going deeper and deeper until a goal node is found or until it hits a node that has no children Then the search backtracks returning to the most recent node it hasnt finished exploring In a non-recursive implementation all freshly expanded nodes are added to a stack for exploration

The time and space analysis of DFS differs according to its application area In theoretical computer science DFS is typically used to traverse an entire graph and takes time O(|V| + |E|) linear in the size of the graph In these applications it also uses space O(|V|) in the worst case to store the stack of vertices on the current search path as well as the set of already-visited vertices Thus in this setting the time and space bounds are the same as for breadth first search and the choice of which of these two algorithms to use depends less on their complexity and more on the different properties of the vertex orderings the two algorithms produce

a depth-first search starting at A assuming that the left edges in the shown graph are chosen before right edges and assuming the search remembers previously-visited nodes and will not repeat them (since this is a small graph) will visit the nodes in the following order A B D F E C G

Performing the same search without remembering previously visited nodes results in visiting nodes in the order A B D F E A B D F E etc forever caught in the A B D F E cycle and never reaching C or G

16

7 Explain the following theorems of Splay trees

A) Working Set Theorem - A splay tree is a self-adjusting binary search tree with the additional property that recently accessed elements are quick to access again It performs basic operations such as insertion look-up and removal in O(log n) amortized time For many sequences of operations splay trees perform better than other search trees even when the specific pattern of the sequence is unknown

All normal operations on a binary search tree are combined with one basic operation called splaying Splaying the tree for a certain element rearranges the tree so that the element is placed at the root of the tree One way to do this is to first perform a standard binary tree search for the element in question and then use tree rotations in a specific fashion to bring the element to the top Alternatively a top-down algorithm can combine the search and the tree reorganization into a single phase

When a node x is accessed a splay operation is performed on x to move it to the root To perform a splay operation we carry out a sequence of splay steps each of which moves x closer to the root By performing a splay operation on the node of interest after every access the recently accessed nodes are kept near the root and the tree remains roughly balanced so that we achieve the desired amortized time bounds

B) Sequential Access Theorem - When a node x is accessed a splay operation is

performed on x to move it to the root To perform a splay operation we carry out a

sequence of splay steps each of which moves x closer to the root By performing a splay

operation on the node of interest after every access the recently accessed nodes are kept

near the root and the tree remains roughly balanced so that we achieve the desired

amortized time boundsEach particular step depends on three factors

Whether x is the left or right child of its parent node p

whether p is the root or not and if not

whether p is the left or right child of its parent g (the grandparent of x)

The three types of splay steps are

Zig Step This step is done when p is the root The tree is rotated on the edge between x

and p Zig steps exist to deal with the parity issue and will be done only as the last step in

a splay operation and only when x has odd depth at the beginning of the operation

Zig-zig Step This step is done when p is not the root and x and p are either both right

children or are both left children The picture below shows the case where x and p are both

left children The tree is rotated on the edge joining p with its parent g then rotated on the

17

edge joining x with p Note that zig-zig steps are the only thing that differentiate splay

trees from the rotate to root method introduced by Allen and Munro prior to the

introduction of splay trees

Zig-zag Step This step is done when p is not the root and x is a right child and p is a left

child or vice versa The tree is rotated on the edge between x and p then rotated on the

edge between x and its new parent g

C) Dynamic Finger Theorem - A simple amortized analysis of static splay trees can be carried out using the potential method Suppose that size(r) is the number of nodes in the subtree rooted at r (including r) and rank(r) = log2(size(r)) Then the potential function P(t) for a splay tree t is the sum of the ranks of all the nodes in the tree This will tend to be high for poorly-balanced trees and low for well-balanced trees We can bound the amortized cost of any zig-zig or zig-zag operation by

amortized cost = cost + P(tf) - P(ti) le 3(rankf(x) - ranki(x))

where x is the node being moved towards the root and the subscripts f and i indicate after and before the operation respectively When summed over the entire splay operation this telescopes to 3(rank(root)) which is O(log n) Since theres at most one zig operation this only adds a constant

Dynamic Finger Theorem The cost of performing S is O(m+n log n + sum mi=1 log( |Ij+1 ndash Ij + 1 ))

8 Explain the following in the context of files

A) Sequential Files - True random access file handling however only accesses the file at the point at which the data should be read or written rather than having to process it sequentially A hybrid approach is also possible whereby a part of the file is used for sequential access to locate something in the random access portion of the file in much the same way that a File Allocation Table (FAT) worksThe three main functions that this article will deal with are

rewind() ndash return the file pointer to the beginning fseek() ndash position the file pointer ftell() ndash return the current offset of the file pointer

Each of these functions operates on the C file pointer which is just the offset from the start of the file and can be positioned at will All readwrite operations take place at the current position of the file pointer The rewind() Function The rewind() function can be used in sequential or random access C file programming and simply tells the file system to position the file pointer at the start of the file Any error flags will also be cleared and no value is returned While useful the companion function fseek() can also be used to reposition the file pointer at will including the same behavior as rewind() Using fseek() and ftell() to Process Files

18

The fseek() function is most useful in random access files where either the record (or block) size is known or there is an allocation system that denotes the start and end positions of records in an index portion of the file The fseek() function takes three parameters

FILE f ndash the file pointer long offset ndash the position offset int origin ndash the point from which the offset is applied

B) Inverted Files - The inverted index data structure is a central component of a typical search engine indexing algorithm A goal of a search engine implementation is to optimize the speed of the query find the documents where word X occurs Once a forward index is developed which stores lists of words per document it is next inverted to develop an inverted index Querying the forward index would require sequential iteration through each document and to each word to verify a matching document The time memory and processing resources to perform such a query are not always technically realistic Instead of listing the words per document in the forward index the inverted index data structure is developed which lists the documents per word

With the inverted index created the query can now be resolved by jumping to the word id (via random access) in the inverted index

In pre-computer times concordances to important books were manually assembled These were effectively inverted indexes with a small amount of accompanying commentary that required a tremendous amount of effort to produce

There are two main variants of inverted indexes A record level inverted index (or inverted file index or just inverted file) contains a list of references to documents for each word A word level inverted index (or full inverted index or inverted list) additionally contains the positions of each word within a document The latter form offers more functionality (like phrase searches) but needs more time and space to be created

19

  • Ans- Stack operations-
Page 4: SEM_2_MC0068_ Data Structures Using C

include dqueueh include dlisth include lt stdlibhgt

struct dqueue dlist head dlist tail

dqueue dq_create(void) dqueue q = malloc(sizeof(struct dqueue)) q -gt head = q -gt tail = NULL return q

int dq_empty(dqueue q) return q -gt head == NULL

void dq_enq_front(dqueue q void element) if(dq_empty(q)) q -gt head = q -gt tail = dcons(element NULL NULL) else q -gt head -gt prev = dcons(element NULL q -gt head)

q -gt head -gt prev -gt next = q -gt head

q -gt head = q -gt head -gt prev

void dq_enq_back(dqueue q void element) if(dq_empty(q)) q -gt head = q -gt tail = dcons(element NULL NULL)

else q -gt tail -gt next = dcons(element q -gt tail NULL)

q -gt tail -gt next -gt prev = q -gt tail

q -gt tail = q -gt tail -gt next

void dq_deq_front(dqueue q) assert(empty(q)) dqueue temp = q -gt head void element = temp -gt element q -gt head = q -gt head -gt next free(temp) if(q -gt head == NULL) q -gt tail = NULL else q -gt head -gt prev = NULL return element

void dq_deq_back(dqueue q) assert(empty(q)) dqueue temp = q -gt tail void element = temp -gt element q -gt tail = q -gt tail -gt prev free(temp) if(q -gt tail == NULL) q -gt head = NULL else q -gt tail -gt next = NULL return element

circular queues- A circular queue is a particular implementation of a queue It is very efficient It is also quite useful in low level code because insertion and deletion are totally independant which

4

means that you dont have to worry about an interrupt handler trying to do an insertion at the same time as your main code is doing a deletion

Example-include ltstdiohgtinclude ltstdlibhgt

define MAX 10

void insert(int queue[] int rear int front int value) rear= (rear +1) MAX if(rear == front) printf(The queue is full can not insert a valuen) exit(0) queue[rear] = value

void delete(int queue[] int front int rear int value) if(front == rear) printf(The queue is empty can not delete a valuen) exit(0) front = (front + 1) MAX value = queue[front]

void main() int queue[MAX] int frontrear int nvalue front=0 rear=0

insert(queueamprearfront1) insert(queueamprearfront2) insert(queueamprearfront3) insert(queueamprearfront4) delete(queueampfrontrearampvalue) printf(The value deleted is dnvalue)

delete(queueampfrontrearampvalue) printf(The value deleted is dnvalue)

delete(queueampfrontrearampvalue) printf(The value deleted is dnvalue)

5

6 With the help of a suitable numerical example describe the following

concepts of a Binary Search Tree

A) Analysis of BST - carry out an Analysis of this method to determine its time complexity Since there are no ldquoforrdquo loops we can not use summations to express the total number ofoperations Let us examine the operations for a specific case where the number ofelements in the array n is 64When n= 64 BinarySearch is called to reduce size to n=32When n= 32 BinarySearch is called to reduce size to n=16When n= 16 BinarySearch is called to reduce size to n=8When n= 8 BinarySearch is called to reduce size to n=4When n= 4 BinarySearch is called to reduce size to n=2When n= 2 BinarySearch is called to reduce size to n=1

int BinarySearch (int A[ ] int n int K)int L=0 Mid R= n-1while (Llt=R)Mid = (L +R)2if ( K= =A[Mid] )return Midelse if ( K gt A[Mid] )L = Mid + 1elseR = Mid ndash 1 return ndash1

B) Insertion of Nodes into a BST - To insert a node into a BST

1 find a leaf st the appropriate place and 2 connect the node to the parent of the leaf

TREE-INSERT (T z)

y larr NILx larr root [T]while x ne NIL do y larr x if key [z] lt key[x] then x larr left[x] else x larr right[x]p[z] larr yif y = NIL then root [T] larr z else if key [z] lt key [y]

6

then left [y] larr z else right [y] larr z

Like other primitive operations on search trees this algorithm begins at the root of the tree and traces a path downward Clearly it runs in O(h) time on a tree of height h

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

Ans-include ltstdiohgt

The input file (weighttxt) look something like this

40 0 0 210 0 8 170 8 0 1621 17 16 0

The first line contains n the number of nodesNext is an nxn matrix containg the distances between the nodesNOTE The distance between a node and itself should be 0

int n The number of nodes in the graph

int weight[100][100] weight[i][j] is the distance between node i and node j

if there is no path between i and j weight[i][j] should

be 0

char inTree[100] inTree[i] is 1 if the node i is already in the minimum

spanning tree 0 otherwise

int d[100] d[i] is the distance between node i and the minimum spanning

tree this is initially infinity (100000) if i is already in

the tree then d[i] is undefinedthis is just a temporary variable Its not necessary

but speedsup execution considerably (by a factor of n)

int whoTo[100] whoTo[i] holds the index of the node i would have to be

linked to in order to get a distance of d[i]

updateDistances(int target)

7

should be called immediately after target is added to the tree

updates d so that the values are correct (goes through targets

neighbours making sure that the distances between them and the tree

are indeed minimum)void updateDistances(int target)

int ifor (i = 0 i lt n ++i)

if ((weight[target][i] = 0) ampamp (d[i] gt weight[target][i]))

d[i] = weight[target][i]whoTo[i] = target

int main(int argc char argv[]) FILE f = fopen(disttxt r)fscanf(f d ampn)int i jfor (i = 0 i lt n ++i)

for (j = 0 j lt n ++j)fscanf(f d ampweight[i][j])

fclose(f)

Initialise d with infinity for (i = 0 i lt n ++i)

d[i] = 100000

Mark all nodes as NOT beeing in the minimum spanning tree

for (i = 0 i lt n ++i)inTree[i] = 0

Add the first node to the tree printf(Adding node cn 0 + A)inTree[0] = 1updateDistances(0)

int total = 0int treeSizefor (treeSize = 1 treeSize lt n ++treeSize)

Find the node with the smallest distance to the tree

int min = -1for (i = 0 i lt n ++i)

if (inTree[i])if ((min == -1) || (d[min] gt d[i]))

min = i

8

And add it printf(Adding edge c-cn whoTo[min] + A min +

A)inTree[min] = 1total += d[min]

updateDistances(min)

printf(Total distance dn total)

return 0

8 Explain the following graph problems

A) Telecommunication problem - Subscription con_guration problem and is taken (with slight modi_cation) from [4]Let F denote a _nite set of features For fi fj 2 F a precedence constraint(figtfj) indicates that fi is after fj An exclusion constraint (filtgtfj) between fiand fj indicates that fi and fj cannot appear together in a sequence of featuresand is equivalent to the pair (figtfj ) (fjgtfi) A catalog is a pair hF Pi with F aset of features and P a set of precedence constraints on F A feature subscriptionS of a catalog hFc Pci is a tuple hFCUWF WUi where F _ Fc is the set offeatures selected from Fc C is the projection of Pc on F U is a set of user de_nedprecedence constraints on F and WF F N and WUU N are maps whichassign weights to features and user precedence constraints The value of S isde_ned by V alue(S) = _f2FWF (f) + _p2UWU(p) The weight associated witha feature or a precedence constraint signi_es its importance for the userA feature subscription hFCUWF WUi is consistent i_ the directed graphhFC[Ui is acyclic Checking for consistency is straightforward using topologicalsort as described in [4] If a feature subscription is inconsistent then the task isto relax it and to generate a consistent one with maximum value A relaxationof a feature subscription S = hFCUWF WUi is a consistent subscriptionS0 = hF0C0U0WF0 WU0 i such that F0 _ F C0 is the projection of C on F0U0 is a subset of the projection of U on F0 WF0 is the restriction of WF to F0and WU0 is the restriction of WU to U0 We say that S0 is an optimal relaxationof S if there does not exist another relaxation S00 of S such that V alue(S00) gtV alue(S0) In [4] the authors prove that _nding an optimal relaxation of afeature subscription is NP-hard This is the problem addressed in this paper

B) Knight Moves - A knight is a chess piece that can move either two spaces horizontally and one space vertically or one space horizontally and two spaces vertically That is a knight on square (xy) can move to any of the eight squares (x plusmn 2y plusmn 1) (x plusmn 1y plusmn 2) if these squares exist on the chessboard (which is normally 8 times 8) A knightrsquos tour is a sequence of legal moves by a knight starting at some square and visiting each square exactly once A knightrsquos tour is called reentrant if there is a legal move that takes the knight from the last square of the tour back to where the tour began We can model knightrsquos tours using the graph that has a vertex for each square

9

on the boardwith an edge connecting two vertices if a knight can legally move between the squares represented by these vertices (a) Show that finding a reentrant knightrsquos tour on an m times n chessboard is equivalent to finding a Hamilton circuit on the corresponding graph (b) Show that the graph representing the legal moves of a knight on a mtimesn chessboard wherever m and n are positive integers is bipartite (c) Deduce that there is no reentrant knightrsquos tour on an m times n chessboard when m

and n are both odd

10

August 2010

Master of Computer Application (MCA) ndash Semester 2

MC0068 ndash Data Structures using C

Assignment Set ndash 2

1 Describe the theory of circular singly linked lists

Ans- The linked lisis that we have seen so far are often known as linear linked

lists The elements of such a linked list can be accessed first by setting up a

pointer pointing to the first node in the list and then traversing the entire list using

this pointer Although a linear linked list is a useful data structure it has several

shortcomings For example given a pointer p to a node in a linear list we cannot

reach any of the nodes that precede the node to which p is pointing This

disadvantage can be overcome by making a small change to the structure of a

linear list such that the link field in the last node contains a pointer back to the

first node rather than a NULL Such a list is called a circular linked list

2 Describe following Binary Trees

A) Strictly Binary trees - A binary tree is a finite set of elements that is either

empty or is partitioned into three disjoint subsets The first subset contains a

single element called the root of the tree The other two subsets are themselves

binary trees called the left and rightsubtrees of the original tree A left or right

subtree can be empty Each element of a binary tree is called a node of the tree

and the tree consists of nine nodes with A as its root Its left subtree is rooted at B

and its right subtree is rooted at C This is indicated by the two branches

emanating from A to B on the left and to C on the right The absence of a branch

indicates an empty subtree For example the left subtree of the binary tree rooted

at C and the right subtree of the binary tree rooted at E are both empty The

binary trees rooted at D G H and I have empty right and left subtrees Following

figure illustrates some structures that are not binary trees Be sure that you

understand why each of them is not a binary tree as just defined

B) Complete Binary trees - A binary tree is made of nodes where each node contains a

left pointer a right pointer and a data element The root pointer points to the topmost

node in the tree The left and right pointers recursively point to smaller subtrees on either

side A null pointer represents a binary tree with no elements -- the empty tree The formal

11

recursive definition is a binary tree is either empty (represented by a null pointer) or is made

of a single node where the left and right pointers (recursive definition ahead) each point to a

binary tree

C) Almost Complete Binary Trees - All leafs at lowest and next-tolowest levels onlyAll

except the lowest level is fullNo gaps except at the end of a level A perfectly balanced tree with

leaves at the last level all in the leftmost position A tree which can be represented

without any vacant space in the array representation

3 With the help of a program and an example explain Breadth First Tree

Traversal

Ans- Certain programming problems are easier to solve using multiple data structures

For example testing a sequence of characters to determine if it is a palindrome (ie reads the same forward and backward like radar) can be accomplished easily with one stack and one queue The solution is to enter the sequence of characters into both data structures then remove letters from each data structure one at a time and compare them making sure that the letters match

In this palindrome example the user (person writing the main program) has access to both data structures to solve the problem Another way that 2 data structures can be used in concert is to use one data structure to help implement another

treeh treec------ ------ include treeh include queueh

typedef char treeElementT typedef struct treeNodeTag treeElementT element struct treeNodeTag left right treeNodeT

typedef struct treeCDT typedef struct treeCDT treeADT treeNodeT root treeCDT

4 Write a program to perform a binary search on an unsorted list of n integers

Ans-

Program Example-

includeltstdiohgt

includeltconiohgt

12

includeltmathhgt

int main()

int a[20]= 0

int n i j temp

int beg end mid target

printf( enter the total integers you want to enter (make it less

then 20)n)

scanf(d ampn)

if (n gt= 20) return 0

printf( enter the integer array elementsn )

for(i = 0 i lt n i++)

scanf(d ampa[i])

for(i = 0 i lt n-1 i++)

for(j = 0 j lt n-i-1 j++)

if (a[j+1] lt a[j])

temp = a[j]

a[j] = a[j+1]

a[j+1] = temp

13

printf( the sorted numbers are)

for(i = 0 i lt n i++)

printf(d a[i])

beg = ampa[0]

end = ampa[n]

mid = beg += n2

printf(n enter the number to be searched)

scanf(damptarget)

while((beg lt= end) ampamp (mid = target))

if (target lt mid)

end = mid ndash 1

n = n2

mid = beg += n2

else

beg = mid + 1

n = n2

mid = beg += n2

14

if (mid == target)

printf(n d found target)

else

printf(n d not found target)

getchar()

getchar()

return 0

5 With the help of a numerical example explain the working of Insertion Sort

Ans- When sorting an array with insertion sort we conceptually separate it into two parts

The list of elements already inserted which is always in sorted order and is found at the

beginning of the arrayThe list of elements we have yet to insert following

In outline our primary function looks like thisltltinsertion_sortgtgt=void insertion_sort(int a[] int length) int i for (i=0 i lt length i++) insert a[i] into sorted sublist

To insert each element we need to create a hole in the array at the place where the element

belongs then place the element in that hole We can combine the creation of the hole with the

searching for the place by starting at the end and shifting each element up by one until we find

15

the place where the element belongs This overwrites the element were inserting so we have

to save it in a variable firstltltinsert a[i] into sorted sublistgtgt=int j v = a[i]

for (j = i - 1 j gt= 0 j--) if (a[j] lt= v) break a[j + 1] = a[j]

a[j + 1] = v

6 Describe Depth First search algorithm and analyze its complexity

Ans- Formally DFS is an uninformed search that progresses by expanding the first child node of the search tree that appears and thus going deeper and deeper until a goal node is found or until it hits a node that has no children Then the search backtracks returning to the most recent node it hasnt finished exploring In a non-recursive implementation all freshly expanded nodes are added to a stack for exploration

The time and space analysis of DFS differs according to its application area In theoretical computer science DFS is typically used to traverse an entire graph and takes time O(|V| + |E|) linear in the size of the graph In these applications it also uses space O(|V|) in the worst case to store the stack of vertices on the current search path as well as the set of already-visited vertices Thus in this setting the time and space bounds are the same as for breadth first search and the choice of which of these two algorithms to use depends less on their complexity and more on the different properties of the vertex orderings the two algorithms produce

a depth-first search starting at A assuming that the left edges in the shown graph are chosen before right edges and assuming the search remembers previously-visited nodes and will not repeat them (since this is a small graph) will visit the nodes in the following order A B D F E C G

Performing the same search without remembering previously visited nodes results in visiting nodes in the order A B D F E A B D F E etc forever caught in the A B D F E cycle and never reaching C or G

16

7 Explain the following theorems of Splay trees

A) Working Set Theorem - A splay tree is a self-adjusting binary search tree with the additional property that recently accessed elements are quick to access again It performs basic operations such as insertion look-up and removal in O(log n) amortized time For many sequences of operations splay trees perform better than other search trees even when the specific pattern of the sequence is unknown

All normal operations on a binary search tree are combined with one basic operation called splaying Splaying the tree for a certain element rearranges the tree so that the element is placed at the root of the tree One way to do this is to first perform a standard binary tree search for the element in question and then use tree rotations in a specific fashion to bring the element to the top Alternatively a top-down algorithm can combine the search and the tree reorganization into a single phase

When a node x is accessed a splay operation is performed on x to move it to the root To perform a splay operation we carry out a sequence of splay steps each of which moves x closer to the root By performing a splay operation on the node of interest after every access the recently accessed nodes are kept near the root and the tree remains roughly balanced so that we achieve the desired amortized time bounds

B) Sequential Access Theorem - When a node x is accessed a splay operation is

performed on x to move it to the root To perform a splay operation we carry out a

sequence of splay steps each of which moves x closer to the root By performing a splay

operation on the node of interest after every access the recently accessed nodes are kept

near the root and the tree remains roughly balanced so that we achieve the desired

amortized time boundsEach particular step depends on three factors

Whether x is the left or right child of its parent node p

whether p is the root or not and if not

whether p is the left or right child of its parent g (the grandparent of x)

The three types of splay steps are

Zig Step This step is done when p is the root The tree is rotated on the edge between x

and p Zig steps exist to deal with the parity issue and will be done only as the last step in

a splay operation and only when x has odd depth at the beginning of the operation

Zig-zig Step This step is done when p is not the root and x and p are either both right

children or are both left children The picture below shows the case where x and p are both

left children The tree is rotated on the edge joining p with its parent g then rotated on the

17

edge joining x with p Note that zig-zig steps are the only thing that differentiate splay

trees from the rotate to root method introduced by Allen and Munro prior to the

introduction of splay trees

Zig-zag Step This step is done when p is not the root and x is a right child and p is a left

child or vice versa The tree is rotated on the edge between x and p then rotated on the

edge between x and its new parent g

C) Dynamic Finger Theorem - A simple amortized analysis of static splay trees can be carried out using the potential method Suppose that size(r) is the number of nodes in the subtree rooted at r (including r) and rank(r) = log2(size(r)) Then the potential function P(t) for a splay tree t is the sum of the ranks of all the nodes in the tree This will tend to be high for poorly-balanced trees and low for well-balanced trees We can bound the amortized cost of any zig-zig or zig-zag operation by

amortized cost = cost + P(tf) - P(ti) le 3(rankf(x) - ranki(x))

where x is the node being moved towards the root and the subscripts f and i indicate after and before the operation respectively When summed over the entire splay operation this telescopes to 3(rank(root)) which is O(log n) Since theres at most one zig operation this only adds a constant

Dynamic Finger Theorem The cost of performing S is O(m+n log n + sum mi=1 log( |Ij+1 ndash Ij + 1 ))

8 Explain the following in the context of files

A) Sequential Files - True random access file handling however only accesses the file at the point at which the data should be read or written rather than having to process it sequentially A hybrid approach is also possible whereby a part of the file is used for sequential access to locate something in the random access portion of the file in much the same way that a File Allocation Table (FAT) worksThe three main functions that this article will deal with are

rewind() ndash return the file pointer to the beginning fseek() ndash position the file pointer ftell() ndash return the current offset of the file pointer

Each of these functions operates on the C file pointer which is just the offset from the start of the file and can be positioned at will All readwrite operations take place at the current position of the file pointer The rewind() Function The rewind() function can be used in sequential or random access C file programming and simply tells the file system to position the file pointer at the start of the file Any error flags will also be cleared and no value is returned While useful the companion function fseek() can also be used to reposition the file pointer at will including the same behavior as rewind() Using fseek() and ftell() to Process Files

18

The fseek() function is most useful in random access files where either the record (or block) size is known or there is an allocation system that denotes the start and end positions of records in an index portion of the file The fseek() function takes three parameters

FILE f ndash the file pointer long offset ndash the position offset int origin ndash the point from which the offset is applied

B) Inverted Files - The inverted index data structure is a central component of a typical search engine indexing algorithm A goal of a search engine implementation is to optimize the speed of the query find the documents where word X occurs Once a forward index is developed which stores lists of words per document it is next inverted to develop an inverted index Querying the forward index would require sequential iteration through each document and to each word to verify a matching document The time memory and processing resources to perform such a query are not always technically realistic Instead of listing the words per document in the forward index the inverted index data structure is developed which lists the documents per word

With the inverted index created the query can now be resolved by jumping to the word id (via random access) in the inverted index

In pre-computer times concordances to important books were manually assembled These were effectively inverted indexes with a small amount of accompanying commentary that required a tremendous amount of effort to produce

There are two main variants of inverted indexes A record level inverted index (or inverted file index or just inverted file) contains a list of references to documents for each word A word level inverted index (or full inverted index or inverted list) additionally contains the positions of each word within a document The latter form offers more functionality (like phrase searches) but needs more time and space to be created

19

  • Ans- Stack operations-
Page 5: SEM_2_MC0068_ Data Structures Using C

means that you dont have to worry about an interrupt handler trying to do an insertion at the same time as your main code is doing a deletion

Example-include ltstdiohgtinclude ltstdlibhgt

define MAX 10

void insert(int queue[] int rear int front int value) rear= (rear +1) MAX if(rear == front) printf(The queue is full can not insert a valuen) exit(0) queue[rear] = value

void delete(int queue[] int front int rear int value) if(front == rear) printf(The queue is empty can not delete a valuen) exit(0) front = (front + 1) MAX value = queue[front]

void main() int queue[MAX] int frontrear int nvalue front=0 rear=0

insert(queueamprearfront1) insert(queueamprearfront2) insert(queueamprearfront3) insert(queueamprearfront4) delete(queueampfrontrearampvalue) printf(The value deleted is dnvalue)

delete(queueampfrontrearampvalue) printf(The value deleted is dnvalue)

delete(queueampfrontrearampvalue) printf(The value deleted is dnvalue)

5

6 With the help of a suitable numerical example describe the following

concepts of a Binary Search Tree

A) Analysis of BST - carry out an Analysis of this method to determine its time complexity Since there are no ldquoforrdquo loops we can not use summations to express the total number ofoperations Let us examine the operations for a specific case where the number ofelements in the array n is 64When n= 64 BinarySearch is called to reduce size to n=32When n= 32 BinarySearch is called to reduce size to n=16When n= 16 BinarySearch is called to reduce size to n=8When n= 8 BinarySearch is called to reduce size to n=4When n= 4 BinarySearch is called to reduce size to n=2When n= 2 BinarySearch is called to reduce size to n=1

int BinarySearch (int A[ ] int n int K)int L=0 Mid R= n-1while (Llt=R)Mid = (L +R)2if ( K= =A[Mid] )return Midelse if ( K gt A[Mid] )L = Mid + 1elseR = Mid ndash 1 return ndash1

B) Insertion of Nodes into a BST - To insert a node into a BST

1 find a leaf st the appropriate place and 2 connect the node to the parent of the leaf

TREE-INSERT (T z)

y larr NILx larr root [T]while x ne NIL do y larr x if key [z] lt key[x] then x larr left[x] else x larr right[x]p[z] larr yif y = NIL then root [T] larr z else if key [z] lt key [y]

6

then left [y] larr z else right [y] larr z

Like other primitive operations on search trees this algorithm begins at the root of the tree and traces a path downward Clearly it runs in O(h) time on a tree of height h

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

Ans-include ltstdiohgt

The input file (weighttxt) look something like this

40 0 0 210 0 8 170 8 0 1621 17 16 0

The first line contains n the number of nodesNext is an nxn matrix containg the distances between the nodesNOTE The distance between a node and itself should be 0

int n The number of nodes in the graph

int weight[100][100] weight[i][j] is the distance between node i and node j

if there is no path between i and j weight[i][j] should

be 0

char inTree[100] inTree[i] is 1 if the node i is already in the minimum

spanning tree 0 otherwise

int d[100] d[i] is the distance between node i and the minimum spanning

tree this is initially infinity (100000) if i is already in

the tree then d[i] is undefinedthis is just a temporary variable Its not necessary

but speedsup execution considerably (by a factor of n)

int whoTo[100] whoTo[i] holds the index of the node i would have to be

linked to in order to get a distance of d[i]

updateDistances(int target)

7

should be called immediately after target is added to the tree

updates d so that the values are correct (goes through targets

neighbours making sure that the distances between them and the tree

are indeed minimum)void updateDistances(int target)

int ifor (i = 0 i lt n ++i)

if ((weight[target][i] = 0) ampamp (d[i] gt weight[target][i]))

d[i] = weight[target][i]whoTo[i] = target

int main(int argc char argv[]) FILE f = fopen(disttxt r)fscanf(f d ampn)int i jfor (i = 0 i lt n ++i)

for (j = 0 j lt n ++j)fscanf(f d ampweight[i][j])

fclose(f)

Initialise d with infinity for (i = 0 i lt n ++i)

d[i] = 100000

Mark all nodes as NOT beeing in the minimum spanning tree

for (i = 0 i lt n ++i)inTree[i] = 0

Add the first node to the tree printf(Adding node cn 0 + A)inTree[0] = 1updateDistances(0)

int total = 0int treeSizefor (treeSize = 1 treeSize lt n ++treeSize)

Find the node with the smallest distance to the tree

int min = -1for (i = 0 i lt n ++i)

if (inTree[i])if ((min == -1) || (d[min] gt d[i]))

min = i

8

And add it printf(Adding edge c-cn whoTo[min] + A min +

A)inTree[min] = 1total += d[min]

updateDistances(min)

printf(Total distance dn total)

return 0

8 Explain the following graph problems

A) Telecommunication problem - Subscription con_guration problem and is taken (with slight modi_cation) from [4]Let F denote a _nite set of features For fi fj 2 F a precedence constraint(figtfj) indicates that fi is after fj An exclusion constraint (filtgtfj) between fiand fj indicates that fi and fj cannot appear together in a sequence of featuresand is equivalent to the pair (figtfj ) (fjgtfi) A catalog is a pair hF Pi with F aset of features and P a set of precedence constraints on F A feature subscriptionS of a catalog hFc Pci is a tuple hFCUWF WUi where F _ Fc is the set offeatures selected from Fc C is the projection of Pc on F U is a set of user de_nedprecedence constraints on F and WF F N and WUU N are maps whichassign weights to features and user precedence constraints The value of S isde_ned by V alue(S) = _f2FWF (f) + _p2UWU(p) The weight associated witha feature or a precedence constraint signi_es its importance for the userA feature subscription hFCUWF WUi is consistent i_ the directed graphhFC[Ui is acyclic Checking for consistency is straightforward using topologicalsort as described in [4] If a feature subscription is inconsistent then the task isto relax it and to generate a consistent one with maximum value A relaxationof a feature subscription S = hFCUWF WUi is a consistent subscriptionS0 = hF0C0U0WF0 WU0 i such that F0 _ F C0 is the projection of C on F0U0 is a subset of the projection of U on F0 WF0 is the restriction of WF to F0and WU0 is the restriction of WU to U0 We say that S0 is an optimal relaxationof S if there does not exist another relaxation S00 of S such that V alue(S00) gtV alue(S0) In [4] the authors prove that _nding an optimal relaxation of afeature subscription is NP-hard This is the problem addressed in this paper

B) Knight Moves - A knight is a chess piece that can move either two spaces horizontally and one space vertically or one space horizontally and two spaces vertically That is a knight on square (xy) can move to any of the eight squares (x plusmn 2y plusmn 1) (x plusmn 1y plusmn 2) if these squares exist on the chessboard (which is normally 8 times 8) A knightrsquos tour is a sequence of legal moves by a knight starting at some square and visiting each square exactly once A knightrsquos tour is called reentrant if there is a legal move that takes the knight from the last square of the tour back to where the tour began We can model knightrsquos tours using the graph that has a vertex for each square

9

on the boardwith an edge connecting two vertices if a knight can legally move between the squares represented by these vertices (a) Show that finding a reentrant knightrsquos tour on an m times n chessboard is equivalent to finding a Hamilton circuit on the corresponding graph (b) Show that the graph representing the legal moves of a knight on a mtimesn chessboard wherever m and n are positive integers is bipartite (c) Deduce that there is no reentrant knightrsquos tour on an m times n chessboard when m

and n are both odd

10

August 2010

Master of Computer Application (MCA) ndash Semester 2

MC0068 ndash Data Structures using C

Assignment Set ndash 2

1 Describe the theory of circular singly linked lists

Ans- The linked lisis that we have seen so far are often known as linear linked

lists The elements of such a linked list can be accessed first by setting up a

pointer pointing to the first node in the list and then traversing the entire list using

this pointer Although a linear linked list is a useful data structure it has several

shortcomings For example given a pointer p to a node in a linear list we cannot

reach any of the nodes that precede the node to which p is pointing This

disadvantage can be overcome by making a small change to the structure of a

linear list such that the link field in the last node contains a pointer back to the

first node rather than a NULL Such a list is called a circular linked list

2 Describe following Binary Trees

A) Strictly Binary trees - A binary tree is a finite set of elements that is either

empty or is partitioned into three disjoint subsets The first subset contains a

single element called the root of the tree The other two subsets are themselves

binary trees called the left and rightsubtrees of the original tree A left or right

subtree can be empty Each element of a binary tree is called a node of the tree

and the tree consists of nine nodes with A as its root Its left subtree is rooted at B

and its right subtree is rooted at C This is indicated by the two branches

emanating from A to B on the left and to C on the right The absence of a branch

indicates an empty subtree For example the left subtree of the binary tree rooted

at C and the right subtree of the binary tree rooted at E are both empty The

binary trees rooted at D G H and I have empty right and left subtrees Following

figure illustrates some structures that are not binary trees Be sure that you

understand why each of them is not a binary tree as just defined

B) Complete Binary trees - A binary tree is made of nodes where each node contains a

left pointer a right pointer and a data element The root pointer points to the topmost

node in the tree The left and right pointers recursively point to smaller subtrees on either

side A null pointer represents a binary tree with no elements -- the empty tree The formal

11

recursive definition is a binary tree is either empty (represented by a null pointer) or is made

of a single node where the left and right pointers (recursive definition ahead) each point to a

binary tree

C) Almost Complete Binary Trees - All leafs at lowest and next-tolowest levels onlyAll

except the lowest level is fullNo gaps except at the end of a level A perfectly balanced tree with

leaves at the last level all in the leftmost position A tree which can be represented

without any vacant space in the array representation

3 With the help of a program and an example explain Breadth First Tree

Traversal

Ans- Certain programming problems are easier to solve using multiple data structures

For example testing a sequence of characters to determine if it is a palindrome (ie reads the same forward and backward like radar) can be accomplished easily with one stack and one queue The solution is to enter the sequence of characters into both data structures then remove letters from each data structure one at a time and compare them making sure that the letters match

In this palindrome example the user (person writing the main program) has access to both data structures to solve the problem Another way that 2 data structures can be used in concert is to use one data structure to help implement another

treeh treec------ ------ include treeh include queueh

typedef char treeElementT typedef struct treeNodeTag treeElementT element struct treeNodeTag left right treeNodeT

typedef struct treeCDT typedef struct treeCDT treeADT treeNodeT root treeCDT

4 Write a program to perform a binary search on an unsorted list of n integers

Ans-

Program Example-

includeltstdiohgt

includeltconiohgt

12

includeltmathhgt

int main()

int a[20]= 0

int n i j temp

int beg end mid target

printf( enter the total integers you want to enter (make it less

then 20)n)

scanf(d ampn)

if (n gt= 20) return 0

printf( enter the integer array elementsn )

for(i = 0 i lt n i++)

scanf(d ampa[i])

for(i = 0 i lt n-1 i++)

for(j = 0 j lt n-i-1 j++)

if (a[j+1] lt a[j])

temp = a[j]

a[j] = a[j+1]

a[j+1] = temp

13

printf( the sorted numbers are)

for(i = 0 i lt n i++)

printf(d a[i])

beg = ampa[0]

end = ampa[n]

mid = beg += n2

printf(n enter the number to be searched)

scanf(damptarget)

while((beg lt= end) ampamp (mid = target))

if (target lt mid)

end = mid ndash 1

n = n2

mid = beg += n2

else

beg = mid + 1

n = n2

mid = beg += n2

14

if (mid == target)

printf(n d found target)

else

printf(n d not found target)

getchar()

getchar()

return 0

5 With the help of a numerical example explain the working of Insertion Sort

Ans- When sorting an array with insertion sort we conceptually separate it into two parts

The list of elements already inserted which is always in sorted order and is found at the

beginning of the arrayThe list of elements we have yet to insert following

In outline our primary function looks like thisltltinsertion_sortgtgt=void insertion_sort(int a[] int length) int i for (i=0 i lt length i++) insert a[i] into sorted sublist

To insert each element we need to create a hole in the array at the place where the element

belongs then place the element in that hole We can combine the creation of the hole with the

searching for the place by starting at the end and shifting each element up by one until we find

15

the place where the element belongs This overwrites the element were inserting so we have

to save it in a variable firstltltinsert a[i] into sorted sublistgtgt=int j v = a[i]

for (j = i - 1 j gt= 0 j--) if (a[j] lt= v) break a[j + 1] = a[j]

a[j + 1] = v

6 Describe Depth First search algorithm and analyze its complexity

Ans- Formally DFS is an uninformed search that progresses by expanding the first child node of the search tree that appears and thus going deeper and deeper until a goal node is found or until it hits a node that has no children Then the search backtracks returning to the most recent node it hasnt finished exploring In a non-recursive implementation all freshly expanded nodes are added to a stack for exploration

The time and space analysis of DFS differs according to its application area In theoretical computer science DFS is typically used to traverse an entire graph and takes time O(|V| + |E|) linear in the size of the graph In these applications it also uses space O(|V|) in the worst case to store the stack of vertices on the current search path as well as the set of already-visited vertices Thus in this setting the time and space bounds are the same as for breadth first search and the choice of which of these two algorithms to use depends less on their complexity and more on the different properties of the vertex orderings the two algorithms produce

a depth-first search starting at A assuming that the left edges in the shown graph are chosen before right edges and assuming the search remembers previously-visited nodes and will not repeat them (since this is a small graph) will visit the nodes in the following order A B D F E C G

Performing the same search without remembering previously visited nodes results in visiting nodes in the order A B D F E A B D F E etc forever caught in the A B D F E cycle and never reaching C or G

16

7 Explain the following theorems of Splay trees

A) Working Set Theorem - A splay tree is a self-adjusting binary search tree with the additional property that recently accessed elements are quick to access again It performs basic operations such as insertion look-up and removal in O(log n) amortized time For many sequences of operations splay trees perform better than other search trees even when the specific pattern of the sequence is unknown

All normal operations on a binary search tree are combined with one basic operation called splaying Splaying the tree for a certain element rearranges the tree so that the element is placed at the root of the tree One way to do this is to first perform a standard binary tree search for the element in question and then use tree rotations in a specific fashion to bring the element to the top Alternatively a top-down algorithm can combine the search and the tree reorganization into a single phase

When a node x is accessed a splay operation is performed on x to move it to the root To perform a splay operation we carry out a sequence of splay steps each of which moves x closer to the root By performing a splay operation on the node of interest after every access the recently accessed nodes are kept near the root and the tree remains roughly balanced so that we achieve the desired amortized time bounds

B) Sequential Access Theorem - When a node x is accessed a splay operation is

performed on x to move it to the root To perform a splay operation we carry out a

sequence of splay steps each of which moves x closer to the root By performing a splay

operation on the node of interest after every access the recently accessed nodes are kept

near the root and the tree remains roughly balanced so that we achieve the desired

amortized time boundsEach particular step depends on three factors

Whether x is the left or right child of its parent node p

whether p is the root or not and if not

whether p is the left or right child of its parent g (the grandparent of x)

The three types of splay steps are

Zig Step This step is done when p is the root The tree is rotated on the edge between x

and p Zig steps exist to deal with the parity issue and will be done only as the last step in

a splay operation and only when x has odd depth at the beginning of the operation

Zig-zig Step This step is done when p is not the root and x and p are either both right

children or are both left children The picture below shows the case where x and p are both

left children The tree is rotated on the edge joining p with its parent g then rotated on the

17

edge joining x with p Note that zig-zig steps are the only thing that differentiate splay

trees from the rotate to root method introduced by Allen and Munro prior to the

introduction of splay trees

Zig-zag Step This step is done when p is not the root and x is a right child and p is a left

child or vice versa The tree is rotated on the edge between x and p then rotated on the

edge between x and its new parent g

C) Dynamic Finger Theorem - A simple amortized analysis of static splay trees can be carried out using the potential method Suppose that size(r) is the number of nodes in the subtree rooted at r (including r) and rank(r) = log2(size(r)) Then the potential function P(t) for a splay tree t is the sum of the ranks of all the nodes in the tree This will tend to be high for poorly-balanced trees and low for well-balanced trees We can bound the amortized cost of any zig-zig or zig-zag operation by

amortized cost = cost + P(tf) - P(ti) le 3(rankf(x) - ranki(x))

where x is the node being moved towards the root and the subscripts f and i indicate after and before the operation respectively When summed over the entire splay operation this telescopes to 3(rank(root)) which is O(log n) Since theres at most one zig operation this only adds a constant

Dynamic Finger Theorem The cost of performing S is O(m+n log n + sum mi=1 log( |Ij+1 ndash Ij + 1 ))

8 Explain the following in the context of files

A) Sequential Files - True random access file handling however only accesses the file at the point at which the data should be read or written rather than having to process it sequentially A hybrid approach is also possible whereby a part of the file is used for sequential access to locate something in the random access portion of the file in much the same way that a File Allocation Table (FAT) worksThe three main functions that this article will deal with are

rewind() ndash return the file pointer to the beginning fseek() ndash position the file pointer ftell() ndash return the current offset of the file pointer

Each of these functions operates on the C file pointer which is just the offset from the start of the file and can be positioned at will All readwrite operations take place at the current position of the file pointer The rewind() Function The rewind() function can be used in sequential or random access C file programming and simply tells the file system to position the file pointer at the start of the file Any error flags will also be cleared and no value is returned While useful the companion function fseek() can also be used to reposition the file pointer at will including the same behavior as rewind() Using fseek() and ftell() to Process Files

18

The fseek() function is most useful in random access files where either the record (or block) size is known or there is an allocation system that denotes the start and end positions of records in an index portion of the file The fseek() function takes three parameters

FILE f ndash the file pointer long offset ndash the position offset int origin ndash the point from which the offset is applied

B) Inverted Files - The inverted index data structure is a central component of a typical search engine indexing algorithm A goal of a search engine implementation is to optimize the speed of the query find the documents where word X occurs Once a forward index is developed which stores lists of words per document it is next inverted to develop an inverted index Querying the forward index would require sequential iteration through each document and to each word to verify a matching document The time memory and processing resources to perform such a query are not always technically realistic Instead of listing the words per document in the forward index the inverted index data structure is developed which lists the documents per word

With the inverted index created the query can now be resolved by jumping to the word id (via random access) in the inverted index

In pre-computer times concordances to important books were manually assembled These were effectively inverted indexes with a small amount of accompanying commentary that required a tremendous amount of effort to produce

There are two main variants of inverted indexes A record level inverted index (or inverted file index or just inverted file) contains a list of references to documents for each word A word level inverted index (or full inverted index or inverted list) additionally contains the positions of each word within a document The latter form offers more functionality (like phrase searches) but needs more time and space to be created

19

  • Ans- Stack operations-
Page 6: SEM_2_MC0068_ Data Structures Using C

6 With the help of a suitable numerical example describe the following

concepts of a Binary Search Tree

A) Analysis of BST - carry out an Analysis of this method to determine its time complexity Since there are no ldquoforrdquo loops we can not use summations to express the total number ofoperations Let us examine the operations for a specific case where the number ofelements in the array n is 64When n= 64 BinarySearch is called to reduce size to n=32When n= 32 BinarySearch is called to reduce size to n=16When n= 16 BinarySearch is called to reduce size to n=8When n= 8 BinarySearch is called to reduce size to n=4When n= 4 BinarySearch is called to reduce size to n=2When n= 2 BinarySearch is called to reduce size to n=1

int BinarySearch (int A[ ] int n int K)int L=0 Mid R= n-1while (Llt=R)Mid = (L +R)2if ( K= =A[Mid] )return Midelse if ( K gt A[Mid] )L = Mid + 1elseR = Mid ndash 1 return ndash1

B) Insertion of Nodes into a BST - To insert a node into a BST

1 find a leaf st the appropriate place and 2 connect the node to the parent of the leaf

TREE-INSERT (T z)

y larr NILx larr root [T]while x ne NIL do y larr x if key [z] lt key[x] then x larr left[x] else x larr right[x]p[z] larr yif y = NIL then root [T] larr z else if key [z] lt key [y]

6

then left [y] larr z else right [y] larr z

Like other primitive operations on search trees this algorithm begins at the root of the tree and traces a path downward Clearly it runs in O(h) time on a tree of height h

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

Ans-include ltstdiohgt

The input file (weighttxt) look something like this

40 0 0 210 0 8 170 8 0 1621 17 16 0

The first line contains n the number of nodesNext is an nxn matrix containg the distances between the nodesNOTE The distance between a node and itself should be 0

int n The number of nodes in the graph

int weight[100][100] weight[i][j] is the distance between node i and node j

if there is no path between i and j weight[i][j] should

be 0

char inTree[100] inTree[i] is 1 if the node i is already in the minimum

spanning tree 0 otherwise

int d[100] d[i] is the distance between node i and the minimum spanning

tree this is initially infinity (100000) if i is already in

the tree then d[i] is undefinedthis is just a temporary variable Its not necessary

but speedsup execution considerably (by a factor of n)

int whoTo[100] whoTo[i] holds the index of the node i would have to be

linked to in order to get a distance of d[i]

updateDistances(int target)

7

should be called immediately after target is added to the tree

updates d so that the values are correct (goes through targets

neighbours making sure that the distances between them and the tree

are indeed minimum)void updateDistances(int target)

int ifor (i = 0 i lt n ++i)

if ((weight[target][i] = 0) ampamp (d[i] gt weight[target][i]))

d[i] = weight[target][i]whoTo[i] = target

int main(int argc char argv[]) FILE f = fopen(disttxt r)fscanf(f d ampn)int i jfor (i = 0 i lt n ++i)

for (j = 0 j lt n ++j)fscanf(f d ampweight[i][j])

fclose(f)

Initialise d with infinity for (i = 0 i lt n ++i)

d[i] = 100000

Mark all nodes as NOT beeing in the minimum spanning tree

for (i = 0 i lt n ++i)inTree[i] = 0

Add the first node to the tree printf(Adding node cn 0 + A)inTree[0] = 1updateDistances(0)

int total = 0int treeSizefor (treeSize = 1 treeSize lt n ++treeSize)

Find the node with the smallest distance to the tree

int min = -1for (i = 0 i lt n ++i)

if (inTree[i])if ((min == -1) || (d[min] gt d[i]))

min = i

8

And add it printf(Adding edge c-cn whoTo[min] + A min +

A)inTree[min] = 1total += d[min]

updateDistances(min)

printf(Total distance dn total)

return 0

8 Explain the following graph problems

A) Telecommunication problem - Subscription con_guration problem and is taken (with slight modi_cation) from [4]Let F denote a _nite set of features For fi fj 2 F a precedence constraint(figtfj) indicates that fi is after fj An exclusion constraint (filtgtfj) between fiand fj indicates that fi and fj cannot appear together in a sequence of featuresand is equivalent to the pair (figtfj ) (fjgtfi) A catalog is a pair hF Pi with F aset of features and P a set of precedence constraints on F A feature subscriptionS of a catalog hFc Pci is a tuple hFCUWF WUi where F _ Fc is the set offeatures selected from Fc C is the projection of Pc on F U is a set of user de_nedprecedence constraints on F and WF F N and WUU N are maps whichassign weights to features and user precedence constraints The value of S isde_ned by V alue(S) = _f2FWF (f) + _p2UWU(p) The weight associated witha feature or a precedence constraint signi_es its importance for the userA feature subscription hFCUWF WUi is consistent i_ the directed graphhFC[Ui is acyclic Checking for consistency is straightforward using topologicalsort as described in [4] If a feature subscription is inconsistent then the task isto relax it and to generate a consistent one with maximum value A relaxationof a feature subscription S = hFCUWF WUi is a consistent subscriptionS0 = hF0C0U0WF0 WU0 i such that F0 _ F C0 is the projection of C on F0U0 is a subset of the projection of U on F0 WF0 is the restriction of WF to F0and WU0 is the restriction of WU to U0 We say that S0 is an optimal relaxationof S if there does not exist another relaxation S00 of S such that V alue(S00) gtV alue(S0) In [4] the authors prove that _nding an optimal relaxation of afeature subscription is NP-hard This is the problem addressed in this paper

B) Knight Moves - A knight is a chess piece that can move either two spaces horizontally and one space vertically or one space horizontally and two spaces vertically That is a knight on square (xy) can move to any of the eight squares (x plusmn 2y plusmn 1) (x plusmn 1y plusmn 2) if these squares exist on the chessboard (which is normally 8 times 8) A knightrsquos tour is a sequence of legal moves by a knight starting at some square and visiting each square exactly once A knightrsquos tour is called reentrant if there is a legal move that takes the knight from the last square of the tour back to where the tour began We can model knightrsquos tours using the graph that has a vertex for each square

9

on the boardwith an edge connecting two vertices if a knight can legally move between the squares represented by these vertices (a) Show that finding a reentrant knightrsquos tour on an m times n chessboard is equivalent to finding a Hamilton circuit on the corresponding graph (b) Show that the graph representing the legal moves of a knight on a mtimesn chessboard wherever m and n are positive integers is bipartite (c) Deduce that there is no reentrant knightrsquos tour on an m times n chessboard when m

and n are both odd

10

August 2010

Master of Computer Application (MCA) ndash Semester 2

MC0068 ndash Data Structures using C

Assignment Set ndash 2

1 Describe the theory of circular singly linked lists

Ans- The linked lisis that we have seen so far are often known as linear linked

lists The elements of such a linked list can be accessed first by setting up a

pointer pointing to the first node in the list and then traversing the entire list using

this pointer Although a linear linked list is a useful data structure it has several

shortcomings For example given a pointer p to a node in a linear list we cannot

reach any of the nodes that precede the node to which p is pointing This

disadvantage can be overcome by making a small change to the structure of a

linear list such that the link field in the last node contains a pointer back to the

first node rather than a NULL Such a list is called a circular linked list

2 Describe following Binary Trees

A) Strictly Binary trees - A binary tree is a finite set of elements that is either

empty or is partitioned into three disjoint subsets The first subset contains a

single element called the root of the tree The other two subsets are themselves

binary trees called the left and rightsubtrees of the original tree A left or right

subtree can be empty Each element of a binary tree is called a node of the tree

and the tree consists of nine nodes with A as its root Its left subtree is rooted at B

and its right subtree is rooted at C This is indicated by the two branches

emanating from A to B on the left and to C on the right The absence of a branch

indicates an empty subtree For example the left subtree of the binary tree rooted

at C and the right subtree of the binary tree rooted at E are both empty The

binary trees rooted at D G H and I have empty right and left subtrees Following

figure illustrates some structures that are not binary trees Be sure that you

understand why each of them is not a binary tree as just defined

B) Complete Binary trees - A binary tree is made of nodes where each node contains a

left pointer a right pointer and a data element The root pointer points to the topmost

node in the tree The left and right pointers recursively point to smaller subtrees on either

side A null pointer represents a binary tree with no elements -- the empty tree The formal

11

recursive definition is a binary tree is either empty (represented by a null pointer) or is made

of a single node where the left and right pointers (recursive definition ahead) each point to a

binary tree

C) Almost Complete Binary Trees - All leafs at lowest and next-tolowest levels onlyAll

except the lowest level is fullNo gaps except at the end of a level A perfectly balanced tree with

leaves at the last level all in the leftmost position A tree which can be represented

without any vacant space in the array representation

3 With the help of a program and an example explain Breadth First Tree

Traversal

Ans- Certain programming problems are easier to solve using multiple data structures

For example testing a sequence of characters to determine if it is a palindrome (ie reads the same forward and backward like radar) can be accomplished easily with one stack and one queue The solution is to enter the sequence of characters into both data structures then remove letters from each data structure one at a time and compare them making sure that the letters match

In this palindrome example the user (person writing the main program) has access to both data structures to solve the problem Another way that 2 data structures can be used in concert is to use one data structure to help implement another

treeh treec------ ------ include treeh include queueh

typedef char treeElementT typedef struct treeNodeTag treeElementT element struct treeNodeTag left right treeNodeT

typedef struct treeCDT typedef struct treeCDT treeADT treeNodeT root treeCDT

4 Write a program to perform a binary search on an unsorted list of n integers

Ans-

Program Example-

includeltstdiohgt

includeltconiohgt

12

includeltmathhgt

int main()

int a[20]= 0

int n i j temp

int beg end mid target

printf( enter the total integers you want to enter (make it less

then 20)n)

scanf(d ampn)

if (n gt= 20) return 0

printf( enter the integer array elementsn )

for(i = 0 i lt n i++)

scanf(d ampa[i])

for(i = 0 i lt n-1 i++)

for(j = 0 j lt n-i-1 j++)

if (a[j+1] lt a[j])

temp = a[j]

a[j] = a[j+1]

a[j+1] = temp

13

printf( the sorted numbers are)

for(i = 0 i lt n i++)

printf(d a[i])

beg = ampa[0]

end = ampa[n]

mid = beg += n2

printf(n enter the number to be searched)

scanf(damptarget)

while((beg lt= end) ampamp (mid = target))

if (target lt mid)

end = mid ndash 1

n = n2

mid = beg += n2

else

beg = mid + 1

n = n2

mid = beg += n2

14

if (mid == target)

printf(n d found target)

else

printf(n d not found target)

getchar()

getchar()

return 0

5 With the help of a numerical example explain the working of Insertion Sort

Ans- When sorting an array with insertion sort we conceptually separate it into two parts

The list of elements already inserted which is always in sorted order and is found at the

beginning of the arrayThe list of elements we have yet to insert following

In outline our primary function looks like thisltltinsertion_sortgtgt=void insertion_sort(int a[] int length) int i for (i=0 i lt length i++) insert a[i] into sorted sublist

To insert each element we need to create a hole in the array at the place where the element

belongs then place the element in that hole We can combine the creation of the hole with the

searching for the place by starting at the end and shifting each element up by one until we find

15

the place where the element belongs This overwrites the element were inserting so we have

to save it in a variable firstltltinsert a[i] into sorted sublistgtgt=int j v = a[i]

for (j = i - 1 j gt= 0 j--) if (a[j] lt= v) break a[j + 1] = a[j]

a[j + 1] = v

6 Describe Depth First search algorithm and analyze its complexity

Ans- Formally DFS is an uninformed search that progresses by expanding the first child node of the search tree that appears and thus going deeper and deeper until a goal node is found or until it hits a node that has no children Then the search backtracks returning to the most recent node it hasnt finished exploring In a non-recursive implementation all freshly expanded nodes are added to a stack for exploration

The time and space analysis of DFS differs according to its application area In theoretical computer science DFS is typically used to traverse an entire graph and takes time O(|V| + |E|) linear in the size of the graph In these applications it also uses space O(|V|) in the worst case to store the stack of vertices on the current search path as well as the set of already-visited vertices Thus in this setting the time and space bounds are the same as for breadth first search and the choice of which of these two algorithms to use depends less on their complexity and more on the different properties of the vertex orderings the two algorithms produce

a depth-first search starting at A assuming that the left edges in the shown graph are chosen before right edges and assuming the search remembers previously-visited nodes and will not repeat them (since this is a small graph) will visit the nodes in the following order A B D F E C G

Performing the same search without remembering previously visited nodes results in visiting nodes in the order A B D F E A B D F E etc forever caught in the A B D F E cycle and never reaching C or G

16

7 Explain the following theorems of Splay trees

A) Working Set Theorem - A splay tree is a self-adjusting binary search tree with the additional property that recently accessed elements are quick to access again It performs basic operations such as insertion look-up and removal in O(log n) amortized time For many sequences of operations splay trees perform better than other search trees even when the specific pattern of the sequence is unknown

All normal operations on a binary search tree are combined with one basic operation called splaying Splaying the tree for a certain element rearranges the tree so that the element is placed at the root of the tree One way to do this is to first perform a standard binary tree search for the element in question and then use tree rotations in a specific fashion to bring the element to the top Alternatively a top-down algorithm can combine the search and the tree reorganization into a single phase

When a node x is accessed a splay operation is performed on x to move it to the root To perform a splay operation we carry out a sequence of splay steps each of which moves x closer to the root By performing a splay operation on the node of interest after every access the recently accessed nodes are kept near the root and the tree remains roughly balanced so that we achieve the desired amortized time bounds

B) Sequential Access Theorem - When a node x is accessed a splay operation is

performed on x to move it to the root To perform a splay operation we carry out a

sequence of splay steps each of which moves x closer to the root By performing a splay

operation on the node of interest after every access the recently accessed nodes are kept

near the root and the tree remains roughly balanced so that we achieve the desired

amortized time boundsEach particular step depends on three factors

Whether x is the left or right child of its parent node p

whether p is the root or not and if not

whether p is the left or right child of its parent g (the grandparent of x)

The three types of splay steps are

Zig Step This step is done when p is the root The tree is rotated on the edge between x

and p Zig steps exist to deal with the parity issue and will be done only as the last step in

a splay operation and only when x has odd depth at the beginning of the operation

Zig-zig Step This step is done when p is not the root and x and p are either both right

children or are both left children The picture below shows the case where x and p are both

left children The tree is rotated on the edge joining p with its parent g then rotated on the

17

edge joining x with p Note that zig-zig steps are the only thing that differentiate splay

trees from the rotate to root method introduced by Allen and Munro prior to the

introduction of splay trees

Zig-zag Step This step is done when p is not the root and x is a right child and p is a left

child or vice versa The tree is rotated on the edge between x and p then rotated on the

edge between x and its new parent g

C) Dynamic Finger Theorem - A simple amortized analysis of static splay trees can be carried out using the potential method Suppose that size(r) is the number of nodes in the subtree rooted at r (including r) and rank(r) = log2(size(r)) Then the potential function P(t) for a splay tree t is the sum of the ranks of all the nodes in the tree This will tend to be high for poorly-balanced trees and low for well-balanced trees We can bound the amortized cost of any zig-zig or zig-zag operation by

amortized cost = cost + P(tf) - P(ti) le 3(rankf(x) - ranki(x))

where x is the node being moved towards the root and the subscripts f and i indicate after and before the operation respectively When summed over the entire splay operation this telescopes to 3(rank(root)) which is O(log n) Since theres at most one zig operation this only adds a constant

Dynamic Finger Theorem The cost of performing S is O(m+n log n + sum mi=1 log( |Ij+1 ndash Ij + 1 ))

8 Explain the following in the context of files

A) Sequential Files - True random access file handling however only accesses the file at the point at which the data should be read or written rather than having to process it sequentially A hybrid approach is also possible whereby a part of the file is used for sequential access to locate something in the random access portion of the file in much the same way that a File Allocation Table (FAT) worksThe three main functions that this article will deal with are

rewind() ndash return the file pointer to the beginning fseek() ndash position the file pointer ftell() ndash return the current offset of the file pointer

Each of these functions operates on the C file pointer which is just the offset from the start of the file and can be positioned at will All readwrite operations take place at the current position of the file pointer The rewind() Function The rewind() function can be used in sequential or random access C file programming and simply tells the file system to position the file pointer at the start of the file Any error flags will also be cleared and no value is returned While useful the companion function fseek() can also be used to reposition the file pointer at will including the same behavior as rewind() Using fseek() and ftell() to Process Files

18

The fseek() function is most useful in random access files where either the record (or block) size is known or there is an allocation system that denotes the start and end positions of records in an index portion of the file The fseek() function takes three parameters

FILE f ndash the file pointer long offset ndash the position offset int origin ndash the point from which the offset is applied

B) Inverted Files - The inverted index data structure is a central component of a typical search engine indexing algorithm A goal of a search engine implementation is to optimize the speed of the query find the documents where word X occurs Once a forward index is developed which stores lists of words per document it is next inverted to develop an inverted index Querying the forward index would require sequential iteration through each document and to each word to verify a matching document The time memory and processing resources to perform such a query are not always technically realistic Instead of listing the words per document in the forward index the inverted index data structure is developed which lists the documents per word

With the inverted index created the query can now be resolved by jumping to the word id (via random access) in the inverted index

In pre-computer times concordances to important books were manually assembled These were effectively inverted indexes with a small amount of accompanying commentary that required a tremendous amount of effort to produce

There are two main variants of inverted indexes A record level inverted index (or inverted file index or just inverted file) contains a list of references to documents for each word A word level inverted index (or full inverted index or inverted list) additionally contains the positions of each word within a document The latter form offers more functionality (like phrase searches) but needs more time and space to be created

19

  • Ans- Stack operations-
Page 7: SEM_2_MC0068_ Data Structures Using C

then left [y] larr z else right [y] larr z

Like other primitive operations on search trees this algorithm begins at the root of the tree and traces a path downward Clearly it runs in O(h) time on a tree of height h

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

Ans-include ltstdiohgt

The input file (weighttxt) look something like this

40 0 0 210 0 8 170 8 0 1621 17 16 0

The first line contains n the number of nodesNext is an nxn matrix containg the distances between the nodesNOTE The distance between a node and itself should be 0

int n The number of nodes in the graph

int weight[100][100] weight[i][j] is the distance between node i and node j

if there is no path between i and j weight[i][j] should

be 0

char inTree[100] inTree[i] is 1 if the node i is already in the minimum

spanning tree 0 otherwise

int d[100] d[i] is the distance between node i and the minimum spanning

tree this is initially infinity (100000) if i is already in

the tree then d[i] is undefinedthis is just a temporary variable Its not necessary

but speedsup execution considerably (by a factor of n)

int whoTo[100] whoTo[i] holds the index of the node i would have to be

linked to in order to get a distance of d[i]

updateDistances(int target)

7

should be called immediately after target is added to the tree

updates d so that the values are correct (goes through targets

neighbours making sure that the distances between them and the tree

are indeed minimum)void updateDistances(int target)

int ifor (i = 0 i lt n ++i)

if ((weight[target][i] = 0) ampamp (d[i] gt weight[target][i]))

d[i] = weight[target][i]whoTo[i] = target

int main(int argc char argv[]) FILE f = fopen(disttxt r)fscanf(f d ampn)int i jfor (i = 0 i lt n ++i)

for (j = 0 j lt n ++j)fscanf(f d ampweight[i][j])

fclose(f)

Initialise d with infinity for (i = 0 i lt n ++i)

d[i] = 100000

Mark all nodes as NOT beeing in the minimum spanning tree

for (i = 0 i lt n ++i)inTree[i] = 0

Add the first node to the tree printf(Adding node cn 0 + A)inTree[0] = 1updateDistances(0)

int total = 0int treeSizefor (treeSize = 1 treeSize lt n ++treeSize)

Find the node with the smallest distance to the tree

int min = -1for (i = 0 i lt n ++i)

if (inTree[i])if ((min == -1) || (d[min] gt d[i]))

min = i

8

And add it printf(Adding edge c-cn whoTo[min] + A min +

A)inTree[min] = 1total += d[min]

updateDistances(min)

printf(Total distance dn total)

return 0

8 Explain the following graph problems

A) Telecommunication problem - Subscription con_guration problem and is taken (with slight modi_cation) from [4]Let F denote a _nite set of features For fi fj 2 F a precedence constraint(figtfj) indicates that fi is after fj An exclusion constraint (filtgtfj) between fiand fj indicates that fi and fj cannot appear together in a sequence of featuresand is equivalent to the pair (figtfj ) (fjgtfi) A catalog is a pair hF Pi with F aset of features and P a set of precedence constraints on F A feature subscriptionS of a catalog hFc Pci is a tuple hFCUWF WUi where F _ Fc is the set offeatures selected from Fc C is the projection of Pc on F U is a set of user de_nedprecedence constraints on F and WF F N and WUU N are maps whichassign weights to features and user precedence constraints The value of S isde_ned by V alue(S) = _f2FWF (f) + _p2UWU(p) The weight associated witha feature or a precedence constraint signi_es its importance for the userA feature subscription hFCUWF WUi is consistent i_ the directed graphhFC[Ui is acyclic Checking for consistency is straightforward using topologicalsort as described in [4] If a feature subscription is inconsistent then the task isto relax it and to generate a consistent one with maximum value A relaxationof a feature subscription S = hFCUWF WUi is a consistent subscriptionS0 = hF0C0U0WF0 WU0 i such that F0 _ F C0 is the projection of C on F0U0 is a subset of the projection of U on F0 WF0 is the restriction of WF to F0and WU0 is the restriction of WU to U0 We say that S0 is an optimal relaxationof S if there does not exist another relaxation S00 of S such that V alue(S00) gtV alue(S0) In [4] the authors prove that _nding an optimal relaxation of afeature subscription is NP-hard This is the problem addressed in this paper

B) Knight Moves - A knight is a chess piece that can move either two spaces horizontally and one space vertically or one space horizontally and two spaces vertically That is a knight on square (xy) can move to any of the eight squares (x plusmn 2y plusmn 1) (x plusmn 1y plusmn 2) if these squares exist on the chessboard (which is normally 8 times 8) A knightrsquos tour is a sequence of legal moves by a knight starting at some square and visiting each square exactly once A knightrsquos tour is called reentrant if there is a legal move that takes the knight from the last square of the tour back to where the tour began We can model knightrsquos tours using the graph that has a vertex for each square

9

on the boardwith an edge connecting two vertices if a knight can legally move between the squares represented by these vertices (a) Show that finding a reentrant knightrsquos tour on an m times n chessboard is equivalent to finding a Hamilton circuit on the corresponding graph (b) Show that the graph representing the legal moves of a knight on a mtimesn chessboard wherever m and n are positive integers is bipartite (c) Deduce that there is no reentrant knightrsquos tour on an m times n chessboard when m

and n are both odd

10

August 2010

Master of Computer Application (MCA) ndash Semester 2

MC0068 ndash Data Structures using C

Assignment Set ndash 2

1 Describe the theory of circular singly linked lists

Ans- The linked lisis that we have seen so far are often known as linear linked

lists The elements of such a linked list can be accessed first by setting up a

pointer pointing to the first node in the list and then traversing the entire list using

this pointer Although a linear linked list is a useful data structure it has several

shortcomings For example given a pointer p to a node in a linear list we cannot

reach any of the nodes that precede the node to which p is pointing This

disadvantage can be overcome by making a small change to the structure of a

linear list such that the link field in the last node contains a pointer back to the

first node rather than a NULL Such a list is called a circular linked list

2 Describe following Binary Trees

A) Strictly Binary trees - A binary tree is a finite set of elements that is either

empty or is partitioned into three disjoint subsets The first subset contains a

single element called the root of the tree The other two subsets are themselves

binary trees called the left and rightsubtrees of the original tree A left or right

subtree can be empty Each element of a binary tree is called a node of the tree

and the tree consists of nine nodes with A as its root Its left subtree is rooted at B

and its right subtree is rooted at C This is indicated by the two branches

emanating from A to B on the left and to C on the right The absence of a branch

indicates an empty subtree For example the left subtree of the binary tree rooted

at C and the right subtree of the binary tree rooted at E are both empty The

binary trees rooted at D G H and I have empty right and left subtrees Following

figure illustrates some structures that are not binary trees Be sure that you

understand why each of them is not a binary tree as just defined

B) Complete Binary trees - A binary tree is made of nodes where each node contains a

left pointer a right pointer and a data element The root pointer points to the topmost

node in the tree The left and right pointers recursively point to smaller subtrees on either

side A null pointer represents a binary tree with no elements -- the empty tree The formal

11

recursive definition is a binary tree is either empty (represented by a null pointer) or is made

of a single node where the left and right pointers (recursive definition ahead) each point to a

binary tree

C) Almost Complete Binary Trees - All leafs at lowest and next-tolowest levels onlyAll

except the lowest level is fullNo gaps except at the end of a level A perfectly balanced tree with

leaves at the last level all in the leftmost position A tree which can be represented

without any vacant space in the array representation

3 With the help of a program and an example explain Breadth First Tree

Traversal

Ans- Certain programming problems are easier to solve using multiple data structures

For example testing a sequence of characters to determine if it is a palindrome (ie reads the same forward and backward like radar) can be accomplished easily with one stack and one queue The solution is to enter the sequence of characters into both data structures then remove letters from each data structure one at a time and compare them making sure that the letters match

In this palindrome example the user (person writing the main program) has access to both data structures to solve the problem Another way that 2 data structures can be used in concert is to use one data structure to help implement another

treeh treec------ ------ include treeh include queueh

typedef char treeElementT typedef struct treeNodeTag treeElementT element struct treeNodeTag left right treeNodeT

typedef struct treeCDT typedef struct treeCDT treeADT treeNodeT root treeCDT

4 Write a program to perform a binary search on an unsorted list of n integers

Ans-

Program Example-

includeltstdiohgt

includeltconiohgt

12

includeltmathhgt

int main()

int a[20]= 0

int n i j temp

int beg end mid target

printf( enter the total integers you want to enter (make it less

then 20)n)

scanf(d ampn)

if (n gt= 20) return 0

printf( enter the integer array elementsn )

for(i = 0 i lt n i++)

scanf(d ampa[i])

for(i = 0 i lt n-1 i++)

for(j = 0 j lt n-i-1 j++)

if (a[j+1] lt a[j])

temp = a[j]

a[j] = a[j+1]

a[j+1] = temp

13

printf( the sorted numbers are)

for(i = 0 i lt n i++)

printf(d a[i])

beg = ampa[0]

end = ampa[n]

mid = beg += n2

printf(n enter the number to be searched)

scanf(damptarget)

while((beg lt= end) ampamp (mid = target))

if (target lt mid)

end = mid ndash 1

n = n2

mid = beg += n2

else

beg = mid + 1

n = n2

mid = beg += n2

14

if (mid == target)

printf(n d found target)

else

printf(n d not found target)

getchar()

getchar()

return 0

5 With the help of a numerical example explain the working of Insertion Sort

Ans- When sorting an array with insertion sort we conceptually separate it into two parts

The list of elements already inserted which is always in sorted order and is found at the

beginning of the arrayThe list of elements we have yet to insert following

In outline our primary function looks like thisltltinsertion_sortgtgt=void insertion_sort(int a[] int length) int i for (i=0 i lt length i++) insert a[i] into sorted sublist

To insert each element we need to create a hole in the array at the place where the element

belongs then place the element in that hole We can combine the creation of the hole with the

searching for the place by starting at the end and shifting each element up by one until we find

15

the place where the element belongs This overwrites the element were inserting so we have

to save it in a variable firstltltinsert a[i] into sorted sublistgtgt=int j v = a[i]

for (j = i - 1 j gt= 0 j--) if (a[j] lt= v) break a[j + 1] = a[j]

a[j + 1] = v

6 Describe Depth First search algorithm and analyze its complexity

Ans- Formally DFS is an uninformed search that progresses by expanding the first child node of the search tree that appears and thus going deeper and deeper until a goal node is found or until it hits a node that has no children Then the search backtracks returning to the most recent node it hasnt finished exploring In a non-recursive implementation all freshly expanded nodes are added to a stack for exploration

The time and space analysis of DFS differs according to its application area In theoretical computer science DFS is typically used to traverse an entire graph and takes time O(|V| + |E|) linear in the size of the graph In these applications it also uses space O(|V|) in the worst case to store the stack of vertices on the current search path as well as the set of already-visited vertices Thus in this setting the time and space bounds are the same as for breadth first search and the choice of which of these two algorithms to use depends less on their complexity and more on the different properties of the vertex orderings the two algorithms produce

a depth-first search starting at A assuming that the left edges in the shown graph are chosen before right edges and assuming the search remembers previously-visited nodes and will not repeat them (since this is a small graph) will visit the nodes in the following order A B D F E C G

Performing the same search without remembering previously visited nodes results in visiting nodes in the order A B D F E A B D F E etc forever caught in the A B D F E cycle and never reaching C or G

16

7 Explain the following theorems of Splay trees

A) Working Set Theorem - A splay tree is a self-adjusting binary search tree with the additional property that recently accessed elements are quick to access again It performs basic operations such as insertion look-up and removal in O(log n) amortized time For many sequences of operations splay trees perform better than other search trees even when the specific pattern of the sequence is unknown

All normal operations on a binary search tree are combined with one basic operation called splaying Splaying the tree for a certain element rearranges the tree so that the element is placed at the root of the tree One way to do this is to first perform a standard binary tree search for the element in question and then use tree rotations in a specific fashion to bring the element to the top Alternatively a top-down algorithm can combine the search and the tree reorganization into a single phase

When a node x is accessed a splay operation is performed on x to move it to the root To perform a splay operation we carry out a sequence of splay steps each of which moves x closer to the root By performing a splay operation on the node of interest after every access the recently accessed nodes are kept near the root and the tree remains roughly balanced so that we achieve the desired amortized time bounds

B) Sequential Access Theorem - When a node x is accessed a splay operation is

performed on x to move it to the root To perform a splay operation we carry out a

sequence of splay steps each of which moves x closer to the root By performing a splay

operation on the node of interest after every access the recently accessed nodes are kept

near the root and the tree remains roughly balanced so that we achieve the desired

amortized time boundsEach particular step depends on three factors

Whether x is the left or right child of its parent node p

whether p is the root or not and if not

whether p is the left or right child of its parent g (the grandparent of x)

The three types of splay steps are

Zig Step This step is done when p is the root The tree is rotated on the edge between x

and p Zig steps exist to deal with the parity issue and will be done only as the last step in

a splay operation and only when x has odd depth at the beginning of the operation

Zig-zig Step This step is done when p is not the root and x and p are either both right

children or are both left children The picture below shows the case where x and p are both

left children The tree is rotated on the edge joining p with its parent g then rotated on the

17

edge joining x with p Note that zig-zig steps are the only thing that differentiate splay

trees from the rotate to root method introduced by Allen and Munro prior to the

introduction of splay trees

Zig-zag Step This step is done when p is not the root and x is a right child and p is a left

child or vice versa The tree is rotated on the edge between x and p then rotated on the

edge between x and its new parent g

C) Dynamic Finger Theorem - A simple amortized analysis of static splay trees can be carried out using the potential method Suppose that size(r) is the number of nodes in the subtree rooted at r (including r) and rank(r) = log2(size(r)) Then the potential function P(t) for a splay tree t is the sum of the ranks of all the nodes in the tree This will tend to be high for poorly-balanced trees and low for well-balanced trees We can bound the amortized cost of any zig-zig or zig-zag operation by

amortized cost = cost + P(tf) - P(ti) le 3(rankf(x) - ranki(x))

where x is the node being moved towards the root and the subscripts f and i indicate after and before the operation respectively When summed over the entire splay operation this telescopes to 3(rank(root)) which is O(log n) Since theres at most one zig operation this only adds a constant

Dynamic Finger Theorem The cost of performing S is O(m+n log n + sum mi=1 log( |Ij+1 ndash Ij + 1 ))

8 Explain the following in the context of files

A) Sequential Files - True random access file handling however only accesses the file at the point at which the data should be read or written rather than having to process it sequentially A hybrid approach is also possible whereby a part of the file is used for sequential access to locate something in the random access portion of the file in much the same way that a File Allocation Table (FAT) worksThe three main functions that this article will deal with are

rewind() ndash return the file pointer to the beginning fseek() ndash position the file pointer ftell() ndash return the current offset of the file pointer

Each of these functions operates on the C file pointer which is just the offset from the start of the file and can be positioned at will All readwrite operations take place at the current position of the file pointer The rewind() Function The rewind() function can be used in sequential or random access C file programming and simply tells the file system to position the file pointer at the start of the file Any error flags will also be cleared and no value is returned While useful the companion function fseek() can also be used to reposition the file pointer at will including the same behavior as rewind() Using fseek() and ftell() to Process Files

18

The fseek() function is most useful in random access files where either the record (or block) size is known or there is an allocation system that denotes the start and end positions of records in an index portion of the file The fseek() function takes three parameters

FILE f ndash the file pointer long offset ndash the position offset int origin ndash the point from which the offset is applied

B) Inverted Files - The inverted index data structure is a central component of a typical search engine indexing algorithm A goal of a search engine implementation is to optimize the speed of the query find the documents where word X occurs Once a forward index is developed which stores lists of words per document it is next inverted to develop an inverted index Querying the forward index would require sequential iteration through each document and to each word to verify a matching document The time memory and processing resources to perform such a query are not always technically realistic Instead of listing the words per document in the forward index the inverted index data structure is developed which lists the documents per word

With the inverted index created the query can now be resolved by jumping to the word id (via random access) in the inverted index

In pre-computer times concordances to important books were manually assembled These were effectively inverted indexes with a small amount of accompanying commentary that required a tremendous amount of effort to produce

There are two main variants of inverted indexes A record level inverted index (or inverted file index or just inverted file) contains a list of references to documents for each word A word level inverted index (or full inverted index or inverted list) additionally contains the positions of each word within a document The latter form offers more functionality (like phrase searches) but needs more time and space to be created

19

  • Ans- Stack operations-
Page 8: SEM_2_MC0068_ Data Structures Using C

should be called immediately after target is added to the tree

updates d so that the values are correct (goes through targets

neighbours making sure that the distances between them and the tree

are indeed minimum)void updateDistances(int target)

int ifor (i = 0 i lt n ++i)

if ((weight[target][i] = 0) ampamp (d[i] gt weight[target][i]))

d[i] = weight[target][i]whoTo[i] = target

int main(int argc char argv[]) FILE f = fopen(disttxt r)fscanf(f d ampn)int i jfor (i = 0 i lt n ++i)

for (j = 0 j lt n ++j)fscanf(f d ampweight[i][j])

fclose(f)

Initialise d with infinity for (i = 0 i lt n ++i)

d[i] = 100000

Mark all nodes as NOT beeing in the minimum spanning tree

for (i = 0 i lt n ++i)inTree[i] = 0

Add the first node to the tree printf(Adding node cn 0 + A)inTree[0] = 1updateDistances(0)

int total = 0int treeSizefor (treeSize = 1 treeSize lt n ++treeSize)

Find the node with the smallest distance to the tree

int min = -1for (i = 0 i lt n ++i)

if (inTree[i])if ((min == -1) || (d[min] gt d[i]))

min = i

8

And add it printf(Adding edge c-cn whoTo[min] + A min +

A)inTree[min] = 1total += d[min]

updateDistances(min)

printf(Total distance dn total)

return 0

8 Explain the following graph problems

A) Telecommunication problem - Subscription con_guration problem and is taken (with slight modi_cation) from [4]Let F denote a _nite set of features For fi fj 2 F a precedence constraint(figtfj) indicates that fi is after fj An exclusion constraint (filtgtfj) between fiand fj indicates that fi and fj cannot appear together in a sequence of featuresand is equivalent to the pair (figtfj ) (fjgtfi) A catalog is a pair hF Pi with F aset of features and P a set of precedence constraints on F A feature subscriptionS of a catalog hFc Pci is a tuple hFCUWF WUi where F _ Fc is the set offeatures selected from Fc C is the projection of Pc on F U is a set of user de_nedprecedence constraints on F and WF F N and WUU N are maps whichassign weights to features and user precedence constraints The value of S isde_ned by V alue(S) = _f2FWF (f) + _p2UWU(p) The weight associated witha feature or a precedence constraint signi_es its importance for the userA feature subscription hFCUWF WUi is consistent i_ the directed graphhFC[Ui is acyclic Checking for consistency is straightforward using topologicalsort as described in [4] If a feature subscription is inconsistent then the task isto relax it and to generate a consistent one with maximum value A relaxationof a feature subscription S = hFCUWF WUi is a consistent subscriptionS0 = hF0C0U0WF0 WU0 i such that F0 _ F C0 is the projection of C on F0U0 is a subset of the projection of U on F0 WF0 is the restriction of WF to F0and WU0 is the restriction of WU to U0 We say that S0 is an optimal relaxationof S if there does not exist another relaxation S00 of S such that V alue(S00) gtV alue(S0) In [4] the authors prove that _nding an optimal relaxation of afeature subscription is NP-hard This is the problem addressed in this paper

B) Knight Moves - A knight is a chess piece that can move either two spaces horizontally and one space vertically or one space horizontally and two spaces vertically That is a knight on square (xy) can move to any of the eight squares (x plusmn 2y plusmn 1) (x plusmn 1y plusmn 2) if these squares exist on the chessboard (which is normally 8 times 8) A knightrsquos tour is a sequence of legal moves by a knight starting at some square and visiting each square exactly once A knightrsquos tour is called reentrant if there is a legal move that takes the knight from the last square of the tour back to where the tour began We can model knightrsquos tours using the graph that has a vertex for each square

9

on the boardwith an edge connecting two vertices if a knight can legally move between the squares represented by these vertices (a) Show that finding a reentrant knightrsquos tour on an m times n chessboard is equivalent to finding a Hamilton circuit on the corresponding graph (b) Show that the graph representing the legal moves of a knight on a mtimesn chessboard wherever m and n are positive integers is bipartite (c) Deduce that there is no reentrant knightrsquos tour on an m times n chessboard when m

and n are both odd

10

August 2010

Master of Computer Application (MCA) ndash Semester 2

MC0068 ndash Data Structures using C

Assignment Set ndash 2

1 Describe the theory of circular singly linked lists

Ans- The linked lisis that we have seen so far are often known as linear linked

lists The elements of such a linked list can be accessed first by setting up a

pointer pointing to the first node in the list and then traversing the entire list using

this pointer Although a linear linked list is a useful data structure it has several

shortcomings For example given a pointer p to a node in a linear list we cannot

reach any of the nodes that precede the node to which p is pointing This

disadvantage can be overcome by making a small change to the structure of a

linear list such that the link field in the last node contains a pointer back to the

first node rather than a NULL Such a list is called a circular linked list

2 Describe following Binary Trees

A) Strictly Binary trees - A binary tree is a finite set of elements that is either

empty or is partitioned into three disjoint subsets The first subset contains a

single element called the root of the tree The other two subsets are themselves

binary trees called the left and rightsubtrees of the original tree A left or right

subtree can be empty Each element of a binary tree is called a node of the tree

and the tree consists of nine nodes with A as its root Its left subtree is rooted at B

and its right subtree is rooted at C This is indicated by the two branches

emanating from A to B on the left and to C on the right The absence of a branch

indicates an empty subtree For example the left subtree of the binary tree rooted

at C and the right subtree of the binary tree rooted at E are both empty The

binary trees rooted at D G H and I have empty right and left subtrees Following

figure illustrates some structures that are not binary trees Be sure that you

understand why each of them is not a binary tree as just defined

B) Complete Binary trees - A binary tree is made of nodes where each node contains a

left pointer a right pointer and a data element The root pointer points to the topmost

node in the tree The left and right pointers recursively point to smaller subtrees on either

side A null pointer represents a binary tree with no elements -- the empty tree The formal

11

recursive definition is a binary tree is either empty (represented by a null pointer) or is made

of a single node where the left and right pointers (recursive definition ahead) each point to a

binary tree

C) Almost Complete Binary Trees - All leafs at lowest and next-tolowest levels onlyAll

except the lowest level is fullNo gaps except at the end of a level A perfectly balanced tree with

leaves at the last level all in the leftmost position A tree which can be represented

without any vacant space in the array representation

3 With the help of a program and an example explain Breadth First Tree

Traversal

Ans- Certain programming problems are easier to solve using multiple data structures

For example testing a sequence of characters to determine if it is a palindrome (ie reads the same forward and backward like radar) can be accomplished easily with one stack and one queue The solution is to enter the sequence of characters into both data structures then remove letters from each data structure one at a time and compare them making sure that the letters match

In this palindrome example the user (person writing the main program) has access to both data structures to solve the problem Another way that 2 data structures can be used in concert is to use one data structure to help implement another

treeh treec------ ------ include treeh include queueh

typedef char treeElementT typedef struct treeNodeTag treeElementT element struct treeNodeTag left right treeNodeT

typedef struct treeCDT typedef struct treeCDT treeADT treeNodeT root treeCDT

4 Write a program to perform a binary search on an unsorted list of n integers

Ans-

Program Example-

includeltstdiohgt

includeltconiohgt

12

includeltmathhgt

int main()

int a[20]= 0

int n i j temp

int beg end mid target

printf( enter the total integers you want to enter (make it less

then 20)n)

scanf(d ampn)

if (n gt= 20) return 0

printf( enter the integer array elementsn )

for(i = 0 i lt n i++)

scanf(d ampa[i])

for(i = 0 i lt n-1 i++)

for(j = 0 j lt n-i-1 j++)

if (a[j+1] lt a[j])

temp = a[j]

a[j] = a[j+1]

a[j+1] = temp

13

printf( the sorted numbers are)

for(i = 0 i lt n i++)

printf(d a[i])

beg = ampa[0]

end = ampa[n]

mid = beg += n2

printf(n enter the number to be searched)

scanf(damptarget)

while((beg lt= end) ampamp (mid = target))

if (target lt mid)

end = mid ndash 1

n = n2

mid = beg += n2

else

beg = mid + 1

n = n2

mid = beg += n2

14

if (mid == target)

printf(n d found target)

else

printf(n d not found target)

getchar()

getchar()

return 0

5 With the help of a numerical example explain the working of Insertion Sort

Ans- When sorting an array with insertion sort we conceptually separate it into two parts

The list of elements already inserted which is always in sorted order and is found at the

beginning of the arrayThe list of elements we have yet to insert following

In outline our primary function looks like thisltltinsertion_sortgtgt=void insertion_sort(int a[] int length) int i for (i=0 i lt length i++) insert a[i] into sorted sublist

To insert each element we need to create a hole in the array at the place where the element

belongs then place the element in that hole We can combine the creation of the hole with the

searching for the place by starting at the end and shifting each element up by one until we find

15

the place where the element belongs This overwrites the element were inserting so we have

to save it in a variable firstltltinsert a[i] into sorted sublistgtgt=int j v = a[i]

for (j = i - 1 j gt= 0 j--) if (a[j] lt= v) break a[j + 1] = a[j]

a[j + 1] = v

6 Describe Depth First search algorithm and analyze its complexity

Ans- Formally DFS is an uninformed search that progresses by expanding the first child node of the search tree that appears and thus going deeper and deeper until a goal node is found or until it hits a node that has no children Then the search backtracks returning to the most recent node it hasnt finished exploring In a non-recursive implementation all freshly expanded nodes are added to a stack for exploration

The time and space analysis of DFS differs according to its application area In theoretical computer science DFS is typically used to traverse an entire graph and takes time O(|V| + |E|) linear in the size of the graph In these applications it also uses space O(|V|) in the worst case to store the stack of vertices on the current search path as well as the set of already-visited vertices Thus in this setting the time and space bounds are the same as for breadth first search and the choice of which of these two algorithms to use depends less on their complexity and more on the different properties of the vertex orderings the two algorithms produce

a depth-first search starting at A assuming that the left edges in the shown graph are chosen before right edges and assuming the search remembers previously-visited nodes and will not repeat them (since this is a small graph) will visit the nodes in the following order A B D F E C G

Performing the same search without remembering previously visited nodes results in visiting nodes in the order A B D F E A B D F E etc forever caught in the A B D F E cycle and never reaching C or G

16

7 Explain the following theorems of Splay trees

A) Working Set Theorem - A splay tree is a self-adjusting binary search tree with the additional property that recently accessed elements are quick to access again It performs basic operations such as insertion look-up and removal in O(log n) amortized time For many sequences of operations splay trees perform better than other search trees even when the specific pattern of the sequence is unknown

All normal operations on a binary search tree are combined with one basic operation called splaying Splaying the tree for a certain element rearranges the tree so that the element is placed at the root of the tree One way to do this is to first perform a standard binary tree search for the element in question and then use tree rotations in a specific fashion to bring the element to the top Alternatively a top-down algorithm can combine the search and the tree reorganization into a single phase

When a node x is accessed a splay operation is performed on x to move it to the root To perform a splay operation we carry out a sequence of splay steps each of which moves x closer to the root By performing a splay operation on the node of interest after every access the recently accessed nodes are kept near the root and the tree remains roughly balanced so that we achieve the desired amortized time bounds

B) Sequential Access Theorem - When a node x is accessed a splay operation is

performed on x to move it to the root To perform a splay operation we carry out a

sequence of splay steps each of which moves x closer to the root By performing a splay

operation on the node of interest after every access the recently accessed nodes are kept

near the root and the tree remains roughly balanced so that we achieve the desired

amortized time boundsEach particular step depends on three factors

Whether x is the left or right child of its parent node p

whether p is the root or not and if not

whether p is the left or right child of its parent g (the grandparent of x)

The three types of splay steps are

Zig Step This step is done when p is the root The tree is rotated on the edge between x

and p Zig steps exist to deal with the parity issue and will be done only as the last step in

a splay operation and only when x has odd depth at the beginning of the operation

Zig-zig Step This step is done when p is not the root and x and p are either both right

children or are both left children The picture below shows the case where x and p are both

left children The tree is rotated on the edge joining p with its parent g then rotated on the

17

edge joining x with p Note that zig-zig steps are the only thing that differentiate splay

trees from the rotate to root method introduced by Allen and Munro prior to the

introduction of splay trees

Zig-zag Step This step is done when p is not the root and x is a right child and p is a left

child or vice versa The tree is rotated on the edge between x and p then rotated on the

edge between x and its new parent g

C) Dynamic Finger Theorem - A simple amortized analysis of static splay trees can be carried out using the potential method Suppose that size(r) is the number of nodes in the subtree rooted at r (including r) and rank(r) = log2(size(r)) Then the potential function P(t) for a splay tree t is the sum of the ranks of all the nodes in the tree This will tend to be high for poorly-balanced trees and low for well-balanced trees We can bound the amortized cost of any zig-zig or zig-zag operation by

amortized cost = cost + P(tf) - P(ti) le 3(rankf(x) - ranki(x))

where x is the node being moved towards the root and the subscripts f and i indicate after and before the operation respectively When summed over the entire splay operation this telescopes to 3(rank(root)) which is O(log n) Since theres at most one zig operation this only adds a constant

Dynamic Finger Theorem The cost of performing S is O(m+n log n + sum mi=1 log( |Ij+1 ndash Ij + 1 ))

8 Explain the following in the context of files

A) Sequential Files - True random access file handling however only accesses the file at the point at which the data should be read or written rather than having to process it sequentially A hybrid approach is also possible whereby a part of the file is used for sequential access to locate something in the random access portion of the file in much the same way that a File Allocation Table (FAT) worksThe three main functions that this article will deal with are

rewind() ndash return the file pointer to the beginning fseek() ndash position the file pointer ftell() ndash return the current offset of the file pointer

Each of these functions operates on the C file pointer which is just the offset from the start of the file and can be positioned at will All readwrite operations take place at the current position of the file pointer The rewind() Function The rewind() function can be used in sequential or random access C file programming and simply tells the file system to position the file pointer at the start of the file Any error flags will also be cleared and no value is returned While useful the companion function fseek() can also be used to reposition the file pointer at will including the same behavior as rewind() Using fseek() and ftell() to Process Files

18

The fseek() function is most useful in random access files where either the record (or block) size is known or there is an allocation system that denotes the start and end positions of records in an index portion of the file The fseek() function takes three parameters

FILE f ndash the file pointer long offset ndash the position offset int origin ndash the point from which the offset is applied

B) Inverted Files - The inverted index data structure is a central component of a typical search engine indexing algorithm A goal of a search engine implementation is to optimize the speed of the query find the documents where word X occurs Once a forward index is developed which stores lists of words per document it is next inverted to develop an inverted index Querying the forward index would require sequential iteration through each document and to each word to verify a matching document The time memory and processing resources to perform such a query are not always technically realistic Instead of listing the words per document in the forward index the inverted index data structure is developed which lists the documents per word

With the inverted index created the query can now be resolved by jumping to the word id (via random access) in the inverted index

In pre-computer times concordances to important books were manually assembled These were effectively inverted indexes with a small amount of accompanying commentary that required a tremendous amount of effort to produce

There are two main variants of inverted indexes A record level inverted index (or inverted file index or just inverted file) contains a list of references to documents for each word A word level inverted index (or full inverted index or inverted list) additionally contains the positions of each word within a document The latter form offers more functionality (like phrase searches) but needs more time and space to be created

19

  • Ans- Stack operations-
Page 9: SEM_2_MC0068_ Data Structures Using C

And add it printf(Adding edge c-cn whoTo[min] + A min +

A)inTree[min] = 1total += d[min]

updateDistances(min)

printf(Total distance dn total)

return 0

8 Explain the following graph problems

A) Telecommunication problem - Subscription con_guration problem and is taken (with slight modi_cation) from [4]Let F denote a _nite set of features For fi fj 2 F a precedence constraint(figtfj) indicates that fi is after fj An exclusion constraint (filtgtfj) between fiand fj indicates that fi and fj cannot appear together in a sequence of featuresand is equivalent to the pair (figtfj ) (fjgtfi) A catalog is a pair hF Pi with F aset of features and P a set of precedence constraints on F A feature subscriptionS of a catalog hFc Pci is a tuple hFCUWF WUi where F _ Fc is the set offeatures selected from Fc C is the projection of Pc on F U is a set of user de_nedprecedence constraints on F and WF F N and WUU N are maps whichassign weights to features and user precedence constraints The value of S isde_ned by V alue(S) = _f2FWF (f) + _p2UWU(p) The weight associated witha feature or a precedence constraint signi_es its importance for the userA feature subscription hFCUWF WUi is consistent i_ the directed graphhFC[Ui is acyclic Checking for consistency is straightforward using topologicalsort as described in [4] If a feature subscription is inconsistent then the task isto relax it and to generate a consistent one with maximum value A relaxationof a feature subscription S = hFCUWF WUi is a consistent subscriptionS0 = hF0C0U0WF0 WU0 i such that F0 _ F C0 is the projection of C on F0U0 is a subset of the projection of U on F0 WF0 is the restriction of WF to F0and WU0 is the restriction of WU to U0 We say that S0 is an optimal relaxationof S if there does not exist another relaxation S00 of S such that V alue(S00) gtV alue(S0) In [4] the authors prove that _nding an optimal relaxation of afeature subscription is NP-hard This is the problem addressed in this paper

B) Knight Moves - A knight is a chess piece that can move either two spaces horizontally and one space vertically or one space horizontally and two spaces vertically That is a knight on square (xy) can move to any of the eight squares (x plusmn 2y plusmn 1) (x plusmn 1y plusmn 2) if these squares exist on the chessboard (which is normally 8 times 8) A knightrsquos tour is a sequence of legal moves by a knight starting at some square and visiting each square exactly once A knightrsquos tour is called reentrant if there is a legal move that takes the knight from the last square of the tour back to where the tour began We can model knightrsquos tours using the graph that has a vertex for each square

9

on the boardwith an edge connecting two vertices if a knight can legally move between the squares represented by these vertices (a) Show that finding a reentrant knightrsquos tour on an m times n chessboard is equivalent to finding a Hamilton circuit on the corresponding graph (b) Show that the graph representing the legal moves of a knight on a mtimesn chessboard wherever m and n are positive integers is bipartite (c) Deduce that there is no reentrant knightrsquos tour on an m times n chessboard when m

and n are both odd

10

August 2010

Master of Computer Application (MCA) ndash Semester 2

MC0068 ndash Data Structures using C

Assignment Set ndash 2

1 Describe the theory of circular singly linked lists

Ans- The linked lisis that we have seen so far are often known as linear linked

lists The elements of such a linked list can be accessed first by setting up a

pointer pointing to the first node in the list and then traversing the entire list using

this pointer Although a linear linked list is a useful data structure it has several

shortcomings For example given a pointer p to a node in a linear list we cannot

reach any of the nodes that precede the node to which p is pointing This

disadvantage can be overcome by making a small change to the structure of a

linear list such that the link field in the last node contains a pointer back to the

first node rather than a NULL Such a list is called a circular linked list

2 Describe following Binary Trees

A) Strictly Binary trees - A binary tree is a finite set of elements that is either

empty or is partitioned into three disjoint subsets The first subset contains a

single element called the root of the tree The other two subsets are themselves

binary trees called the left and rightsubtrees of the original tree A left or right

subtree can be empty Each element of a binary tree is called a node of the tree

and the tree consists of nine nodes with A as its root Its left subtree is rooted at B

and its right subtree is rooted at C This is indicated by the two branches

emanating from A to B on the left and to C on the right The absence of a branch

indicates an empty subtree For example the left subtree of the binary tree rooted

at C and the right subtree of the binary tree rooted at E are both empty The

binary trees rooted at D G H and I have empty right and left subtrees Following

figure illustrates some structures that are not binary trees Be sure that you

understand why each of them is not a binary tree as just defined

B) Complete Binary trees - A binary tree is made of nodes where each node contains a

left pointer a right pointer and a data element The root pointer points to the topmost

node in the tree The left and right pointers recursively point to smaller subtrees on either

side A null pointer represents a binary tree with no elements -- the empty tree The formal

11

recursive definition is a binary tree is either empty (represented by a null pointer) or is made

of a single node where the left and right pointers (recursive definition ahead) each point to a

binary tree

C) Almost Complete Binary Trees - All leafs at lowest and next-tolowest levels onlyAll

except the lowest level is fullNo gaps except at the end of a level A perfectly balanced tree with

leaves at the last level all in the leftmost position A tree which can be represented

without any vacant space in the array representation

3 With the help of a program and an example explain Breadth First Tree

Traversal

Ans- Certain programming problems are easier to solve using multiple data structures

For example testing a sequence of characters to determine if it is a palindrome (ie reads the same forward and backward like radar) can be accomplished easily with one stack and one queue The solution is to enter the sequence of characters into both data structures then remove letters from each data structure one at a time and compare them making sure that the letters match

In this palindrome example the user (person writing the main program) has access to both data structures to solve the problem Another way that 2 data structures can be used in concert is to use one data structure to help implement another

treeh treec------ ------ include treeh include queueh

typedef char treeElementT typedef struct treeNodeTag treeElementT element struct treeNodeTag left right treeNodeT

typedef struct treeCDT typedef struct treeCDT treeADT treeNodeT root treeCDT

4 Write a program to perform a binary search on an unsorted list of n integers

Ans-

Program Example-

includeltstdiohgt

includeltconiohgt

12

includeltmathhgt

int main()

int a[20]= 0

int n i j temp

int beg end mid target

printf( enter the total integers you want to enter (make it less

then 20)n)

scanf(d ampn)

if (n gt= 20) return 0

printf( enter the integer array elementsn )

for(i = 0 i lt n i++)

scanf(d ampa[i])

for(i = 0 i lt n-1 i++)

for(j = 0 j lt n-i-1 j++)

if (a[j+1] lt a[j])

temp = a[j]

a[j] = a[j+1]

a[j+1] = temp

13

printf( the sorted numbers are)

for(i = 0 i lt n i++)

printf(d a[i])

beg = ampa[0]

end = ampa[n]

mid = beg += n2

printf(n enter the number to be searched)

scanf(damptarget)

while((beg lt= end) ampamp (mid = target))

if (target lt mid)

end = mid ndash 1

n = n2

mid = beg += n2

else

beg = mid + 1

n = n2

mid = beg += n2

14

if (mid == target)

printf(n d found target)

else

printf(n d not found target)

getchar()

getchar()

return 0

5 With the help of a numerical example explain the working of Insertion Sort

Ans- When sorting an array with insertion sort we conceptually separate it into two parts

The list of elements already inserted which is always in sorted order and is found at the

beginning of the arrayThe list of elements we have yet to insert following

In outline our primary function looks like thisltltinsertion_sortgtgt=void insertion_sort(int a[] int length) int i for (i=0 i lt length i++) insert a[i] into sorted sublist

To insert each element we need to create a hole in the array at the place where the element

belongs then place the element in that hole We can combine the creation of the hole with the

searching for the place by starting at the end and shifting each element up by one until we find

15

the place where the element belongs This overwrites the element were inserting so we have

to save it in a variable firstltltinsert a[i] into sorted sublistgtgt=int j v = a[i]

for (j = i - 1 j gt= 0 j--) if (a[j] lt= v) break a[j + 1] = a[j]

a[j + 1] = v

6 Describe Depth First search algorithm and analyze its complexity

Ans- Formally DFS is an uninformed search that progresses by expanding the first child node of the search tree that appears and thus going deeper and deeper until a goal node is found or until it hits a node that has no children Then the search backtracks returning to the most recent node it hasnt finished exploring In a non-recursive implementation all freshly expanded nodes are added to a stack for exploration

The time and space analysis of DFS differs according to its application area In theoretical computer science DFS is typically used to traverse an entire graph and takes time O(|V| + |E|) linear in the size of the graph In these applications it also uses space O(|V|) in the worst case to store the stack of vertices on the current search path as well as the set of already-visited vertices Thus in this setting the time and space bounds are the same as for breadth first search and the choice of which of these two algorithms to use depends less on their complexity and more on the different properties of the vertex orderings the two algorithms produce

a depth-first search starting at A assuming that the left edges in the shown graph are chosen before right edges and assuming the search remembers previously-visited nodes and will not repeat them (since this is a small graph) will visit the nodes in the following order A B D F E C G

Performing the same search without remembering previously visited nodes results in visiting nodes in the order A B D F E A B D F E etc forever caught in the A B D F E cycle and never reaching C or G

16

7 Explain the following theorems of Splay trees

A) Working Set Theorem - A splay tree is a self-adjusting binary search tree with the additional property that recently accessed elements are quick to access again It performs basic operations such as insertion look-up and removal in O(log n) amortized time For many sequences of operations splay trees perform better than other search trees even when the specific pattern of the sequence is unknown

All normal operations on a binary search tree are combined with one basic operation called splaying Splaying the tree for a certain element rearranges the tree so that the element is placed at the root of the tree One way to do this is to first perform a standard binary tree search for the element in question and then use tree rotations in a specific fashion to bring the element to the top Alternatively a top-down algorithm can combine the search and the tree reorganization into a single phase

When a node x is accessed a splay operation is performed on x to move it to the root To perform a splay operation we carry out a sequence of splay steps each of which moves x closer to the root By performing a splay operation on the node of interest after every access the recently accessed nodes are kept near the root and the tree remains roughly balanced so that we achieve the desired amortized time bounds

B) Sequential Access Theorem - When a node x is accessed a splay operation is

performed on x to move it to the root To perform a splay operation we carry out a

sequence of splay steps each of which moves x closer to the root By performing a splay

operation on the node of interest after every access the recently accessed nodes are kept

near the root and the tree remains roughly balanced so that we achieve the desired

amortized time boundsEach particular step depends on three factors

Whether x is the left or right child of its parent node p

whether p is the root or not and if not

whether p is the left or right child of its parent g (the grandparent of x)

The three types of splay steps are

Zig Step This step is done when p is the root The tree is rotated on the edge between x

and p Zig steps exist to deal with the parity issue and will be done only as the last step in

a splay operation and only when x has odd depth at the beginning of the operation

Zig-zig Step This step is done when p is not the root and x and p are either both right

children or are both left children The picture below shows the case where x and p are both

left children The tree is rotated on the edge joining p with its parent g then rotated on the

17

edge joining x with p Note that zig-zig steps are the only thing that differentiate splay

trees from the rotate to root method introduced by Allen and Munro prior to the

introduction of splay trees

Zig-zag Step This step is done when p is not the root and x is a right child and p is a left

child or vice versa The tree is rotated on the edge between x and p then rotated on the

edge between x and its new parent g

C) Dynamic Finger Theorem - A simple amortized analysis of static splay trees can be carried out using the potential method Suppose that size(r) is the number of nodes in the subtree rooted at r (including r) and rank(r) = log2(size(r)) Then the potential function P(t) for a splay tree t is the sum of the ranks of all the nodes in the tree This will tend to be high for poorly-balanced trees and low for well-balanced trees We can bound the amortized cost of any zig-zig or zig-zag operation by

amortized cost = cost + P(tf) - P(ti) le 3(rankf(x) - ranki(x))

where x is the node being moved towards the root and the subscripts f and i indicate after and before the operation respectively When summed over the entire splay operation this telescopes to 3(rank(root)) which is O(log n) Since theres at most one zig operation this only adds a constant

Dynamic Finger Theorem The cost of performing S is O(m+n log n + sum mi=1 log( |Ij+1 ndash Ij + 1 ))

8 Explain the following in the context of files

A) Sequential Files - True random access file handling however only accesses the file at the point at which the data should be read or written rather than having to process it sequentially A hybrid approach is also possible whereby a part of the file is used for sequential access to locate something in the random access portion of the file in much the same way that a File Allocation Table (FAT) worksThe three main functions that this article will deal with are

rewind() ndash return the file pointer to the beginning fseek() ndash position the file pointer ftell() ndash return the current offset of the file pointer

Each of these functions operates on the C file pointer which is just the offset from the start of the file and can be positioned at will All readwrite operations take place at the current position of the file pointer The rewind() Function The rewind() function can be used in sequential or random access C file programming and simply tells the file system to position the file pointer at the start of the file Any error flags will also be cleared and no value is returned While useful the companion function fseek() can also be used to reposition the file pointer at will including the same behavior as rewind() Using fseek() and ftell() to Process Files

18

The fseek() function is most useful in random access files where either the record (or block) size is known or there is an allocation system that denotes the start and end positions of records in an index portion of the file The fseek() function takes three parameters

FILE f ndash the file pointer long offset ndash the position offset int origin ndash the point from which the offset is applied

B) Inverted Files - The inverted index data structure is a central component of a typical search engine indexing algorithm A goal of a search engine implementation is to optimize the speed of the query find the documents where word X occurs Once a forward index is developed which stores lists of words per document it is next inverted to develop an inverted index Querying the forward index would require sequential iteration through each document and to each word to verify a matching document The time memory and processing resources to perform such a query are not always technically realistic Instead of listing the words per document in the forward index the inverted index data structure is developed which lists the documents per word

With the inverted index created the query can now be resolved by jumping to the word id (via random access) in the inverted index

In pre-computer times concordances to important books were manually assembled These were effectively inverted indexes with a small amount of accompanying commentary that required a tremendous amount of effort to produce

There are two main variants of inverted indexes A record level inverted index (or inverted file index or just inverted file) contains a list of references to documents for each word A word level inverted index (or full inverted index or inverted list) additionally contains the positions of each word within a document The latter form offers more functionality (like phrase searches) but needs more time and space to be created

19

  • Ans- Stack operations-
Page 10: SEM_2_MC0068_ Data Structures Using C

on the boardwith an edge connecting two vertices if a knight can legally move between the squares represented by these vertices (a) Show that finding a reentrant knightrsquos tour on an m times n chessboard is equivalent to finding a Hamilton circuit on the corresponding graph (b) Show that the graph representing the legal moves of a knight on a mtimesn chessboard wherever m and n are positive integers is bipartite (c) Deduce that there is no reentrant knightrsquos tour on an m times n chessboard when m

and n are both odd

10

August 2010

Master of Computer Application (MCA) ndash Semester 2

MC0068 ndash Data Structures using C

Assignment Set ndash 2

1 Describe the theory of circular singly linked lists

Ans- The linked lisis that we have seen so far are often known as linear linked

lists The elements of such a linked list can be accessed first by setting up a

pointer pointing to the first node in the list and then traversing the entire list using

this pointer Although a linear linked list is a useful data structure it has several

shortcomings For example given a pointer p to a node in a linear list we cannot

reach any of the nodes that precede the node to which p is pointing This

disadvantage can be overcome by making a small change to the structure of a

linear list such that the link field in the last node contains a pointer back to the

first node rather than a NULL Such a list is called a circular linked list

2 Describe following Binary Trees

A) Strictly Binary trees - A binary tree is a finite set of elements that is either

empty or is partitioned into three disjoint subsets The first subset contains a

single element called the root of the tree The other two subsets are themselves

binary trees called the left and rightsubtrees of the original tree A left or right

subtree can be empty Each element of a binary tree is called a node of the tree

and the tree consists of nine nodes with A as its root Its left subtree is rooted at B

and its right subtree is rooted at C This is indicated by the two branches

emanating from A to B on the left and to C on the right The absence of a branch

indicates an empty subtree For example the left subtree of the binary tree rooted

at C and the right subtree of the binary tree rooted at E are both empty The

binary trees rooted at D G H and I have empty right and left subtrees Following

figure illustrates some structures that are not binary trees Be sure that you

understand why each of them is not a binary tree as just defined

B) Complete Binary trees - A binary tree is made of nodes where each node contains a

left pointer a right pointer and a data element The root pointer points to the topmost

node in the tree The left and right pointers recursively point to smaller subtrees on either

side A null pointer represents a binary tree with no elements -- the empty tree The formal

11

recursive definition is a binary tree is either empty (represented by a null pointer) or is made

of a single node where the left and right pointers (recursive definition ahead) each point to a

binary tree

C) Almost Complete Binary Trees - All leafs at lowest and next-tolowest levels onlyAll

except the lowest level is fullNo gaps except at the end of a level A perfectly balanced tree with

leaves at the last level all in the leftmost position A tree which can be represented

without any vacant space in the array representation

3 With the help of a program and an example explain Breadth First Tree

Traversal

Ans- Certain programming problems are easier to solve using multiple data structures

For example testing a sequence of characters to determine if it is a palindrome (ie reads the same forward and backward like radar) can be accomplished easily with one stack and one queue The solution is to enter the sequence of characters into both data structures then remove letters from each data structure one at a time and compare them making sure that the letters match

In this palindrome example the user (person writing the main program) has access to both data structures to solve the problem Another way that 2 data structures can be used in concert is to use one data structure to help implement another

treeh treec------ ------ include treeh include queueh

typedef char treeElementT typedef struct treeNodeTag treeElementT element struct treeNodeTag left right treeNodeT

typedef struct treeCDT typedef struct treeCDT treeADT treeNodeT root treeCDT

4 Write a program to perform a binary search on an unsorted list of n integers

Ans-

Program Example-

includeltstdiohgt

includeltconiohgt

12

includeltmathhgt

int main()

int a[20]= 0

int n i j temp

int beg end mid target

printf( enter the total integers you want to enter (make it less

then 20)n)

scanf(d ampn)

if (n gt= 20) return 0

printf( enter the integer array elementsn )

for(i = 0 i lt n i++)

scanf(d ampa[i])

for(i = 0 i lt n-1 i++)

for(j = 0 j lt n-i-1 j++)

if (a[j+1] lt a[j])

temp = a[j]

a[j] = a[j+1]

a[j+1] = temp

13

printf( the sorted numbers are)

for(i = 0 i lt n i++)

printf(d a[i])

beg = ampa[0]

end = ampa[n]

mid = beg += n2

printf(n enter the number to be searched)

scanf(damptarget)

while((beg lt= end) ampamp (mid = target))

if (target lt mid)

end = mid ndash 1

n = n2

mid = beg += n2

else

beg = mid + 1

n = n2

mid = beg += n2

14

if (mid == target)

printf(n d found target)

else

printf(n d not found target)

getchar()

getchar()

return 0

5 With the help of a numerical example explain the working of Insertion Sort

Ans- When sorting an array with insertion sort we conceptually separate it into two parts

The list of elements already inserted which is always in sorted order and is found at the

beginning of the arrayThe list of elements we have yet to insert following

In outline our primary function looks like thisltltinsertion_sortgtgt=void insertion_sort(int a[] int length) int i for (i=0 i lt length i++) insert a[i] into sorted sublist

To insert each element we need to create a hole in the array at the place where the element

belongs then place the element in that hole We can combine the creation of the hole with the

searching for the place by starting at the end and shifting each element up by one until we find

15

the place where the element belongs This overwrites the element were inserting so we have

to save it in a variable firstltltinsert a[i] into sorted sublistgtgt=int j v = a[i]

for (j = i - 1 j gt= 0 j--) if (a[j] lt= v) break a[j + 1] = a[j]

a[j + 1] = v

6 Describe Depth First search algorithm and analyze its complexity

Ans- Formally DFS is an uninformed search that progresses by expanding the first child node of the search tree that appears and thus going deeper and deeper until a goal node is found or until it hits a node that has no children Then the search backtracks returning to the most recent node it hasnt finished exploring In a non-recursive implementation all freshly expanded nodes are added to a stack for exploration

The time and space analysis of DFS differs according to its application area In theoretical computer science DFS is typically used to traverse an entire graph and takes time O(|V| + |E|) linear in the size of the graph In these applications it also uses space O(|V|) in the worst case to store the stack of vertices on the current search path as well as the set of already-visited vertices Thus in this setting the time and space bounds are the same as for breadth first search and the choice of which of these two algorithms to use depends less on their complexity and more on the different properties of the vertex orderings the two algorithms produce

a depth-first search starting at A assuming that the left edges in the shown graph are chosen before right edges and assuming the search remembers previously-visited nodes and will not repeat them (since this is a small graph) will visit the nodes in the following order A B D F E C G

Performing the same search without remembering previously visited nodes results in visiting nodes in the order A B D F E A B D F E etc forever caught in the A B D F E cycle and never reaching C or G

16

7 Explain the following theorems of Splay trees

A) Working Set Theorem - A splay tree is a self-adjusting binary search tree with the additional property that recently accessed elements are quick to access again It performs basic operations such as insertion look-up and removal in O(log n) amortized time For many sequences of operations splay trees perform better than other search trees even when the specific pattern of the sequence is unknown

All normal operations on a binary search tree are combined with one basic operation called splaying Splaying the tree for a certain element rearranges the tree so that the element is placed at the root of the tree One way to do this is to first perform a standard binary tree search for the element in question and then use tree rotations in a specific fashion to bring the element to the top Alternatively a top-down algorithm can combine the search and the tree reorganization into a single phase

When a node x is accessed a splay operation is performed on x to move it to the root To perform a splay operation we carry out a sequence of splay steps each of which moves x closer to the root By performing a splay operation on the node of interest after every access the recently accessed nodes are kept near the root and the tree remains roughly balanced so that we achieve the desired amortized time bounds

B) Sequential Access Theorem - When a node x is accessed a splay operation is

performed on x to move it to the root To perform a splay operation we carry out a

sequence of splay steps each of which moves x closer to the root By performing a splay

operation on the node of interest after every access the recently accessed nodes are kept

near the root and the tree remains roughly balanced so that we achieve the desired

amortized time boundsEach particular step depends on three factors

Whether x is the left or right child of its parent node p

whether p is the root or not and if not

whether p is the left or right child of its parent g (the grandparent of x)

The three types of splay steps are

Zig Step This step is done when p is the root The tree is rotated on the edge between x

and p Zig steps exist to deal with the parity issue and will be done only as the last step in

a splay operation and only when x has odd depth at the beginning of the operation

Zig-zig Step This step is done when p is not the root and x and p are either both right

children or are both left children The picture below shows the case where x and p are both

left children The tree is rotated on the edge joining p with its parent g then rotated on the

17

edge joining x with p Note that zig-zig steps are the only thing that differentiate splay

trees from the rotate to root method introduced by Allen and Munro prior to the

introduction of splay trees

Zig-zag Step This step is done when p is not the root and x is a right child and p is a left

child or vice versa The tree is rotated on the edge between x and p then rotated on the

edge between x and its new parent g

C) Dynamic Finger Theorem - A simple amortized analysis of static splay trees can be carried out using the potential method Suppose that size(r) is the number of nodes in the subtree rooted at r (including r) and rank(r) = log2(size(r)) Then the potential function P(t) for a splay tree t is the sum of the ranks of all the nodes in the tree This will tend to be high for poorly-balanced trees and low for well-balanced trees We can bound the amortized cost of any zig-zig or zig-zag operation by

amortized cost = cost + P(tf) - P(ti) le 3(rankf(x) - ranki(x))

where x is the node being moved towards the root and the subscripts f and i indicate after and before the operation respectively When summed over the entire splay operation this telescopes to 3(rank(root)) which is O(log n) Since theres at most one zig operation this only adds a constant

Dynamic Finger Theorem The cost of performing S is O(m+n log n + sum mi=1 log( |Ij+1 ndash Ij + 1 ))

8 Explain the following in the context of files

A) Sequential Files - True random access file handling however only accesses the file at the point at which the data should be read or written rather than having to process it sequentially A hybrid approach is also possible whereby a part of the file is used for sequential access to locate something in the random access portion of the file in much the same way that a File Allocation Table (FAT) worksThe three main functions that this article will deal with are

rewind() ndash return the file pointer to the beginning fseek() ndash position the file pointer ftell() ndash return the current offset of the file pointer

Each of these functions operates on the C file pointer which is just the offset from the start of the file and can be positioned at will All readwrite operations take place at the current position of the file pointer The rewind() Function The rewind() function can be used in sequential or random access C file programming and simply tells the file system to position the file pointer at the start of the file Any error flags will also be cleared and no value is returned While useful the companion function fseek() can also be used to reposition the file pointer at will including the same behavior as rewind() Using fseek() and ftell() to Process Files

18

The fseek() function is most useful in random access files where either the record (or block) size is known or there is an allocation system that denotes the start and end positions of records in an index portion of the file The fseek() function takes three parameters

FILE f ndash the file pointer long offset ndash the position offset int origin ndash the point from which the offset is applied

B) Inverted Files - The inverted index data structure is a central component of a typical search engine indexing algorithm A goal of a search engine implementation is to optimize the speed of the query find the documents where word X occurs Once a forward index is developed which stores lists of words per document it is next inverted to develop an inverted index Querying the forward index would require sequential iteration through each document and to each word to verify a matching document The time memory and processing resources to perform such a query are not always technically realistic Instead of listing the words per document in the forward index the inverted index data structure is developed which lists the documents per word

With the inverted index created the query can now be resolved by jumping to the word id (via random access) in the inverted index

In pre-computer times concordances to important books were manually assembled These were effectively inverted indexes with a small amount of accompanying commentary that required a tremendous amount of effort to produce

There are two main variants of inverted indexes A record level inverted index (or inverted file index or just inverted file) contains a list of references to documents for each word A word level inverted index (or full inverted index or inverted list) additionally contains the positions of each word within a document The latter form offers more functionality (like phrase searches) but needs more time and space to be created

19

  • Ans- Stack operations-
Page 11: SEM_2_MC0068_ Data Structures Using C

August 2010

Master of Computer Application (MCA) ndash Semester 2

MC0068 ndash Data Structures using C

Assignment Set ndash 2

1 Describe the theory of circular singly linked lists

Ans- The linked lisis that we have seen so far are often known as linear linked

lists The elements of such a linked list can be accessed first by setting up a

pointer pointing to the first node in the list and then traversing the entire list using

this pointer Although a linear linked list is a useful data structure it has several

shortcomings For example given a pointer p to a node in a linear list we cannot

reach any of the nodes that precede the node to which p is pointing This

disadvantage can be overcome by making a small change to the structure of a

linear list such that the link field in the last node contains a pointer back to the

first node rather than a NULL Such a list is called a circular linked list

2 Describe following Binary Trees

A) Strictly Binary trees - A binary tree is a finite set of elements that is either

empty or is partitioned into three disjoint subsets The first subset contains a

single element called the root of the tree The other two subsets are themselves

binary trees called the left and rightsubtrees of the original tree A left or right

subtree can be empty Each element of a binary tree is called a node of the tree

and the tree consists of nine nodes with A as its root Its left subtree is rooted at B

and its right subtree is rooted at C This is indicated by the two branches

emanating from A to B on the left and to C on the right The absence of a branch

indicates an empty subtree For example the left subtree of the binary tree rooted

at C and the right subtree of the binary tree rooted at E are both empty The

binary trees rooted at D G H and I have empty right and left subtrees Following

figure illustrates some structures that are not binary trees Be sure that you

understand why each of them is not a binary tree as just defined

B) Complete Binary trees - A binary tree is made of nodes where each node contains a

left pointer a right pointer and a data element The root pointer points to the topmost

node in the tree The left and right pointers recursively point to smaller subtrees on either

side A null pointer represents a binary tree with no elements -- the empty tree The formal

11

recursive definition is a binary tree is either empty (represented by a null pointer) or is made

of a single node where the left and right pointers (recursive definition ahead) each point to a

binary tree

C) Almost Complete Binary Trees - All leafs at lowest and next-tolowest levels onlyAll

except the lowest level is fullNo gaps except at the end of a level A perfectly balanced tree with

leaves at the last level all in the leftmost position A tree which can be represented

without any vacant space in the array representation

3 With the help of a program and an example explain Breadth First Tree

Traversal

Ans- Certain programming problems are easier to solve using multiple data structures

For example testing a sequence of characters to determine if it is a palindrome (ie reads the same forward and backward like radar) can be accomplished easily with one stack and one queue The solution is to enter the sequence of characters into both data structures then remove letters from each data structure one at a time and compare them making sure that the letters match

In this palindrome example the user (person writing the main program) has access to both data structures to solve the problem Another way that 2 data structures can be used in concert is to use one data structure to help implement another

treeh treec------ ------ include treeh include queueh

typedef char treeElementT typedef struct treeNodeTag treeElementT element struct treeNodeTag left right treeNodeT

typedef struct treeCDT typedef struct treeCDT treeADT treeNodeT root treeCDT

4 Write a program to perform a binary search on an unsorted list of n integers

Ans-

Program Example-

includeltstdiohgt

includeltconiohgt

12

includeltmathhgt

int main()

int a[20]= 0

int n i j temp

int beg end mid target

printf( enter the total integers you want to enter (make it less

then 20)n)

scanf(d ampn)

if (n gt= 20) return 0

printf( enter the integer array elementsn )

for(i = 0 i lt n i++)

scanf(d ampa[i])

for(i = 0 i lt n-1 i++)

for(j = 0 j lt n-i-1 j++)

if (a[j+1] lt a[j])

temp = a[j]

a[j] = a[j+1]

a[j+1] = temp

13

printf( the sorted numbers are)

for(i = 0 i lt n i++)

printf(d a[i])

beg = ampa[0]

end = ampa[n]

mid = beg += n2

printf(n enter the number to be searched)

scanf(damptarget)

while((beg lt= end) ampamp (mid = target))

if (target lt mid)

end = mid ndash 1

n = n2

mid = beg += n2

else

beg = mid + 1

n = n2

mid = beg += n2

14

if (mid == target)

printf(n d found target)

else

printf(n d not found target)

getchar()

getchar()

return 0

5 With the help of a numerical example explain the working of Insertion Sort

Ans- When sorting an array with insertion sort we conceptually separate it into two parts

The list of elements already inserted which is always in sorted order and is found at the

beginning of the arrayThe list of elements we have yet to insert following

In outline our primary function looks like thisltltinsertion_sortgtgt=void insertion_sort(int a[] int length) int i for (i=0 i lt length i++) insert a[i] into sorted sublist

To insert each element we need to create a hole in the array at the place where the element

belongs then place the element in that hole We can combine the creation of the hole with the

searching for the place by starting at the end and shifting each element up by one until we find

15

the place where the element belongs This overwrites the element were inserting so we have

to save it in a variable firstltltinsert a[i] into sorted sublistgtgt=int j v = a[i]

for (j = i - 1 j gt= 0 j--) if (a[j] lt= v) break a[j + 1] = a[j]

a[j + 1] = v

6 Describe Depth First search algorithm and analyze its complexity

Ans- Formally DFS is an uninformed search that progresses by expanding the first child node of the search tree that appears and thus going deeper and deeper until a goal node is found or until it hits a node that has no children Then the search backtracks returning to the most recent node it hasnt finished exploring In a non-recursive implementation all freshly expanded nodes are added to a stack for exploration

The time and space analysis of DFS differs according to its application area In theoretical computer science DFS is typically used to traverse an entire graph and takes time O(|V| + |E|) linear in the size of the graph In these applications it also uses space O(|V|) in the worst case to store the stack of vertices on the current search path as well as the set of already-visited vertices Thus in this setting the time and space bounds are the same as for breadth first search and the choice of which of these two algorithms to use depends less on their complexity and more on the different properties of the vertex orderings the two algorithms produce

a depth-first search starting at A assuming that the left edges in the shown graph are chosen before right edges and assuming the search remembers previously-visited nodes and will not repeat them (since this is a small graph) will visit the nodes in the following order A B D F E C G

Performing the same search without remembering previously visited nodes results in visiting nodes in the order A B D F E A B D F E etc forever caught in the A B D F E cycle and never reaching C or G

16

7 Explain the following theorems of Splay trees

A) Working Set Theorem - A splay tree is a self-adjusting binary search tree with the additional property that recently accessed elements are quick to access again It performs basic operations such as insertion look-up and removal in O(log n) amortized time For many sequences of operations splay trees perform better than other search trees even when the specific pattern of the sequence is unknown

All normal operations on a binary search tree are combined with one basic operation called splaying Splaying the tree for a certain element rearranges the tree so that the element is placed at the root of the tree One way to do this is to first perform a standard binary tree search for the element in question and then use tree rotations in a specific fashion to bring the element to the top Alternatively a top-down algorithm can combine the search and the tree reorganization into a single phase

When a node x is accessed a splay operation is performed on x to move it to the root To perform a splay operation we carry out a sequence of splay steps each of which moves x closer to the root By performing a splay operation on the node of interest after every access the recently accessed nodes are kept near the root and the tree remains roughly balanced so that we achieve the desired amortized time bounds

B) Sequential Access Theorem - When a node x is accessed a splay operation is

performed on x to move it to the root To perform a splay operation we carry out a

sequence of splay steps each of which moves x closer to the root By performing a splay

operation on the node of interest after every access the recently accessed nodes are kept

near the root and the tree remains roughly balanced so that we achieve the desired

amortized time boundsEach particular step depends on three factors

Whether x is the left or right child of its parent node p

whether p is the root or not and if not

whether p is the left or right child of its parent g (the grandparent of x)

The three types of splay steps are

Zig Step This step is done when p is the root The tree is rotated on the edge between x

and p Zig steps exist to deal with the parity issue and will be done only as the last step in

a splay operation and only when x has odd depth at the beginning of the operation

Zig-zig Step This step is done when p is not the root and x and p are either both right

children or are both left children The picture below shows the case where x and p are both

left children The tree is rotated on the edge joining p with its parent g then rotated on the

17

edge joining x with p Note that zig-zig steps are the only thing that differentiate splay

trees from the rotate to root method introduced by Allen and Munro prior to the

introduction of splay trees

Zig-zag Step This step is done when p is not the root and x is a right child and p is a left

child or vice versa The tree is rotated on the edge between x and p then rotated on the

edge between x and its new parent g

C) Dynamic Finger Theorem - A simple amortized analysis of static splay trees can be carried out using the potential method Suppose that size(r) is the number of nodes in the subtree rooted at r (including r) and rank(r) = log2(size(r)) Then the potential function P(t) for a splay tree t is the sum of the ranks of all the nodes in the tree This will tend to be high for poorly-balanced trees and low for well-balanced trees We can bound the amortized cost of any zig-zig or zig-zag operation by

amortized cost = cost + P(tf) - P(ti) le 3(rankf(x) - ranki(x))

where x is the node being moved towards the root and the subscripts f and i indicate after and before the operation respectively When summed over the entire splay operation this telescopes to 3(rank(root)) which is O(log n) Since theres at most one zig operation this only adds a constant

Dynamic Finger Theorem The cost of performing S is O(m+n log n + sum mi=1 log( |Ij+1 ndash Ij + 1 ))

8 Explain the following in the context of files

A) Sequential Files - True random access file handling however only accesses the file at the point at which the data should be read or written rather than having to process it sequentially A hybrid approach is also possible whereby a part of the file is used for sequential access to locate something in the random access portion of the file in much the same way that a File Allocation Table (FAT) worksThe three main functions that this article will deal with are

rewind() ndash return the file pointer to the beginning fseek() ndash position the file pointer ftell() ndash return the current offset of the file pointer

Each of these functions operates on the C file pointer which is just the offset from the start of the file and can be positioned at will All readwrite operations take place at the current position of the file pointer The rewind() Function The rewind() function can be used in sequential or random access C file programming and simply tells the file system to position the file pointer at the start of the file Any error flags will also be cleared and no value is returned While useful the companion function fseek() can also be used to reposition the file pointer at will including the same behavior as rewind() Using fseek() and ftell() to Process Files

18

The fseek() function is most useful in random access files where either the record (or block) size is known or there is an allocation system that denotes the start and end positions of records in an index portion of the file The fseek() function takes three parameters

FILE f ndash the file pointer long offset ndash the position offset int origin ndash the point from which the offset is applied

B) Inverted Files - The inverted index data structure is a central component of a typical search engine indexing algorithm A goal of a search engine implementation is to optimize the speed of the query find the documents where word X occurs Once a forward index is developed which stores lists of words per document it is next inverted to develop an inverted index Querying the forward index would require sequential iteration through each document and to each word to verify a matching document The time memory and processing resources to perform such a query are not always technically realistic Instead of listing the words per document in the forward index the inverted index data structure is developed which lists the documents per word

With the inverted index created the query can now be resolved by jumping to the word id (via random access) in the inverted index

In pre-computer times concordances to important books were manually assembled These were effectively inverted indexes with a small amount of accompanying commentary that required a tremendous amount of effort to produce

There are two main variants of inverted indexes A record level inverted index (or inverted file index or just inverted file) contains a list of references to documents for each word A word level inverted index (or full inverted index or inverted list) additionally contains the positions of each word within a document The latter form offers more functionality (like phrase searches) but needs more time and space to be created

19

  • Ans- Stack operations-
Page 12: SEM_2_MC0068_ Data Structures Using C

recursive definition is a binary tree is either empty (represented by a null pointer) or is made

of a single node where the left and right pointers (recursive definition ahead) each point to a

binary tree

C) Almost Complete Binary Trees - All leafs at lowest and next-tolowest levels onlyAll

except the lowest level is fullNo gaps except at the end of a level A perfectly balanced tree with

leaves at the last level all in the leftmost position A tree which can be represented

without any vacant space in the array representation

3 With the help of a program and an example explain Breadth First Tree

Traversal

Ans- Certain programming problems are easier to solve using multiple data structures

For example testing a sequence of characters to determine if it is a palindrome (ie reads the same forward and backward like radar) can be accomplished easily with one stack and one queue The solution is to enter the sequence of characters into both data structures then remove letters from each data structure one at a time and compare them making sure that the letters match

In this palindrome example the user (person writing the main program) has access to both data structures to solve the problem Another way that 2 data structures can be used in concert is to use one data structure to help implement another

treeh treec------ ------ include treeh include queueh

typedef char treeElementT typedef struct treeNodeTag treeElementT element struct treeNodeTag left right treeNodeT

typedef struct treeCDT typedef struct treeCDT treeADT treeNodeT root treeCDT

4 Write a program to perform a binary search on an unsorted list of n integers

Ans-

Program Example-

includeltstdiohgt

includeltconiohgt

12

includeltmathhgt

int main()

int a[20]= 0

int n i j temp

int beg end mid target

printf( enter the total integers you want to enter (make it less

then 20)n)

scanf(d ampn)

if (n gt= 20) return 0

printf( enter the integer array elementsn )

for(i = 0 i lt n i++)

scanf(d ampa[i])

for(i = 0 i lt n-1 i++)

for(j = 0 j lt n-i-1 j++)

if (a[j+1] lt a[j])

temp = a[j]

a[j] = a[j+1]

a[j+1] = temp

13

printf( the sorted numbers are)

for(i = 0 i lt n i++)

printf(d a[i])

beg = ampa[0]

end = ampa[n]

mid = beg += n2

printf(n enter the number to be searched)

scanf(damptarget)

while((beg lt= end) ampamp (mid = target))

if (target lt mid)

end = mid ndash 1

n = n2

mid = beg += n2

else

beg = mid + 1

n = n2

mid = beg += n2

14

if (mid == target)

printf(n d found target)

else

printf(n d not found target)

getchar()

getchar()

return 0

5 With the help of a numerical example explain the working of Insertion Sort

Ans- When sorting an array with insertion sort we conceptually separate it into two parts

The list of elements already inserted which is always in sorted order and is found at the

beginning of the arrayThe list of elements we have yet to insert following

In outline our primary function looks like thisltltinsertion_sortgtgt=void insertion_sort(int a[] int length) int i for (i=0 i lt length i++) insert a[i] into sorted sublist

To insert each element we need to create a hole in the array at the place where the element

belongs then place the element in that hole We can combine the creation of the hole with the

searching for the place by starting at the end and shifting each element up by one until we find

15

the place where the element belongs This overwrites the element were inserting so we have

to save it in a variable firstltltinsert a[i] into sorted sublistgtgt=int j v = a[i]

for (j = i - 1 j gt= 0 j--) if (a[j] lt= v) break a[j + 1] = a[j]

a[j + 1] = v

6 Describe Depth First search algorithm and analyze its complexity

Ans- Formally DFS is an uninformed search that progresses by expanding the first child node of the search tree that appears and thus going deeper and deeper until a goal node is found or until it hits a node that has no children Then the search backtracks returning to the most recent node it hasnt finished exploring In a non-recursive implementation all freshly expanded nodes are added to a stack for exploration

The time and space analysis of DFS differs according to its application area In theoretical computer science DFS is typically used to traverse an entire graph and takes time O(|V| + |E|) linear in the size of the graph In these applications it also uses space O(|V|) in the worst case to store the stack of vertices on the current search path as well as the set of already-visited vertices Thus in this setting the time and space bounds are the same as for breadth first search and the choice of which of these two algorithms to use depends less on their complexity and more on the different properties of the vertex orderings the two algorithms produce

a depth-first search starting at A assuming that the left edges in the shown graph are chosen before right edges and assuming the search remembers previously-visited nodes and will not repeat them (since this is a small graph) will visit the nodes in the following order A B D F E C G

Performing the same search without remembering previously visited nodes results in visiting nodes in the order A B D F E A B D F E etc forever caught in the A B D F E cycle and never reaching C or G

16

7 Explain the following theorems of Splay trees

A) Working Set Theorem - A splay tree is a self-adjusting binary search tree with the additional property that recently accessed elements are quick to access again It performs basic operations such as insertion look-up and removal in O(log n) amortized time For many sequences of operations splay trees perform better than other search trees even when the specific pattern of the sequence is unknown

All normal operations on a binary search tree are combined with one basic operation called splaying Splaying the tree for a certain element rearranges the tree so that the element is placed at the root of the tree One way to do this is to first perform a standard binary tree search for the element in question and then use tree rotations in a specific fashion to bring the element to the top Alternatively a top-down algorithm can combine the search and the tree reorganization into a single phase

When a node x is accessed a splay operation is performed on x to move it to the root To perform a splay operation we carry out a sequence of splay steps each of which moves x closer to the root By performing a splay operation on the node of interest after every access the recently accessed nodes are kept near the root and the tree remains roughly balanced so that we achieve the desired amortized time bounds

B) Sequential Access Theorem - When a node x is accessed a splay operation is

performed on x to move it to the root To perform a splay operation we carry out a

sequence of splay steps each of which moves x closer to the root By performing a splay

operation on the node of interest after every access the recently accessed nodes are kept

near the root and the tree remains roughly balanced so that we achieve the desired

amortized time boundsEach particular step depends on three factors

Whether x is the left or right child of its parent node p

whether p is the root or not and if not

whether p is the left or right child of its parent g (the grandparent of x)

The three types of splay steps are

Zig Step This step is done when p is the root The tree is rotated on the edge between x

and p Zig steps exist to deal with the parity issue and will be done only as the last step in

a splay operation and only when x has odd depth at the beginning of the operation

Zig-zig Step This step is done when p is not the root and x and p are either both right

children or are both left children The picture below shows the case where x and p are both

left children The tree is rotated on the edge joining p with its parent g then rotated on the

17

edge joining x with p Note that zig-zig steps are the only thing that differentiate splay

trees from the rotate to root method introduced by Allen and Munro prior to the

introduction of splay trees

Zig-zag Step This step is done when p is not the root and x is a right child and p is a left

child or vice versa The tree is rotated on the edge between x and p then rotated on the

edge between x and its new parent g

C) Dynamic Finger Theorem - A simple amortized analysis of static splay trees can be carried out using the potential method Suppose that size(r) is the number of nodes in the subtree rooted at r (including r) and rank(r) = log2(size(r)) Then the potential function P(t) for a splay tree t is the sum of the ranks of all the nodes in the tree This will tend to be high for poorly-balanced trees and low for well-balanced trees We can bound the amortized cost of any zig-zig or zig-zag operation by

amortized cost = cost + P(tf) - P(ti) le 3(rankf(x) - ranki(x))

where x is the node being moved towards the root and the subscripts f and i indicate after and before the operation respectively When summed over the entire splay operation this telescopes to 3(rank(root)) which is O(log n) Since theres at most one zig operation this only adds a constant

Dynamic Finger Theorem The cost of performing S is O(m+n log n + sum mi=1 log( |Ij+1 ndash Ij + 1 ))

8 Explain the following in the context of files

A) Sequential Files - True random access file handling however only accesses the file at the point at which the data should be read or written rather than having to process it sequentially A hybrid approach is also possible whereby a part of the file is used for sequential access to locate something in the random access portion of the file in much the same way that a File Allocation Table (FAT) worksThe three main functions that this article will deal with are

rewind() ndash return the file pointer to the beginning fseek() ndash position the file pointer ftell() ndash return the current offset of the file pointer

Each of these functions operates on the C file pointer which is just the offset from the start of the file and can be positioned at will All readwrite operations take place at the current position of the file pointer The rewind() Function The rewind() function can be used in sequential or random access C file programming and simply tells the file system to position the file pointer at the start of the file Any error flags will also be cleared and no value is returned While useful the companion function fseek() can also be used to reposition the file pointer at will including the same behavior as rewind() Using fseek() and ftell() to Process Files

18

The fseek() function is most useful in random access files where either the record (or block) size is known or there is an allocation system that denotes the start and end positions of records in an index portion of the file The fseek() function takes three parameters

FILE f ndash the file pointer long offset ndash the position offset int origin ndash the point from which the offset is applied

B) Inverted Files - The inverted index data structure is a central component of a typical search engine indexing algorithm A goal of a search engine implementation is to optimize the speed of the query find the documents where word X occurs Once a forward index is developed which stores lists of words per document it is next inverted to develop an inverted index Querying the forward index would require sequential iteration through each document and to each word to verify a matching document The time memory and processing resources to perform such a query are not always technically realistic Instead of listing the words per document in the forward index the inverted index data structure is developed which lists the documents per word

With the inverted index created the query can now be resolved by jumping to the word id (via random access) in the inverted index

In pre-computer times concordances to important books were manually assembled These were effectively inverted indexes with a small amount of accompanying commentary that required a tremendous amount of effort to produce

There are two main variants of inverted indexes A record level inverted index (or inverted file index or just inverted file) contains a list of references to documents for each word A word level inverted index (or full inverted index or inverted list) additionally contains the positions of each word within a document The latter form offers more functionality (like phrase searches) but needs more time and space to be created

19

  • Ans- Stack operations-
Page 13: SEM_2_MC0068_ Data Structures Using C

includeltmathhgt

int main()

int a[20]= 0

int n i j temp

int beg end mid target

printf( enter the total integers you want to enter (make it less

then 20)n)

scanf(d ampn)

if (n gt= 20) return 0

printf( enter the integer array elementsn )

for(i = 0 i lt n i++)

scanf(d ampa[i])

for(i = 0 i lt n-1 i++)

for(j = 0 j lt n-i-1 j++)

if (a[j+1] lt a[j])

temp = a[j]

a[j] = a[j+1]

a[j+1] = temp

13

printf( the sorted numbers are)

for(i = 0 i lt n i++)

printf(d a[i])

beg = ampa[0]

end = ampa[n]

mid = beg += n2

printf(n enter the number to be searched)

scanf(damptarget)

while((beg lt= end) ampamp (mid = target))

if (target lt mid)

end = mid ndash 1

n = n2

mid = beg += n2

else

beg = mid + 1

n = n2

mid = beg += n2

14

if (mid == target)

printf(n d found target)

else

printf(n d not found target)

getchar()

getchar()

return 0

5 With the help of a numerical example explain the working of Insertion Sort

Ans- When sorting an array with insertion sort we conceptually separate it into two parts

The list of elements already inserted which is always in sorted order and is found at the

beginning of the arrayThe list of elements we have yet to insert following

In outline our primary function looks like thisltltinsertion_sortgtgt=void insertion_sort(int a[] int length) int i for (i=0 i lt length i++) insert a[i] into sorted sublist

To insert each element we need to create a hole in the array at the place where the element

belongs then place the element in that hole We can combine the creation of the hole with the

searching for the place by starting at the end and shifting each element up by one until we find

15

the place where the element belongs This overwrites the element were inserting so we have

to save it in a variable firstltltinsert a[i] into sorted sublistgtgt=int j v = a[i]

for (j = i - 1 j gt= 0 j--) if (a[j] lt= v) break a[j + 1] = a[j]

a[j + 1] = v

6 Describe Depth First search algorithm and analyze its complexity

Ans- Formally DFS is an uninformed search that progresses by expanding the first child node of the search tree that appears and thus going deeper and deeper until a goal node is found or until it hits a node that has no children Then the search backtracks returning to the most recent node it hasnt finished exploring In a non-recursive implementation all freshly expanded nodes are added to a stack for exploration

The time and space analysis of DFS differs according to its application area In theoretical computer science DFS is typically used to traverse an entire graph and takes time O(|V| + |E|) linear in the size of the graph In these applications it also uses space O(|V|) in the worst case to store the stack of vertices on the current search path as well as the set of already-visited vertices Thus in this setting the time and space bounds are the same as for breadth first search and the choice of which of these two algorithms to use depends less on their complexity and more on the different properties of the vertex orderings the two algorithms produce

a depth-first search starting at A assuming that the left edges in the shown graph are chosen before right edges and assuming the search remembers previously-visited nodes and will not repeat them (since this is a small graph) will visit the nodes in the following order A B D F E C G

Performing the same search without remembering previously visited nodes results in visiting nodes in the order A B D F E A B D F E etc forever caught in the A B D F E cycle and never reaching C or G

16

7 Explain the following theorems of Splay trees

A) Working Set Theorem - A splay tree is a self-adjusting binary search tree with the additional property that recently accessed elements are quick to access again It performs basic operations such as insertion look-up and removal in O(log n) amortized time For many sequences of operations splay trees perform better than other search trees even when the specific pattern of the sequence is unknown

All normal operations on a binary search tree are combined with one basic operation called splaying Splaying the tree for a certain element rearranges the tree so that the element is placed at the root of the tree One way to do this is to first perform a standard binary tree search for the element in question and then use tree rotations in a specific fashion to bring the element to the top Alternatively a top-down algorithm can combine the search and the tree reorganization into a single phase

When a node x is accessed a splay operation is performed on x to move it to the root To perform a splay operation we carry out a sequence of splay steps each of which moves x closer to the root By performing a splay operation on the node of interest after every access the recently accessed nodes are kept near the root and the tree remains roughly balanced so that we achieve the desired amortized time bounds

B) Sequential Access Theorem - When a node x is accessed a splay operation is

performed on x to move it to the root To perform a splay operation we carry out a

sequence of splay steps each of which moves x closer to the root By performing a splay

operation on the node of interest after every access the recently accessed nodes are kept

near the root and the tree remains roughly balanced so that we achieve the desired

amortized time boundsEach particular step depends on three factors

Whether x is the left or right child of its parent node p

whether p is the root or not and if not

whether p is the left or right child of its parent g (the grandparent of x)

The three types of splay steps are

Zig Step This step is done when p is the root The tree is rotated on the edge between x

and p Zig steps exist to deal with the parity issue and will be done only as the last step in

a splay operation and only when x has odd depth at the beginning of the operation

Zig-zig Step This step is done when p is not the root and x and p are either both right

children or are both left children The picture below shows the case where x and p are both

left children The tree is rotated on the edge joining p with its parent g then rotated on the

17

edge joining x with p Note that zig-zig steps are the only thing that differentiate splay

trees from the rotate to root method introduced by Allen and Munro prior to the

introduction of splay trees

Zig-zag Step This step is done when p is not the root and x is a right child and p is a left

child or vice versa The tree is rotated on the edge between x and p then rotated on the

edge between x and its new parent g

C) Dynamic Finger Theorem - A simple amortized analysis of static splay trees can be carried out using the potential method Suppose that size(r) is the number of nodes in the subtree rooted at r (including r) and rank(r) = log2(size(r)) Then the potential function P(t) for a splay tree t is the sum of the ranks of all the nodes in the tree This will tend to be high for poorly-balanced trees and low for well-balanced trees We can bound the amortized cost of any zig-zig or zig-zag operation by

amortized cost = cost + P(tf) - P(ti) le 3(rankf(x) - ranki(x))

where x is the node being moved towards the root and the subscripts f and i indicate after and before the operation respectively When summed over the entire splay operation this telescopes to 3(rank(root)) which is O(log n) Since theres at most one zig operation this only adds a constant

Dynamic Finger Theorem The cost of performing S is O(m+n log n + sum mi=1 log( |Ij+1 ndash Ij + 1 ))

8 Explain the following in the context of files

A) Sequential Files - True random access file handling however only accesses the file at the point at which the data should be read or written rather than having to process it sequentially A hybrid approach is also possible whereby a part of the file is used for sequential access to locate something in the random access portion of the file in much the same way that a File Allocation Table (FAT) worksThe three main functions that this article will deal with are

rewind() ndash return the file pointer to the beginning fseek() ndash position the file pointer ftell() ndash return the current offset of the file pointer

Each of these functions operates on the C file pointer which is just the offset from the start of the file and can be positioned at will All readwrite operations take place at the current position of the file pointer The rewind() Function The rewind() function can be used in sequential or random access C file programming and simply tells the file system to position the file pointer at the start of the file Any error flags will also be cleared and no value is returned While useful the companion function fseek() can also be used to reposition the file pointer at will including the same behavior as rewind() Using fseek() and ftell() to Process Files

18

The fseek() function is most useful in random access files where either the record (or block) size is known or there is an allocation system that denotes the start and end positions of records in an index portion of the file The fseek() function takes three parameters

FILE f ndash the file pointer long offset ndash the position offset int origin ndash the point from which the offset is applied

B) Inverted Files - The inverted index data structure is a central component of a typical search engine indexing algorithm A goal of a search engine implementation is to optimize the speed of the query find the documents where word X occurs Once a forward index is developed which stores lists of words per document it is next inverted to develop an inverted index Querying the forward index would require sequential iteration through each document and to each word to verify a matching document The time memory and processing resources to perform such a query are not always technically realistic Instead of listing the words per document in the forward index the inverted index data structure is developed which lists the documents per word

With the inverted index created the query can now be resolved by jumping to the word id (via random access) in the inverted index

In pre-computer times concordances to important books were manually assembled These were effectively inverted indexes with a small amount of accompanying commentary that required a tremendous amount of effort to produce

There are two main variants of inverted indexes A record level inverted index (or inverted file index or just inverted file) contains a list of references to documents for each word A word level inverted index (or full inverted index or inverted list) additionally contains the positions of each word within a document The latter form offers more functionality (like phrase searches) but needs more time and space to be created

19

  • Ans- Stack operations-
Page 14: SEM_2_MC0068_ Data Structures Using C

printf( the sorted numbers are)

for(i = 0 i lt n i++)

printf(d a[i])

beg = ampa[0]

end = ampa[n]

mid = beg += n2

printf(n enter the number to be searched)

scanf(damptarget)

while((beg lt= end) ampamp (mid = target))

if (target lt mid)

end = mid ndash 1

n = n2

mid = beg += n2

else

beg = mid + 1

n = n2

mid = beg += n2

14

if (mid == target)

printf(n d found target)

else

printf(n d not found target)

getchar()

getchar()

return 0

5 With the help of a numerical example explain the working of Insertion Sort

Ans- When sorting an array with insertion sort we conceptually separate it into two parts

The list of elements already inserted which is always in sorted order and is found at the

beginning of the arrayThe list of elements we have yet to insert following

In outline our primary function looks like thisltltinsertion_sortgtgt=void insertion_sort(int a[] int length) int i for (i=0 i lt length i++) insert a[i] into sorted sublist

To insert each element we need to create a hole in the array at the place where the element

belongs then place the element in that hole We can combine the creation of the hole with the

searching for the place by starting at the end and shifting each element up by one until we find

15

the place where the element belongs This overwrites the element were inserting so we have

to save it in a variable firstltltinsert a[i] into sorted sublistgtgt=int j v = a[i]

for (j = i - 1 j gt= 0 j--) if (a[j] lt= v) break a[j + 1] = a[j]

a[j + 1] = v

6 Describe Depth First search algorithm and analyze its complexity

Ans- Formally DFS is an uninformed search that progresses by expanding the first child node of the search tree that appears and thus going deeper and deeper until a goal node is found or until it hits a node that has no children Then the search backtracks returning to the most recent node it hasnt finished exploring In a non-recursive implementation all freshly expanded nodes are added to a stack for exploration

The time and space analysis of DFS differs according to its application area In theoretical computer science DFS is typically used to traverse an entire graph and takes time O(|V| + |E|) linear in the size of the graph In these applications it also uses space O(|V|) in the worst case to store the stack of vertices on the current search path as well as the set of already-visited vertices Thus in this setting the time and space bounds are the same as for breadth first search and the choice of which of these two algorithms to use depends less on their complexity and more on the different properties of the vertex orderings the two algorithms produce

a depth-first search starting at A assuming that the left edges in the shown graph are chosen before right edges and assuming the search remembers previously-visited nodes and will not repeat them (since this is a small graph) will visit the nodes in the following order A B D F E C G

Performing the same search without remembering previously visited nodes results in visiting nodes in the order A B D F E A B D F E etc forever caught in the A B D F E cycle and never reaching C or G

16

7 Explain the following theorems of Splay trees

A) Working Set Theorem - A splay tree is a self-adjusting binary search tree with the additional property that recently accessed elements are quick to access again It performs basic operations such as insertion look-up and removal in O(log n) amortized time For many sequences of operations splay trees perform better than other search trees even when the specific pattern of the sequence is unknown

All normal operations on a binary search tree are combined with one basic operation called splaying Splaying the tree for a certain element rearranges the tree so that the element is placed at the root of the tree One way to do this is to first perform a standard binary tree search for the element in question and then use tree rotations in a specific fashion to bring the element to the top Alternatively a top-down algorithm can combine the search and the tree reorganization into a single phase

When a node x is accessed a splay operation is performed on x to move it to the root To perform a splay operation we carry out a sequence of splay steps each of which moves x closer to the root By performing a splay operation on the node of interest after every access the recently accessed nodes are kept near the root and the tree remains roughly balanced so that we achieve the desired amortized time bounds

B) Sequential Access Theorem - When a node x is accessed a splay operation is

performed on x to move it to the root To perform a splay operation we carry out a

sequence of splay steps each of which moves x closer to the root By performing a splay

operation on the node of interest after every access the recently accessed nodes are kept

near the root and the tree remains roughly balanced so that we achieve the desired

amortized time boundsEach particular step depends on three factors

Whether x is the left or right child of its parent node p

whether p is the root or not and if not

whether p is the left or right child of its parent g (the grandparent of x)

The three types of splay steps are

Zig Step This step is done when p is the root The tree is rotated on the edge between x

and p Zig steps exist to deal with the parity issue and will be done only as the last step in

a splay operation and only when x has odd depth at the beginning of the operation

Zig-zig Step This step is done when p is not the root and x and p are either both right

children or are both left children The picture below shows the case where x and p are both

left children The tree is rotated on the edge joining p with its parent g then rotated on the

17

edge joining x with p Note that zig-zig steps are the only thing that differentiate splay

trees from the rotate to root method introduced by Allen and Munro prior to the

introduction of splay trees

Zig-zag Step This step is done when p is not the root and x is a right child and p is a left

child or vice versa The tree is rotated on the edge between x and p then rotated on the

edge between x and its new parent g

C) Dynamic Finger Theorem - A simple amortized analysis of static splay trees can be carried out using the potential method Suppose that size(r) is the number of nodes in the subtree rooted at r (including r) and rank(r) = log2(size(r)) Then the potential function P(t) for a splay tree t is the sum of the ranks of all the nodes in the tree This will tend to be high for poorly-balanced trees and low for well-balanced trees We can bound the amortized cost of any zig-zig or zig-zag operation by

amortized cost = cost + P(tf) - P(ti) le 3(rankf(x) - ranki(x))

where x is the node being moved towards the root and the subscripts f and i indicate after and before the operation respectively When summed over the entire splay operation this telescopes to 3(rank(root)) which is O(log n) Since theres at most one zig operation this only adds a constant

Dynamic Finger Theorem The cost of performing S is O(m+n log n + sum mi=1 log( |Ij+1 ndash Ij + 1 ))

8 Explain the following in the context of files

A) Sequential Files - True random access file handling however only accesses the file at the point at which the data should be read or written rather than having to process it sequentially A hybrid approach is also possible whereby a part of the file is used for sequential access to locate something in the random access portion of the file in much the same way that a File Allocation Table (FAT) worksThe three main functions that this article will deal with are

rewind() ndash return the file pointer to the beginning fseek() ndash position the file pointer ftell() ndash return the current offset of the file pointer

Each of these functions operates on the C file pointer which is just the offset from the start of the file and can be positioned at will All readwrite operations take place at the current position of the file pointer The rewind() Function The rewind() function can be used in sequential or random access C file programming and simply tells the file system to position the file pointer at the start of the file Any error flags will also be cleared and no value is returned While useful the companion function fseek() can also be used to reposition the file pointer at will including the same behavior as rewind() Using fseek() and ftell() to Process Files

18

The fseek() function is most useful in random access files where either the record (or block) size is known or there is an allocation system that denotes the start and end positions of records in an index portion of the file The fseek() function takes three parameters

FILE f ndash the file pointer long offset ndash the position offset int origin ndash the point from which the offset is applied

B) Inverted Files - The inverted index data structure is a central component of a typical search engine indexing algorithm A goal of a search engine implementation is to optimize the speed of the query find the documents where word X occurs Once a forward index is developed which stores lists of words per document it is next inverted to develop an inverted index Querying the forward index would require sequential iteration through each document and to each word to verify a matching document The time memory and processing resources to perform such a query are not always technically realistic Instead of listing the words per document in the forward index the inverted index data structure is developed which lists the documents per word

With the inverted index created the query can now be resolved by jumping to the word id (via random access) in the inverted index

In pre-computer times concordances to important books were manually assembled These were effectively inverted indexes with a small amount of accompanying commentary that required a tremendous amount of effort to produce

There are two main variants of inverted indexes A record level inverted index (or inverted file index or just inverted file) contains a list of references to documents for each word A word level inverted index (or full inverted index or inverted list) additionally contains the positions of each word within a document The latter form offers more functionality (like phrase searches) but needs more time and space to be created

19

  • Ans- Stack operations-
Page 15: SEM_2_MC0068_ Data Structures Using C

if (mid == target)

printf(n d found target)

else

printf(n d not found target)

getchar()

getchar()

return 0

5 With the help of a numerical example explain the working of Insertion Sort

Ans- When sorting an array with insertion sort we conceptually separate it into two parts

The list of elements already inserted which is always in sorted order and is found at the

beginning of the arrayThe list of elements we have yet to insert following

In outline our primary function looks like thisltltinsertion_sortgtgt=void insertion_sort(int a[] int length) int i for (i=0 i lt length i++) insert a[i] into sorted sublist

To insert each element we need to create a hole in the array at the place where the element

belongs then place the element in that hole We can combine the creation of the hole with the

searching for the place by starting at the end and shifting each element up by one until we find

15

the place where the element belongs This overwrites the element were inserting so we have

to save it in a variable firstltltinsert a[i] into sorted sublistgtgt=int j v = a[i]

for (j = i - 1 j gt= 0 j--) if (a[j] lt= v) break a[j + 1] = a[j]

a[j + 1] = v

6 Describe Depth First search algorithm and analyze its complexity

Ans- Formally DFS is an uninformed search that progresses by expanding the first child node of the search tree that appears and thus going deeper and deeper until a goal node is found or until it hits a node that has no children Then the search backtracks returning to the most recent node it hasnt finished exploring In a non-recursive implementation all freshly expanded nodes are added to a stack for exploration

The time and space analysis of DFS differs according to its application area In theoretical computer science DFS is typically used to traverse an entire graph and takes time O(|V| + |E|) linear in the size of the graph In these applications it also uses space O(|V|) in the worst case to store the stack of vertices on the current search path as well as the set of already-visited vertices Thus in this setting the time and space bounds are the same as for breadth first search and the choice of which of these two algorithms to use depends less on their complexity and more on the different properties of the vertex orderings the two algorithms produce

a depth-first search starting at A assuming that the left edges in the shown graph are chosen before right edges and assuming the search remembers previously-visited nodes and will not repeat them (since this is a small graph) will visit the nodes in the following order A B D F E C G

Performing the same search without remembering previously visited nodes results in visiting nodes in the order A B D F E A B D F E etc forever caught in the A B D F E cycle and never reaching C or G

16

7 Explain the following theorems of Splay trees

A) Working Set Theorem - A splay tree is a self-adjusting binary search tree with the additional property that recently accessed elements are quick to access again It performs basic operations such as insertion look-up and removal in O(log n) amortized time For many sequences of operations splay trees perform better than other search trees even when the specific pattern of the sequence is unknown

All normal operations on a binary search tree are combined with one basic operation called splaying Splaying the tree for a certain element rearranges the tree so that the element is placed at the root of the tree One way to do this is to first perform a standard binary tree search for the element in question and then use tree rotations in a specific fashion to bring the element to the top Alternatively a top-down algorithm can combine the search and the tree reorganization into a single phase

When a node x is accessed a splay operation is performed on x to move it to the root To perform a splay operation we carry out a sequence of splay steps each of which moves x closer to the root By performing a splay operation on the node of interest after every access the recently accessed nodes are kept near the root and the tree remains roughly balanced so that we achieve the desired amortized time bounds

B) Sequential Access Theorem - When a node x is accessed a splay operation is

performed on x to move it to the root To perform a splay operation we carry out a

sequence of splay steps each of which moves x closer to the root By performing a splay

operation on the node of interest after every access the recently accessed nodes are kept

near the root and the tree remains roughly balanced so that we achieve the desired

amortized time boundsEach particular step depends on three factors

Whether x is the left or right child of its parent node p

whether p is the root or not and if not

whether p is the left or right child of its parent g (the grandparent of x)

The three types of splay steps are

Zig Step This step is done when p is the root The tree is rotated on the edge between x

and p Zig steps exist to deal with the parity issue and will be done only as the last step in

a splay operation and only when x has odd depth at the beginning of the operation

Zig-zig Step This step is done when p is not the root and x and p are either both right

children or are both left children The picture below shows the case where x and p are both

left children The tree is rotated on the edge joining p with its parent g then rotated on the

17

edge joining x with p Note that zig-zig steps are the only thing that differentiate splay

trees from the rotate to root method introduced by Allen and Munro prior to the

introduction of splay trees

Zig-zag Step This step is done when p is not the root and x is a right child and p is a left

child or vice versa The tree is rotated on the edge between x and p then rotated on the

edge between x and its new parent g

C) Dynamic Finger Theorem - A simple amortized analysis of static splay trees can be carried out using the potential method Suppose that size(r) is the number of nodes in the subtree rooted at r (including r) and rank(r) = log2(size(r)) Then the potential function P(t) for a splay tree t is the sum of the ranks of all the nodes in the tree This will tend to be high for poorly-balanced trees and low for well-balanced trees We can bound the amortized cost of any zig-zig or zig-zag operation by

amortized cost = cost + P(tf) - P(ti) le 3(rankf(x) - ranki(x))

where x is the node being moved towards the root and the subscripts f and i indicate after and before the operation respectively When summed over the entire splay operation this telescopes to 3(rank(root)) which is O(log n) Since theres at most one zig operation this only adds a constant

Dynamic Finger Theorem The cost of performing S is O(m+n log n + sum mi=1 log( |Ij+1 ndash Ij + 1 ))

8 Explain the following in the context of files

A) Sequential Files - True random access file handling however only accesses the file at the point at which the data should be read or written rather than having to process it sequentially A hybrid approach is also possible whereby a part of the file is used for sequential access to locate something in the random access portion of the file in much the same way that a File Allocation Table (FAT) worksThe three main functions that this article will deal with are

rewind() ndash return the file pointer to the beginning fseek() ndash position the file pointer ftell() ndash return the current offset of the file pointer

Each of these functions operates on the C file pointer which is just the offset from the start of the file and can be positioned at will All readwrite operations take place at the current position of the file pointer The rewind() Function The rewind() function can be used in sequential or random access C file programming and simply tells the file system to position the file pointer at the start of the file Any error flags will also be cleared and no value is returned While useful the companion function fseek() can also be used to reposition the file pointer at will including the same behavior as rewind() Using fseek() and ftell() to Process Files

18

The fseek() function is most useful in random access files where either the record (or block) size is known or there is an allocation system that denotes the start and end positions of records in an index portion of the file The fseek() function takes three parameters

FILE f ndash the file pointer long offset ndash the position offset int origin ndash the point from which the offset is applied

B) Inverted Files - The inverted index data structure is a central component of a typical search engine indexing algorithm A goal of a search engine implementation is to optimize the speed of the query find the documents where word X occurs Once a forward index is developed which stores lists of words per document it is next inverted to develop an inverted index Querying the forward index would require sequential iteration through each document and to each word to verify a matching document The time memory and processing resources to perform such a query are not always technically realistic Instead of listing the words per document in the forward index the inverted index data structure is developed which lists the documents per word

With the inverted index created the query can now be resolved by jumping to the word id (via random access) in the inverted index

In pre-computer times concordances to important books were manually assembled These were effectively inverted indexes with a small amount of accompanying commentary that required a tremendous amount of effort to produce

There are two main variants of inverted indexes A record level inverted index (or inverted file index or just inverted file) contains a list of references to documents for each word A word level inverted index (or full inverted index or inverted list) additionally contains the positions of each word within a document The latter form offers more functionality (like phrase searches) but needs more time and space to be created

19

  • Ans- Stack operations-
Page 16: SEM_2_MC0068_ Data Structures Using C

the place where the element belongs This overwrites the element were inserting so we have

to save it in a variable firstltltinsert a[i] into sorted sublistgtgt=int j v = a[i]

for (j = i - 1 j gt= 0 j--) if (a[j] lt= v) break a[j + 1] = a[j]

a[j + 1] = v

6 Describe Depth First search algorithm and analyze its complexity

Ans- Formally DFS is an uninformed search that progresses by expanding the first child node of the search tree that appears and thus going deeper and deeper until a goal node is found or until it hits a node that has no children Then the search backtracks returning to the most recent node it hasnt finished exploring In a non-recursive implementation all freshly expanded nodes are added to a stack for exploration

The time and space analysis of DFS differs according to its application area In theoretical computer science DFS is typically used to traverse an entire graph and takes time O(|V| + |E|) linear in the size of the graph In these applications it also uses space O(|V|) in the worst case to store the stack of vertices on the current search path as well as the set of already-visited vertices Thus in this setting the time and space bounds are the same as for breadth first search and the choice of which of these two algorithms to use depends less on their complexity and more on the different properties of the vertex orderings the two algorithms produce

a depth-first search starting at A assuming that the left edges in the shown graph are chosen before right edges and assuming the search remembers previously-visited nodes and will not repeat them (since this is a small graph) will visit the nodes in the following order A B D F E C G

Performing the same search without remembering previously visited nodes results in visiting nodes in the order A B D F E A B D F E etc forever caught in the A B D F E cycle and never reaching C or G

16

7 Explain the following theorems of Splay trees

A) Working Set Theorem - A splay tree is a self-adjusting binary search tree with the additional property that recently accessed elements are quick to access again It performs basic operations such as insertion look-up and removal in O(log n) amortized time For many sequences of operations splay trees perform better than other search trees even when the specific pattern of the sequence is unknown

All normal operations on a binary search tree are combined with one basic operation called splaying Splaying the tree for a certain element rearranges the tree so that the element is placed at the root of the tree One way to do this is to first perform a standard binary tree search for the element in question and then use tree rotations in a specific fashion to bring the element to the top Alternatively a top-down algorithm can combine the search and the tree reorganization into a single phase

When a node x is accessed a splay operation is performed on x to move it to the root To perform a splay operation we carry out a sequence of splay steps each of which moves x closer to the root By performing a splay operation on the node of interest after every access the recently accessed nodes are kept near the root and the tree remains roughly balanced so that we achieve the desired amortized time bounds

B) Sequential Access Theorem - When a node x is accessed a splay operation is

performed on x to move it to the root To perform a splay operation we carry out a

sequence of splay steps each of which moves x closer to the root By performing a splay

operation on the node of interest after every access the recently accessed nodes are kept

near the root and the tree remains roughly balanced so that we achieve the desired

amortized time boundsEach particular step depends on three factors

Whether x is the left or right child of its parent node p

whether p is the root or not and if not

whether p is the left or right child of its parent g (the grandparent of x)

The three types of splay steps are

Zig Step This step is done when p is the root The tree is rotated on the edge between x

and p Zig steps exist to deal with the parity issue and will be done only as the last step in

a splay operation and only when x has odd depth at the beginning of the operation

Zig-zig Step This step is done when p is not the root and x and p are either both right

children or are both left children The picture below shows the case where x and p are both

left children The tree is rotated on the edge joining p with its parent g then rotated on the

17

edge joining x with p Note that zig-zig steps are the only thing that differentiate splay

trees from the rotate to root method introduced by Allen and Munro prior to the

introduction of splay trees

Zig-zag Step This step is done when p is not the root and x is a right child and p is a left

child or vice versa The tree is rotated on the edge between x and p then rotated on the

edge between x and its new parent g

C) Dynamic Finger Theorem - A simple amortized analysis of static splay trees can be carried out using the potential method Suppose that size(r) is the number of nodes in the subtree rooted at r (including r) and rank(r) = log2(size(r)) Then the potential function P(t) for a splay tree t is the sum of the ranks of all the nodes in the tree This will tend to be high for poorly-balanced trees and low for well-balanced trees We can bound the amortized cost of any zig-zig or zig-zag operation by

amortized cost = cost + P(tf) - P(ti) le 3(rankf(x) - ranki(x))

where x is the node being moved towards the root and the subscripts f and i indicate after and before the operation respectively When summed over the entire splay operation this telescopes to 3(rank(root)) which is O(log n) Since theres at most one zig operation this only adds a constant

Dynamic Finger Theorem The cost of performing S is O(m+n log n + sum mi=1 log( |Ij+1 ndash Ij + 1 ))

8 Explain the following in the context of files

A) Sequential Files - True random access file handling however only accesses the file at the point at which the data should be read or written rather than having to process it sequentially A hybrid approach is also possible whereby a part of the file is used for sequential access to locate something in the random access portion of the file in much the same way that a File Allocation Table (FAT) worksThe three main functions that this article will deal with are

rewind() ndash return the file pointer to the beginning fseek() ndash position the file pointer ftell() ndash return the current offset of the file pointer

Each of these functions operates on the C file pointer which is just the offset from the start of the file and can be positioned at will All readwrite operations take place at the current position of the file pointer The rewind() Function The rewind() function can be used in sequential or random access C file programming and simply tells the file system to position the file pointer at the start of the file Any error flags will also be cleared and no value is returned While useful the companion function fseek() can also be used to reposition the file pointer at will including the same behavior as rewind() Using fseek() and ftell() to Process Files

18

The fseek() function is most useful in random access files where either the record (or block) size is known or there is an allocation system that denotes the start and end positions of records in an index portion of the file The fseek() function takes three parameters

FILE f ndash the file pointer long offset ndash the position offset int origin ndash the point from which the offset is applied

B) Inverted Files - The inverted index data structure is a central component of a typical search engine indexing algorithm A goal of a search engine implementation is to optimize the speed of the query find the documents where word X occurs Once a forward index is developed which stores lists of words per document it is next inverted to develop an inverted index Querying the forward index would require sequential iteration through each document and to each word to verify a matching document The time memory and processing resources to perform such a query are not always technically realistic Instead of listing the words per document in the forward index the inverted index data structure is developed which lists the documents per word

With the inverted index created the query can now be resolved by jumping to the word id (via random access) in the inverted index

In pre-computer times concordances to important books were manually assembled These were effectively inverted indexes with a small amount of accompanying commentary that required a tremendous amount of effort to produce

There are two main variants of inverted indexes A record level inverted index (or inverted file index or just inverted file) contains a list of references to documents for each word A word level inverted index (or full inverted index or inverted list) additionally contains the positions of each word within a document The latter form offers more functionality (like phrase searches) but needs more time and space to be created

19

  • Ans- Stack operations-
Page 17: SEM_2_MC0068_ Data Structures Using C

7 Explain the following theorems of Splay trees

A) Working Set Theorem - A splay tree is a self-adjusting binary search tree with the additional property that recently accessed elements are quick to access again It performs basic operations such as insertion look-up and removal in O(log n) amortized time For many sequences of operations splay trees perform better than other search trees even when the specific pattern of the sequence is unknown

All normal operations on a binary search tree are combined with one basic operation called splaying Splaying the tree for a certain element rearranges the tree so that the element is placed at the root of the tree One way to do this is to first perform a standard binary tree search for the element in question and then use tree rotations in a specific fashion to bring the element to the top Alternatively a top-down algorithm can combine the search and the tree reorganization into a single phase

When a node x is accessed a splay operation is performed on x to move it to the root To perform a splay operation we carry out a sequence of splay steps each of which moves x closer to the root By performing a splay operation on the node of interest after every access the recently accessed nodes are kept near the root and the tree remains roughly balanced so that we achieve the desired amortized time bounds

B) Sequential Access Theorem - When a node x is accessed a splay operation is

performed on x to move it to the root To perform a splay operation we carry out a

sequence of splay steps each of which moves x closer to the root By performing a splay

operation on the node of interest after every access the recently accessed nodes are kept

near the root and the tree remains roughly balanced so that we achieve the desired

amortized time boundsEach particular step depends on three factors

Whether x is the left or right child of its parent node p

whether p is the root or not and if not

whether p is the left or right child of its parent g (the grandparent of x)

The three types of splay steps are

Zig Step This step is done when p is the root The tree is rotated on the edge between x

and p Zig steps exist to deal with the parity issue and will be done only as the last step in

a splay operation and only when x has odd depth at the beginning of the operation

Zig-zig Step This step is done when p is not the root and x and p are either both right

children or are both left children The picture below shows the case where x and p are both

left children The tree is rotated on the edge joining p with its parent g then rotated on the

17

edge joining x with p Note that zig-zig steps are the only thing that differentiate splay

trees from the rotate to root method introduced by Allen and Munro prior to the

introduction of splay trees

Zig-zag Step This step is done when p is not the root and x is a right child and p is a left

child or vice versa The tree is rotated on the edge between x and p then rotated on the

edge between x and its new parent g

C) Dynamic Finger Theorem - A simple amortized analysis of static splay trees can be carried out using the potential method Suppose that size(r) is the number of nodes in the subtree rooted at r (including r) and rank(r) = log2(size(r)) Then the potential function P(t) for a splay tree t is the sum of the ranks of all the nodes in the tree This will tend to be high for poorly-balanced trees and low for well-balanced trees We can bound the amortized cost of any zig-zig or zig-zag operation by

amortized cost = cost + P(tf) - P(ti) le 3(rankf(x) - ranki(x))

where x is the node being moved towards the root and the subscripts f and i indicate after and before the operation respectively When summed over the entire splay operation this telescopes to 3(rank(root)) which is O(log n) Since theres at most one zig operation this only adds a constant

Dynamic Finger Theorem The cost of performing S is O(m+n log n + sum mi=1 log( |Ij+1 ndash Ij + 1 ))

8 Explain the following in the context of files

A) Sequential Files - True random access file handling however only accesses the file at the point at which the data should be read or written rather than having to process it sequentially A hybrid approach is also possible whereby a part of the file is used for sequential access to locate something in the random access portion of the file in much the same way that a File Allocation Table (FAT) worksThe three main functions that this article will deal with are

rewind() ndash return the file pointer to the beginning fseek() ndash position the file pointer ftell() ndash return the current offset of the file pointer

Each of these functions operates on the C file pointer which is just the offset from the start of the file and can be positioned at will All readwrite operations take place at the current position of the file pointer The rewind() Function The rewind() function can be used in sequential or random access C file programming and simply tells the file system to position the file pointer at the start of the file Any error flags will also be cleared and no value is returned While useful the companion function fseek() can also be used to reposition the file pointer at will including the same behavior as rewind() Using fseek() and ftell() to Process Files

18

The fseek() function is most useful in random access files where either the record (or block) size is known or there is an allocation system that denotes the start and end positions of records in an index portion of the file The fseek() function takes three parameters

FILE f ndash the file pointer long offset ndash the position offset int origin ndash the point from which the offset is applied

B) Inverted Files - The inverted index data structure is a central component of a typical search engine indexing algorithm A goal of a search engine implementation is to optimize the speed of the query find the documents where word X occurs Once a forward index is developed which stores lists of words per document it is next inverted to develop an inverted index Querying the forward index would require sequential iteration through each document and to each word to verify a matching document The time memory and processing resources to perform such a query are not always technically realistic Instead of listing the words per document in the forward index the inverted index data structure is developed which lists the documents per word

With the inverted index created the query can now be resolved by jumping to the word id (via random access) in the inverted index

In pre-computer times concordances to important books were manually assembled These were effectively inverted indexes with a small amount of accompanying commentary that required a tremendous amount of effort to produce

There are two main variants of inverted indexes A record level inverted index (or inverted file index or just inverted file) contains a list of references to documents for each word A word level inverted index (or full inverted index or inverted list) additionally contains the positions of each word within a document The latter form offers more functionality (like phrase searches) but needs more time and space to be created

19

  • Ans- Stack operations-
Page 18: SEM_2_MC0068_ Data Structures Using C

edge joining x with p Note that zig-zig steps are the only thing that differentiate splay

trees from the rotate to root method introduced by Allen and Munro prior to the

introduction of splay trees

Zig-zag Step This step is done when p is not the root and x is a right child and p is a left

child or vice versa The tree is rotated on the edge between x and p then rotated on the

edge between x and its new parent g

C) Dynamic Finger Theorem - A simple amortized analysis of static splay trees can be carried out using the potential method Suppose that size(r) is the number of nodes in the subtree rooted at r (including r) and rank(r) = log2(size(r)) Then the potential function P(t) for a splay tree t is the sum of the ranks of all the nodes in the tree This will tend to be high for poorly-balanced trees and low for well-balanced trees We can bound the amortized cost of any zig-zig or zig-zag operation by

amortized cost = cost + P(tf) - P(ti) le 3(rankf(x) - ranki(x))

where x is the node being moved towards the root and the subscripts f and i indicate after and before the operation respectively When summed over the entire splay operation this telescopes to 3(rank(root)) which is O(log n) Since theres at most one zig operation this only adds a constant

Dynamic Finger Theorem The cost of performing S is O(m+n log n + sum mi=1 log( |Ij+1 ndash Ij + 1 ))

8 Explain the following in the context of files

A) Sequential Files - True random access file handling however only accesses the file at the point at which the data should be read or written rather than having to process it sequentially A hybrid approach is also possible whereby a part of the file is used for sequential access to locate something in the random access portion of the file in much the same way that a File Allocation Table (FAT) worksThe three main functions that this article will deal with are

rewind() ndash return the file pointer to the beginning fseek() ndash position the file pointer ftell() ndash return the current offset of the file pointer

Each of these functions operates on the C file pointer which is just the offset from the start of the file and can be positioned at will All readwrite operations take place at the current position of the file pointer The rewind() Function The rewind() function can be used in sequential or random access C file programming and simply tells the file system to position the file pointer at the start of the file Any error flags will also be cleared and no value is returned While useful the companion function fseek() can also be used to reposition the file pointer at will including the same behavior as rewind() Using fseek() and ftell() to Process Files

18

The fseek() function is most useful in random access files where either the record (or block) size is known or there is an allocation system that denotes the start and end positions of records in an index portion of the file The fseek() function takes three parameters

FILE f ndash the file pointer long offset ndash the position offset int origin ndash the point from which the offset is applied

B) Inverted Files - The inverted index data structure is a central component of a typical search engine indexing algorithm A goal of a search engine implementation is to optimize the speed of the query find the documents where word X occurs Once a forward index is developed which stores lists of words per document it is next inverted to develop an inverted index Querying the forward index would require sequential iteration through each document and to each word to verify a matching document The time memory and processing resources to perform such a query are not always technically realistic Instead of listing the words per document in the forward index the inverted index data structure is developed which lists the documents per word

With the inverted index created the query can now be resolved by jumping to the word id (via random access) in the inverted index

In pre-computer times concordances to important books were manually assembled These were effectively inverted indexes with a small amount of accompanying commentary that required a tremendous amount of effort to produce

There are two main variants of inverted indexes A record level inverted index (or inverted file index or just inverted file) contains a list of references to documents for each word A word level inverted index (or full inverted index or inverted list) additionally contains the positions of each word within a document The latter form offers more functionality (like phrase searches) but needs more time and space to be created

19

  • Ans- Stack operations-
Page 19: SEM_2_MC0068_ Data Structures Using C

The fseek() function is most useful in random access files where either the record (or block) size is known or there is an allocation system that denotes the start and end positions of records in an index portion of the file The fseek() function takes three parameters

FILE f ndash the file pointer long offset ndash the position offset int origin ndash the point from which the offset is applied

B) Inverted Files - The inverted index data structure is a central component of a typical search engine indexing algorithm A goal of a search engine implementation is to optimize the speed of the query find the documents where word X occurs Once a forward index is developed which stores lists of words per document it is next inverted to develop an inverted index Querying the forward index would require sequential iteration through each document and to each word to verify a matching document The time memory and processing resources to perform such a query are not always technically realistic Instead of listing the words per document in the forward index the inverted index data structure is developed which lists the documents per word

With the inverted index created the query can now be resolved by jumping to the word id (via random access) in the inverted index

In pre-computer times concordances to important books were manually assembled These were effectively inverted indexes with a small amount of accompanying commentary that required a tremendous amount of effort to produce

There are two main variants of inverted indexes A record level inverted index (or inverted file index or just inverted file) contains a list of references to documents for each word A word level inverted index (or full inverted index or inverted list) additionally contains the positions of each word within a document The latter form offers more functionality (like phrase searches) but needs more time and space to be created

19

  • Ans- Stack operations-