Algorithms and Data Structure
Algorithms and Data Structure
Algorithms and Data Structure
Bhavana Sangamnerkar
M.Sc. (Comp. Prog.), PGDCA
H.O.D.
Revised by: Neha jain
Revised by: Ms Rashmi Sharma
Information Technology
Biyani Girls College, Jaipur
Published by :
Think Tanks
Biyani Group of Colleges
ISBN : 978-93-81254-40-0
Edition : 2011
Price :
While every effort is taken to avoid errors or omissions in this Publication, any
mistake or omission that may have crept in is not intentional. It may be taken note of
that neither the publisher nor the author will be responsible for any damage or loss of
any kind arising to anyone in any manner on account of such errors and omissions.
Preface
am glad to present this book, especially designed to serve the needs of the
students. The book has been written keeping in mind the general weakness in
understanding the fundamental concepts of the topics. The book is self-explanatory
and adopts the Teach Yourself style. It is based on question-answer pattern. The
language of book is quite easy and understandable based on scientific approach.
Any further improvement in the contents of the book by making corrections,
omission and inclusion is keen to be achieved based on suggestions from the
readers for which the author shall be obliged.
I acknowledge special thanks to Mr. Rajeev Biyani, Chairman & Dr. Sanjay
Biyani, Director (Acad.) Biyani Group of Colleges, who are the backbones and main
concept provider and also have been constant source of motivation throughout this
Endeavour. They played an active role in coordinating the various stages of this
Endeavour and spearheaded the publishing work.
I look forward to receiving valuable suggestions from professors of various
educational institutions, other faculty members and students for improvement of the
quality of the book. The reader may feel free to send in their comments and
suggestions to the under mentioned address.
Author
Syllabus
B.C.A. Part-I
Content
S.No.
1.
Name of Topic
Basics of Algorithms
2.
3.
Arrays
4.
Strings
5.
6.
Linked List
7.
Stacks
8.
Queue
9.
10.
Graph
11.
12.
13.
Tree
Unsolved Papers 2011 to 2006
MCQ
Chapter-1
Basics of Algorithms
Q.1.
(2)
(3)
(4)
Q.2.
Ans.: Consider the following three examples. What do they all have in common?
How to change your motor oil
(1)
Place the oil pan underneath the oil plug of your car.
(2)
(3)
Drain oil.
(4)
(5)
(6)
(7)
solving the problem. Through the use of algorithms, we can make computers
"intelligent" by programming them with various algorithms to solve
problems. Because of their speed and accuracy, computers are well-suited for
solving tedious problems such as searching for a name in a large telephone
directory or adding a long column of numbers. However, the usefulness of
computers as problem solving machines is limited because the solutions to
some problems cannot be stated in an algorithm.
Much of the study of computer science is dedicated to discovering efficient
algorithms and representing them so that they can be understood by
computers.
An informal definition of an algorithm is "a set of instructions for solving a
problem" and we illustrated this definition with a recipe, and instructions for
changing the oil in a car engine. You also created your own algorithm for
putting letters and numbers in order. While these simple algorithms are fine
for us, they are much too ambiguous for a computer. In order for an algorithm
to be applicable to a computer, it must have certain characteristics. We will
specify these characteristics in our formal definition of an algorithm.
An algorithm is a well-ordered collection of unambiguous and effectively
computable operations that when executed produces a result and halts in a
finite amount of time [Schneider and Gersting 1995].
With this definition, we can identify five important characteristics of
algorithms :
Algorithms are well-ordered.
Algorithms have unambiguous operations.
Algorithms have effectively computable operations.
Algorithms produce a result.
Algorithms halt in a finite amount of time.
When writing algorithms, we have several choices of how we will specify the
operations in our algorithm. One option is to write the algorithm using plain
English. Although plain English may seem like a good way to write an
algorithm, it has some problems that make it a poor choice. First, plain English
is too wordy. When we write in plain English, we must include many words
10
each other. We can easily see the advantage of this organization by comparing
the structured English algorithm with the plain English algorithm.
How to change your motor oil
Plain English
First, place the oil pan underneath
the oil plug of your car. Next,
unscrew the oil plug and drain the
oil. Now, replace the oil plug. Once
the old oil is drained, remove the oil
cap from the engine and pour in 4
quarts of oil. Finally, replace the oil
cap on the engine.
Structured English
1.
Place
the
oil
pan
underneath the oil plug
of your car.
2.
3.
Drain oil.
4.
5.
6.
7.
For the remainder of this study, we will write our algorithms using the
structured English approach.
Q.4.
11
12
2n2+3n is θ(n2).
2n3+3n is not θ(n2).
Asymptotically Tight Upper Bound : Big-Oh "O"-Notation :
Definition : Let f(n) and g(n) be real-valued functions of a single nonnegative integer argument. We write f(n) = O(g(n)) if there exist a
positive real-valued constant c and a positive integer n0 such that :
0 f(n) c g(n) for all n n0 .
In other words, for large inputs (asymptotically) f(n) is below
c g(n) :
13
Definition : Let f(n) and g(n) be real-valued functions of a single nonnegative integer argument. We write f(n) = (g(n)) if there exist a
positive real-valued constant c and a positive integer n0 such that :
0 c g(n) f(n) for all n n0 .
In other words : For large inputs (asymptotically) f(n) is above
c g(n) .
Note :
We have f(n) = (g(n)) iff (if and only if)
f(n) = O(g(n)) and f(n) = (g(n)).
In other words :
If f(n) is Θ(g(n)), the f(n) is Ω(g(n)).
If f(n) is Θ(g(n)), then f(n) is O(g(n)).
Example :
2n3+3n is Ω(n3).
Asymptotically Non-Tight Upper Bound : Little-oh "o"-Notation :
Definition : Let f(n) and g(n) be real-valued functions of a single nonnegative integer argument. We write f(n) = o(g(n)) if for any positive
real-valued constant c exists a positive integer n0 such
that :
0 f(n) c g(n) for all n n0 .
In other words, the inequality holds for all constants c.
For any constant c we can come up with large enough inputs n so that
f(n) is below c g(n).
g(n) grows a lot faster than f(n) : f(n)/g(n)0 as n.
Example :
log(n) is o(n)
Asymptotically Non-Tight Lower Bound: Little-Omega "" Notation
14
Definition : Let f(n) and g(n) be real-valued functions of a single nonnegative integer argument. We write f(n) = (g(n)) if for any positive
real-valued constant c exists a positive integer n0 such
that :
0 c g(n) f(n) for all n n0 .
As an alternative definition we can say the following :
Definition : Let f(n) and g(n) be real valued functions of an integer
variable. We say f(n) is (g(n)) if g(n) is o(f(n)). This is pronounced as
"f(n) is little-omega of g(n)".
f(n) grows a lot faster than f(n) : f(n)/g(n) as n.
Example :
n2 is (nlog(n)).
Q.6.
15
16
17
What is Pseudo Code? Explain how can we use Pseudo Code to design a
Program?
Ans.: Pseudo code is a short hand way of describing a computer program. Rather
than use the specific syntax of a computer language, more general wording is
used. Using pseudocode, it is easier for a non-programmer to understand the
general workings of the program.
Pseudo code (pronounced SOO-doh-kohd) is a detailed yet readable
description of what a computer program or algorithm must do, expressed in a
18
2.
(ii)
19
20
Chapter-2
Ans.: Data Types : The type of a data object in C determines the range and kind of
values an object can represent, the size of machine storage reserved for an
object, and the operations allowed on an object. Functions also have types, and
the function's return type and parameter types can be specified in the
function's declaration
Data Sizes : An object of a given data type is stored in a section of memory
having a discreet size. Objects of different data types require different
amounts of memory. Following table shows the size and range of the basic
data types.
Sizes and Ranges of Data Types :
Type
Size
Range
16 bits
-32768 to 32767
16 bits
0 to 65535
32 bits
-2147483648 to 2147483647
unsigned int
32 bits
0 to 4294967295
32 bits
- 2147483648 to 2147483647
64 bits
- 9223372036854775808 to
9223372036854775807
Integral Types :
21
32 bits
0 to 4294967295
64 bits
0 to 18446744073709551615
64 bits
-9223372036854775808 to
9223372036854775807
64 bits
0 to 18446744073709551615
Type
Size
Range
8 bits
-128 to 127
unsigned char
8 bits
0 to 255
wchar_t
32 bits
0 to 4294967295
32 bits
double
64 bits
128 bits
Same as
double
Same as double
22
concrete implementation is kept entirely private, and indeed can change, for
example to incorporate efficiency improvements over time. The idea is that
such changes are not supposed to have any impact on client code, since they
involve no difference in the abstract behaviour.
For example, one could define an abstract data type called lookup table, where
keys are uniquely associated with values, and values may be retrieved by
specifying their corresponding keys. Such a lookup table may be implemented
in various ways: as a hash table, a binary search tree, or even a simple linear
list. As far as client code is concerned, the abstract properties of the type are
the same in each case.
Of course, this all relies on getting the details of the interface right in the first
place, since any changes there can have major impacts on client code. Another
way to look at this is that the interface forms a contract on agreed behaviour
between the data type and client code; anything not spelled out in the contract
is subject to change without notice.
Languages that implement data abstraction include Ada and Modula-2.
Object-oriented languages are commonly claimed to offer data abstraction;
however, their inheritance concept tends to put information in the interface
that more properly belongs in the implementation; thus, changes to such
information ends up impacting client code, leading directly to the Fragile
binary interface problem.
Abstract Data Types :
23
Encapsulation :
Encapsulation is a grouping of subprograms and the data that
they manipulate.
An encapsulation provides an abstracted system and a logical
organization for a collection of related computations.
They are often placed in libraries and made available for reuse in
programs other than those for which they are written.
24
Program units that use a specific abstract data type are called
clients of that type.
A benefit of information hiding is increased reliability.? This is
because clients cannot change the underlying representations of
objects directly, either intentionally or by accident, thus
increasing the integrity of the object
Design Issues :
A facility for defining abstract data types in a language must
provide a syntactic unit that can encapsulate the type definition
and subprogram definitions of the abstraction operations.
Concurrent Pascal, Smalltalk, C++, and Java directly support
abstract data types.
Some design issues beyond encapsulation are whether the kinds
of types that can be abstract should be restricted, whether
abstract data types can be parameterized, and what access
controls are provided, and how such controls are specified.
Language Examples :
C++
o
25
26
Chapter-3
Arrays
Q.1.
Ans.: 1)
Q.2.
2)
3)
4)
5)
Ans.: The amount of memory an array can consume depends on the data type of an
array. In DOS environment, the amount of memory an array can consume
depends on the current memory model (i.e. Tiny, Small, Large, Huge, etc.). In
general an array cannot consume more than 64 kb. Consider following
program, which shows the maximum number of elements an array of type int,
float and char can have in case of Small memory model.
main( )
{
int i[32767] ;
float f[16383] ;
char s[65535] ;
}
Q.3.
27
Ans.: Declaring Arrays : Arrays are declared with the bracket punctuators [ ], as
shown in the following syntax :
storage-class-specifier(opt) type-specifier declarator [constant-expression-list(opt)];
28
int second_function(void)
{
.
.
.
}
The array size specifier may only be omitted from the first pair of
brackets in a multidimensional array declaration. This is because an
array's elements must have complete types, even if the array itself has
an incomplete type.
If the declaration of the array includes initializers, you can omit the size
of the array, as in the following example :
char array_one[] = "Shemps";
char array_two[] = { 'S', 'h', 'e', 'm', 'p', 's', '\0' };
The two definitions initialize variables with identical elements. These
arrays have seven elements: six characters and the null character (\0),
which terminates all character strings. The size of the array is
determined from the number of characters in the initializing characterstring constant or initialization list. Initializing an incomplete array
completes the array type. An array is completed at the end of its
initializer list.
If you use the array as a function parameter, the array must be defined
in the calling function. However, the declaration of the parameter in the
called function can omit the constant expression within the brackets.
The address of the first element of the array is passed. Subscripted
references in the called function can modify elements of the array. The
following example shows how to use an array in this manner :
main()
{
/* Initialize array
static char arg_str[] = "Thomas";
*/
29
int sum;
sum = adder(arg_str); /* Pass address of first array element */
.
.
.
}
/* adder adds ASCII values of letters in array
*/
*/
*/
30
int *x;
int x[10];
Note that the specified size of the array does not matter in the case of a
function parameter, since the pointer always points to only the first
element of the array.
C supports arrays declared as an array of arrays. These are sometimes
called multidimensional arrays. Consider the following example, where
variable table_one is a two-dimensional array containing 20 integers :
int table_one[10][2];
Arrays are stored in row-major order, which means the
element table_one[0][0] (in the previous example) immediately
precedes table_one[0][1], which in turn immediately precedes
table_one[1][0] .
Q.4.
/* error
*/
String literals are often assigned to a char or wchar_t array. In this case, each
character of the string represents one member of a one-dimensional array, and
the array is terminated with the null character. When an array is initialized by
31
a pointer to a string literal, the string literal cannot be modified through the
pointer.
When initializing an array with a string literal, use quotation marks around
the initializing string. For example :
char string[26] = { "This is a string literal." };
/* The braces above are optional here */
The terminating null character is appended to the end of the string if the size
permits, as it does in this case. Another form for initializing an array with
characters is the following :
char string[12] = {'T', 'h', 'i', 's', ' ', 'w', 'a', 'y' };
The preceding example creates a one-dimensional array containing the string
value "This way ". The characters in this array can be freely modified.
Remaining uninitialized array members will be automatically initialized to
zero.
If the size of the array used for a string literal is not explicitly stated, its size is
determined by the number of characters in the string (including the
terminating null character). If the size of the array is explicitly stated,
initializing the array with a string literal longer than the array is an error.
Note : There is one special case where the null character is not automatically
appended to the array. This case is when the array size is explicitly specified
and the number of initializers completely fills the array size. For example :
char c[4] = "abcd";
Here, the array c holds only the four specified characters, a , b , c , and d . No
null character terminates the array.
Using the following rules, you can omit braces when initializing the members
of a multidimensional arrays:
When initializing arrays, you can omit the outermost pair of braces.
If the initializer list includes all of the initializers for the object being
initialized, you can omit the inner braces.
32
Ans.: Pointers and Arrays : Data objects in an array can be referenced through
pointers instead of using array subscripts. The data type of such a pointer is
referred to as "pointer to array of type". The array name itself behaves like a
33
int *p = x;
int a, b;
a = *(x + 3);
b = x[3];
{
*y = *(x + 4);
}
34
recordName
recordMembers
instanceName1
Defines a record. recordName is the name of the record, and is also used as an
object command. This object command is used to create instances of the record
definition. recordMembers are the members of the record that make up the
record definition. These are variables and other record. If optional
instanceName args are given, then an instance is generated after the definition
is created for each instanceName.
record show record
Returns a list of records that have been defined.
record show instances recordName
Returns the instances that have been instantiated by recordName.
record show members recordName
35
Returns the members that are defined for record recordName. It returns the
same format as how the records were defined.
record show values instanceName
Returns a list of values that are set for the instance instanceName. The output is
a list of key/value pairs. If there are nested records, then the values of the
nested records will itself be a list.
record exists record recordName
Tests for the existence of a record with the name recordName.
record exists instance instanceName
Tests for the existence of a instance with the name instanceName.
record delete record recordName
Deletes recordName, and all instances of recordName. It will return an error if
the record does not exist.
record delete instance instanceName
Deletes instance with the name of instanceName. It will return an error if the
instance does not exist.
Record Members : Record members can either be variables, or other records,
However, the same record can not be nested witin itself (circular). To define a
nested record, you need to specify the record keyword, along the with name of
the record, and the name of the instance of that nested record. For example, it
would look like this :
# this is the nested record
record define mynestedrecord {
nest1
nest2
}
# This is the main record
record define myrecord {
mem1
36
mem2
{record mynestedrecord mem3}
}
37
Chapter-4
Strings
Q.1.
Ans.: A major difference is: string will have static storage duration, whereas as a
character array will not, unless it is explicitly specified by using the static
keyword.
Actually, a string is a character array with following properties :
The multi-byte character sequence, to which we generally call string, is
used to initialize an array of static storage duration. The size of this
array is just sufficient to contain these characters plus the terminating
NULL character.
It not specified what happens if this array, i.e., string, is modified.
So the value of a string is the sequence of the values of the contained
characters, in order.
38
Q.3.
Ans.: (1)
(2)
Q.4.
Ans.: The function realloc(ptr,n) uses two arguments.the first argument ptr is a
pointer to a block of memory for which the size is to be altered. The second
argument n specifies the new size. The size may be increased or decreased. If n
is greater than the old size and if sufficient space is not available subsequent to
the old region, the function realloc( ) may create a new region and all the old
data are moved to the new region.
Q.5
Ans.: malloc allocates memory for object in heap but doesn't invoke object's
constructor to initiallize the object.
new allocates memory and also invokes constructor to initialize the object.
malloc() and free() do not support object semantics
Does not construct and destruct objects
string * ptr = (string *)(malloc (sizeof(string)))
Are not safe
Does not calculate the size of the objects that it construct
39
Ans.: The free subroutine frees a block of memory previously allocated by the
malloc subroutine. Undefined results occur if the Pointer parameter is not a
valid pointer. If the Pointer parameter is a null value, no action will occur. The
realloc subroutine changes the size of the block of memory pointed to by the
Pointer parameter to the number of bytes specified by the Size parameter and
returns a new pointer to the block. The pointer specified by the Pointer
parameter must have been created with the malloc, calloc, or realloc
subroutines and not been deallocated with the free or realloc subroutines.
Undefined results occur if the Pointer parameter is not a valid pointer.
Q.8.
Ans.: Both the malloc() and the calloc() functions are used to allocate dynamic
memory. Each operates slightly different from the other. malloc() takes a size
and returns a pointer to a chunk of memory at least that big:
40
Ans.1: 1.)
new and delete are preprocessors while malloc() and free() are
functions. [we dont use brackets will calling new or delete].
2.)
3.)
new will initlize the new memory to 0 but malloc() gives random
value in the new alloted memory location [better to use calloc()]
Ans.2: new()
allocates
continous
space
malloc() allocates distributed space.
for
the
object
instace
new() is castless, meaning that allocates memory for this specific type,
malloc(), calloc() allocate space for void * that is cated to the specific class type
pointer.
41
Q.10. String Processing --- Write out a function that prints out all the
permutations of a String. For example, abc would give you abc, acb, bac, bca,
cab, cba.
Ans.: void PrintPermu (char *sBegin, char* sRest) {
int iLoop;
char cTmp;
char cFLetter[1];
char *sNewBegin;
char *sCur;
int iLen;
static int iCount;
iLen = strlen(sRest);
if (iLen == 2) {
iCount++;
printf("%d: %s%s\n",iCount,sBegin,sRest);
iCount++;
printf("%d: %s%c%c\n",iCount,sBegin,sRest[1],sRest[0]);
return;
} else if (iLen == 1) {
iCount++;
printf("%d: %s%s\n", iCount, sBegin, sRest);
return;
} else {
// swap the first character of sRest with each of
// the remaining chars recursively call debug print
sCur = (char*)malloc(iLen);
42
sNewBegin = (char*)malloc(iLen);
for (iLoop = 0; iLoop < iLen; iLoop ++) {
strcpy(sCur, sRest);
strcpy(sNewBegin, sBegin);
cTmp = sCur[iLoop];
sCur[iLoop] = sCur[0];
sCur[0] = cTmp;
sprintf(cFLetter, "%c", sCur[0]);
strcat(sNewBegin, cFLetter);
debugprint(sNewBegin, sCur+1);
}
}
}
void main() {
char s[255];
char sIn[255];
printf("\nEnter a string:");
scanf("%s%*c",sIn);
memset(s,0,255);
PrintPermu(s, sIn);
Q.11.
What is the difference between a string copy (strcpy) and a memory copy (memcpy)?
When should each be used?
Ans.: The strcpy() function is designed to work exclusively with strings. It copies
each byte of the source string to the destination string and stops when the
terminating null character () has been moved. On the other hand, the
memcpy() function is designed to work with any type of data. Because not all
data ends with a null character, you must provide the memcpy() function with
the number of bytes you want to copy from the source to the destination.
43
Purpose
atof()
atoi()
atol()
strtod()
strtol()
strtoul()
Purpose
itoa()
ltoa()
ultoa()
Purpose
ecvt()
44
fcvt()
gcvt()
Q.14. Write a Program to interchange two variables without using the third one.
Ans.: a=7;
b=2;
a = a + b;
b = a - b;
a = a - b;
Q.15. How will you define String Processing along with the different String
Operations?
Ans.: String Processing (Storing Strings and String Operations) : In C, a string is
stored as a null-terminated char array. This means that after the last truly
usable char there is a null, hex 00, which is represented in C by '\0'. The
subscripts used for the array start with zero (0). The following line declares a
char array called str. C provides fifteen consecutive bytes of memory. Only the
first fourteen bytes are usable for character storage, because one must be used
for the string-terminating null.
char str[15];
The following is a representation of what would be in RAM, if the string
"Hello, world!" is stored in this array.
Characters: H e l l o ,
w o r l d !
Hex values: 48 65 6C 6C 6F 2C 20 77 6F 71 6C 64 21 00
Subscripts: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
The name of the array is treated as a pointer to the array. The subscript serves
as the offset into the array, i.e., the number of bytes from the starting memory
location of the array. Thus, both of the following will save the address of the
0th character in the pointer variable ptr.
45
ptr = str;
ptr = &str[0];
strlen()
Syntax : len = strlen(ptr);
where len is an integer and ptr is a pointer to char
strlen() returns the length of a string, excluding the null. The following code
will result in len having the value 13.
int len;
char str[15];
strcpy(str, "Hello, world!");
len = strlen(str);
strcpy()
Syntax: strcpy(ptr1, ptr2);
where ptr1 and ptr2 are pointers to char
strcpy() is used to copy a null-terminated string into a variable. Given the
following declarations, several things are possible.
char S[25];
char D[25];
Putting text into a string:
strcpy(S, "This is String 1.");
Copying a whole string from S to D:
strcpy(D, S);
Copying the tail end of string S to D:
strcpy(D, &S[8]);
Strncpy()
Syntax: strncpy(ptr1, ptr2, n);
where n is an integer and ptr1 and ptr2 are pointers to char
46
47
strcat(D, S);
strncat()
Syntax: strncat(ptr1, ptr2, n);
where n is an integer and ptr1 and ptr2 are pointers to char
strncat() is used to concatenate a portion of a possibly null-terminated string
onto the end of another string variable. Care must be taken because some
earlier implementations of C do not append the '\0' at the end of destination
string. Given the following declarations, several things are possible, but only
one is commonly used.
char S[25] = "world!";
char D[25] = "Hello, ";
Concatenating five characters from the beginning of S onto the end of D
and placing a null at the end:
strncat(D, S, 5);
strncat(D, S, strlen(S) -1);
Both would result in D containing "Hello, world".
N.B. If you fail to ensure that the source string is null-terminated, very strange
and sometimes very ugly things may result.
strcmp()
Syntax : diff = strcmp(ptr1, ptr2);
where diff is an integer and ptr1 and ptr2 are pointers to char
strcmp() is used to compare two strings. The strings are compared character
by character starting at the characters pointed at by the two pointers. If the
strings are identical, the integer value zero (0) is returned. As soon as a
difference is found, the comparison is halted and if the ASCII value at the
point of difference in the first string is less than that in the second (e.g. 'a' 0x61
vs. 'e' 0x65) a negative value is returned; otherwise, a positive value is
returned. Examine the following examples.
char s1[25] = "pat";
char s2[25] = "pet";
48
diff will have a negative value after the following statement is executed.
diff = strcmp(s1, s2);
diff will have a positive value after the following statement is executed.
diff = strcmp(s2, s1);
diff will have a value of zero (0) after the execution of the following statement,
which compares s1 with itself.
diff = strcmp(s1, s1);
strncmp()
Syntax: diff = strncmp(ptr1, ptr2, n);
where diff and n are integers ptr1 and ptr2 are pointers to char
strncmp() is used to compare the first n characters of two strings. The strings
are compared character by character starting at the characters pointed at by
the two pointers. If the first n strings are identical, the integer value zero (0) is
returned. As soon as a difference is found, the comparison is halted and if the
ASCII value at the point of difference in the first string is less than that in the
second (e.g. 'a' 0x61 vs. 'e' 0x65) a negative value is returned; otherwise, a
positive value is returned. Examine the following examples.
char s1[25] = "pat";
char s2[25] = "pet";
diff will have a negative value after the following statement is executed.
diff = strncmp(s1, s2, 2);
diff will have a positive value after the following statement is executed.
diff = strncmp(s2, s1, 3);
diff will have a value of zero (0) after the following statement.
diff = strncmp(s1, s2, 1);
Q.16.
Ans.: Single characters can be replaced in a string. Given the following declarations,
several things are possible.
49
Ans.: In computer science, pattern matching is the act of checking for the presence
of the constituents of a given pattern. In contrast to pattern recognition, the
pattern is rigidly specified. Such a pattern concerns conventionally either
sequences or tree structures. Pattern matching is used to test whether things
have a desired structure, to find relevant structure, to retrieve the aligning
parts, and to substitute the matching part with something else. Sequence (or
specifically text string) patterns are often described using regular expressions
(i.e. backtracking) and matched using respective algorithms. Sequences can
also be seen as trees branching for each element into the respective element
and the rest of the sequence, or as trees that immediately branch into all
elements.
50
Chapter-5
What is C++?
Ans.:
C does not have a class/object concept.
C++ provides data abstraction, data encapsulation, Inheritance and
Polymorphism.
C++ supports all C syntax.
In C passing value to a function is "Call by Value" whereas in C++ its
"Call by Reference".
File extension is .c in C while .cpp in C++.(C++ compiler compiles the
files with .c extension but C compiler can not!).
51
What is an Object?
Ans.: Object is a software bundle of variables and related methods. Objects have
state and behavior.
Q.4.
What is a Class?
Ans.: Class is a user-defined data type in C++. It can be created to solve a particular
kind of problem. After creation the user need not know the specifics of the
working of a class.
Q.5.
Ans.: Structure : Initially (in C) a structure was used to bundle different type of data
types together to perform a particular functionality. But C++ extended the
structure to contain functions also. The major difference is that all declarations
inside a structure are by default public.
Class : Class is a successor of Structure. By default all the members inside the
class are private.
Q.6.
Ans.: Classes and objects are separate but related concepts. Every object belongs to a
class and every class contains one or more related objects.
A Class is static. All of the attributes of a class are fixed before, during,
and after the execution of a program. The attributes of a class don't change.
The class to which an object belongs is also (usually) static. If a
particular object belongs to a certain class at the time that it is created then it almost
certainly will still belong to that class right up until the time that it is destroyed.
52
An Object on the other hand has a limited lifespan. Objects are created
and eventually destroyed. Also during that lifetime, the attributes of the object may
undergo significant change.
Q.7.
Ans.: Friend classes are used when two or more classes are designed to work
together and need access to each other's implementation in ways that the rest
of the world shouldn't be allowed to have. In other words, they help keep
private things private. For instance, it may be desirable for class
DatabaseCursor to have more privilege to the internals of class Database than
main() has.
Virtual class is used for run time polymorphism when object is linked to
procedure call at run time. or is an inner class that can be overridden by
derived classes of the outer class.
Q.8.
What is the word you will use when defining a function in base class to
allow this function to be a Polymorphic Function?
Ans.: Virtual
Q.9.
Ans.: Encapsulation.
Q.10. What is Friend Function?
Ans.: As the name suggests, the function acts as a friend to a class. As a friend of a
class, it can access its private and protected members. A friend function is not
a member of the class. But it must be listed in the class definition.
Q.11. What is a Scope Resolution Operator?
Ans.: A scope resolution operator (::), can be used to define the member functions of
a class outside the class. Example of SRO
53
e.g.
.
.
{
int x = 10;
.
.
{
int x = 20;
..
.
}
.
}
The declaration of the inner block hides the declaration of same variable in outer
block. This means, within the inner block, the variable x will refer to the data object
declared therein. To access the global version of the variable, C++ provides scope
resolution operator.
54
Ans.: The idea behind inline functions is to insert the code of a called function at the
point where the function is called. If done carefully, this can improve the
application's performance in exchange for increased compile time and possibly
(but not always) an increase in the size of the generated binary executables.
Example:
template
<typename
The only difference between both prototypes is the use of keyword class or
typename, its use is indistinct since both expressions have exactly the same
meaning and behave exactly the same way.
Q.17. What is the difference between Declaration and Definition?
Ans.: The declaration tells the compiler that at some later point we plan to present
the definition of this declaration.
E.g.: void stars () //function declaration
55
The operators >> and << may be used for I/O operations because in the
header, they are overloaded.
2)
56
2)
57
58
Example :
public class SHAPE
{
public virtual void SHAPE::DRAW()=0;
}
Note here the function DRAW() is pure virtual which means the sub classes
must implement the DRAW() method and SHAPE cannot be instatiated
public class CIRCLE::public SHAPE
{
public void CIRCLE::DRAW()
{
// TODO drawing circle
}
}
public class SQUARE::public SHAPE
{
public void SQUARE::DRAW()
{
// TODO drawing square
}
}
now from the user class the calls would be like
globally
SHAPE *newShape;
When user action is to draw
public void MENU::OnClickDrawCircle(){
newShape = new CIRCLE();
}
public void MENU::OnClickDrawCircle(){
newShape = new SQUARE();
}
the when user actually draws
public void CANVAS::OnMouseOperations(){
newShape->DRAW();
}
Ans.3: class SHAPE{
public virtual Draw() = 0; //abstract class with a pure virtual method
};
class CIRCLE{
public int r;
public virtual Draw() { this->drawCircle(0,0,r); }
};
class SQURE
public int a;
59
60
61
You cannot directly access private data members when they are declared
(implicitly)
private:
MyPoint.x = 5; // Compiler will issue a compile ERROR
//Nor yoy can see them:
int x_dim = MyPoint.x; // Compiler will issue a compile ERROR
On the other hand, you can assign and read the public data members:
MyPoint.color = 255; // no problem
int col = MyPoint.color; // no problem
With protected data members you can read them but not write them:
MyPoint.pinned = true; // Compiler will issue a compile ERROR
bool isPinned = MyPoint.pinned; // no problem
Q.25. Write a Program that ask for user input from 5 to 9 then calculate the
average.
Ans.: #include "iostream.h"
int main() {
int MAX = 4;
int total = 0;
int average;
int numb;
for (int i=0; i<MAX; i++) {
cout << "Please enter your input between 5 and 9: ";
cin >> numb;
while ( numb<5 || numb>9) {
cout << "Invalid input, please re-enter: ";
cin >> numb;
}
62
63
Chapter-6
Linked List
Q.1.
64
}
i++;
}
Q.2.
Ans.: Unfortunately, the only way to search a linked list is with a linear search,
because the only way a linked lists members can be accessed is sequentially.
Sometimes it is quicker to take the data from a linked list and store it in a
different data structure so that searches can be more efficient.
Q.3.
Ans.: Static Memory Allocation : The compiler allocates the required memory space
for a declared variable. By using the address of operator, the reserved address
is obtained and this address may be assigned to a pointer variable. Since most
of the declared variables have static memory, this way of assigning pointer
value to a pointer variable is known as static memory allocation. Memory is
assigned during compilation time.
Dynamic Memory Allocation : It uses functions such as malloc( ) or calloc( )
to get memory dynamically. If these functions are used to get memory
dynamically and the values returned by these functions are assigned to
pointer variables, such assignments are known as dynamic memory allocation.
Memory is assigned during run time.
Q.4.
Ans.: Size of the final executable can be reduced using dynamic linking for libraries.
Q.5.
Ans.: There are times when its necessary to have a pointer that doesnt point to
anything. The macro NULL, defined in , has a value thats guaranteed to be
different from any valid pointer. NULL is a literal zero, possibly cast to void*
65
or char*. Some people, notably C++ programmers, prefer to use 0 rather than
NULL.
The null pointer is used in three ways :
Q.6
1)
2)
As an error value
3)
As a sentinel value
Why should we assign NULL to the elements (pointer) after freeing them?
Ans.: This is paranoia based on long experience. After a pointer has been freed, you
can no longer use the pointed-to data. The pointer is said to dangle; it doesnt
point at anything useful. If you NULL out or zero out a pointer immediately
after freeing it, your program can no longer get in trouble by using that
pointer. True, you might go indirect on the null pointer instead, but thats
something your debugger might be able to help you with immediately. Also,
there still might be copies of the pointer that refer to the memory that has been
deallocated; thats the nature of C. Zeroing out pointers after freeing them
wont solve all problems.
Q.7.
Ans.: NULL is defined as either 0 or (void*)0. These values are almost identical;
either a literal zero or a void pointer is converted automatically to any kind of
pointer, as necessary, whenever a pointer is needed (although the compiler
cant always tell when a pointer is needed).
Q.8.
66
Q.9.
Ans.: Both the merge sort and the radix sort are good sorting algorithms to use for
linked lists.
Q.10. Tell how to check whether a Linked List is circular?
Ans.: Create two pointers, and set both to the start of the list. Update each as follows
:
while (pointer1) {
pointer1 = pointer1->next;
pointer2 = pointer2->next;
if (pointer2) pointer2=pointer2->next;
if (pointer1 == pointer2) {
print ("circular");
}
}
If a list is circular, at some point pointer2 will wrap around and be either at the
item just before pointer1, or the item before that. Either way, its either 1 or 2
jumps until they meet.
67
Chapter-7
Stacks
Q.1.
What is Stack?
Ans.: A stack is a limited version of an array. New elements, or nodes as they are
often called, can be added to a stack and removed from a stack only from one
end. For this reason, a stack is referred to as a LIFO structure (Last-In FirstOut).
Stacks have many applications. For example, as processor executes a program,
when a function call is made, the called function must know how to return
back to the program, so the current address of program execution is pushed
onto a stack. Once the function is finished, the address that was saved is
removed from the stack, and execution of the program resumes. If a series of
function calls occur, the successive return values are pushed onto the stack in
LIFO order so that each function can return back to calling program. Stacks
support recursive function calls in the same manner as conventional non
recursive calls.
Stacks are also used by compilers in the process of evaluating expressions and
generating machine language code. They are also used to store return
addresses in a chain of method calls during execution of a program.
Q.2.
Ans.: Stack Declaration Using an Array : Suppose elements of the stack are of type
int and the stack can store a maximum of 10 elements.
#define MAX 10
68
typedef struct
{
int top;
int elements[MAX];
}stack;
stack s;
Here we have defined our own data type named stack.
The first element top will be used to index the topmost element
Array elements holds the elements of the stack
The last line declares a variable s of type stack
Representation of Stack in Memory :
Q.3.
Ans.1: Operations : An abstract data type (ADT) consists of a data structure and a set
of primitive operations. The main primitives of a stack are known
as :
Push adds a new node
Pop removes a node
Additional primitives can be defined :
69
Pop
e.g. Pop(S) removes the TOP node and returns its value
70
s.push(F);
s.pop();
s.pop();
s.pop();
returns F
returns B
returns A
We could try the same example with actual values for A, B and C.
A=1B=2C=3
Ans.2: The STACK Data Structure :
Exercise : Stack Operations
1.
2.
71
Show the state of the stack and the value of each variable after
execution of each of the following statements :
A=5B=3C=7
(a)
create stack
push A onto stack
push C*C onto stack
pop item from stack and store in B
push B+A onto stack
pop item from stack and store in A
pop item from stack and store in B
(b)
create stack
push B onto stack
push C onto stack
push A onto stack
A=B*C
push A+C onto stack
pop item from stack and store in A
pop item from stack and store in B
pop item from stack and store in C
72
Static Data Structures : These define collections of data which are fixed in size
when the program is compiled.
An array is a static data structure.
Dynamic data structures : These define collections of data which are variable
in size and structure. They are created as the program executes, and grow and
shrink to accommodate the data being stored.
Q.5.
Define Stacks & Lists in terms of implementing algorithms with the various
operations.
Ans.: Stacks & Lists : Stacks and Lists are basic data structures that you need to
know about when implementing algorithms.
A stack can be regarded as an array of data elements, that needs to be filled.
There are 2 different kinds of stacks. FIFO stack and LIFO stack.
FIFO is short for First in, First out . That is, the first element that is added to
the array will also be the first to be removed.
LIFO is short for Last in, First out . That is, the last element being added to the
array will be the first to be removed.
The Stack Pointer . Another important thing is, that all stacks, be it FIFO or
LIFO have a so called stack pointer. The stack pointer marks the last element
of the array.
Push and Pop : Push and pop are the basic operations executed on a stack.
Push means, to add another item to the stack. Pop means, to remove another
item from the stack.
Push and Pop are usually implemented as functions but they could also be
implemented as a loop in the main program.
Implementing a LIFO stack. Now comes the fun. We are going to implement
a LIFO stack. Before starting coding we may need gather our basic
informations about the stack.
73
Since its a LIFO stack, we may implement it as an array. Remember that LIFO
means Last in, First out, so we need to assure that the last element being
added will be the first to be released. This is a rather straightforward
operation, since all arrays usually grow from bottom to top and we can simply
remove the last element being added.
/* allocating an array with 10 elemets used as stack */
int* stack;
int StackInit(int i)
{
stack = malloc(i*(sizeof(int));
return stack;
}
In this code snippet, the stack is defined as global variable, because it needs to
be accessible to all other functions.
void push(int elem)
{
stack[++top] = elem;
}
int pop(int elem)
{
return stack[elem--];
}
The code above shows possible implementations of push and pop . The
implementation is hold easy to demonstrate their functionality. In a real-world
program you would have to check if the stack is empty or already filled, if the
stack is full etc.
Push and pop could than be used as follows :
int main()
{
74
int j = 10;
int l;
/* allocating a stack */
stackinit(j);
/* fill the stack with 10 items */
for(l=0;l<=10;l++){
push(l);
/* we have 10 items in the stack, so quit */
if(l >= 10)
{
break;
exit(1);
}
}
/* pop out all items of the stack */
int k;
for(k = 10;k>=0;k--)
{
pop(k);
if(k <= 0)
{
break;
exit(1);
}
}
return 0;
}
75
This program is rather simple. First it allocates space for the stack and then it
uses push and pop operations to fill and empty the stack.
Lists Lists are another basic and popular data structure. Thats why some High
Level programming languages like C++ and Java have implemented them in
their libraries. In C you need to build your own List. This is usually done with
a struct.
typedef struct LinkedList
{
struct LinkedList* head;
struct LinkedList* next;
};
struct LinkedList list;
Having defined this list as a new data type you can use it like you would use
any other elementary data type of C.
Basic List operations: Basic List operations are: insert an item, delete an item,
move an item. However, before doing any operation on lists, you need to
allocate memory for the list.
struct* LinkedList InitList(struct LinkedList* p)
{
if(p =
malloc(x*sizeof(LinkedList))
== NULL)
printf("Error! Unable to allocate memory");
else
{
p = p->next;
p->next = NULL;
76
}
return p;
}
This function is rather simple. It allocates memory for the list dynamically as
we have done with the stack. But it does a little bit more. It also sets the
pointer p as the one and only element, that is, it is the first and the last element
of the list.
Note : This code may not work when compiled with ANSI-C comformity
because ANSI-C does not allow use of reference operator on the left hand side
of an assignment .
77
Chapter-8
Queue
Q.1.
What is Queue?
78
Q.2.
79
The restrictions on a stack imply that if the elements A,B,C,D,E are added to
the stack, n that order, then the first element to be removed/deleted must be
E. Equivalently we say that the last element to be inserted into the stack will
be the first to be removed. For this reason stacks are sometimes referred to as
Last In First Out (LIFO) lists. The restrictions on queue imply that the first
element which is inserted into the queue will be the first one to be removed.
Thus A is the first letter to be removed, and queues are known as First In First
Out (FIFO) lists. Note that the data object queue as defined here need not
necessarily correspond to the mathemathical concept of queue in which the
insert/delete rules may be different.
Q.3.
Ans.:
Queue constructor
back
empty
front
pop
push
size
Priority Queue :
A Priority queue is a collection of zero or more elements. Each element has a
priority or a value. The operations performed on a priority queue are :
1)
Find an element
2)
3)
Delete an element
80
In Min Priority Queue the find operation finds the element with minimum
priority, while the delete operation deletes it.
In Max Priority Queue the find operation finds the element with maximum
priority, while the delete operation deletes it.
Unlike the general queues which are FIFO structures , the order of deletion
from a priority queue is determined by the element priority. Elements are
deleted either in increasing or decreasing order of priority from a priority
queue.
A priority queue can be implemented by using
1)
Heap
2)
#include<iostream.h>
class searching
{
private:
double *array;
int n;
public:
void input();
void bubblesort();
void binarysearch();
};
void searching::input()
{
cout<<****************************************************\n
<<This program is to implement binary search algorithm\n
<<****************************************************\n;
cout<<Enter how many numbers you are going to enter::;
cin>>n;
array=new double[n+1];
cout<<Now enter your elements ::\n;
for(int i=1;i<=n;i++)
cin>>array[i];
}
void searching::bubblesort()
{
for(int i=1;i<=n-1;i++)
{
for(int j=1;j<=n-i;j++)
if(array[j]>=array[j+1])
array[j]+=array[j+1],
array[j+1]=array[j]-array[j+1],
array[j]=array[j]-array[j+1];
}
}
void searching::binarysearch()
{
cout<<Enter the element to be searched ::;
double x;
cin>>x;
int low=1,high=n;
while(low<=high)
{
int middle=(low+high)/2;
if(x<array[middle])
81
82
high=middle-1;
else if(x>array[middle])
low=middle+1;
else
{
cout<<found \n;
return;
}
}
cout<<search unsuccessful\n;
}
int main()
{
searching obj;
obj.input();
obj.bubblesort();
obj.binarysearch();
return 0;
}
/*****************************************************************
SAMPLE OUTPUT ::
****************************************************
This program is to implement binary search algorithm
****************************************************
Enter how many numbers you are going to enter::5
Now enter your elements ::
83
1.3
1.2
1.6
1.5
1.4
Enter the element to be searched ::1.4
found
Press any key to continue
********************************************************************/
84
Chapter-9
85
(2)
(3)
Repeat the steps above for remainder of the list (starting at the second
position).
Effectively, we divide the list into two parts: the sublist of items already
sorted, which we build up from left to right and is found at the beginning, and
the sublist of items remaining to be sorted, occupying the remainder of the
array.
Here is an example of this sort algorithm sorting five elements :
86
64 25 12 22 11
11 25 12 22 64
11 12 25 22 64
11 12 22 25 64
Selection sort can also be used on list structures that make add and remove
efficient, such as a linked list. In this case it's more common to remove the
minimum element from the remainder of the list, and then insert it at the end
of the values sorted so far. For example :
64 25 12 22 11
11 64 25 12 22
11 12 64 25 22
11 12 22 64 25
11 12 22 25 64
Pseudo-code :
A is the set of elements to sort, n is the number of elements in A (the array
starts at index 0)
for i 0 to n-2 do
min i
for j (i + 1) to n-1 do
if A[j] < A[min]
min j
swap A[i] and A[min]
Q.3.
Ans.: Insertion sort is a simple sorting algorithm, a comparison sort in which the
sorted array (or list) is built one entry at a time. It is much less efficient on
large lists than more advanced algorithms such as quick sort, heap sort, or
merge sort, but it has various advantages :
(1)
Simple to implement.
(2)
(3)
(4)
stable(does not change the relative order of elements with equal keys)
(5)
In- place (only requires a constant amount O(1) of extra memory space)
(6)
87
88
function mergesort(m)
var list left, right, result
if length(m) 1
return m
var middle = length(m) / 2
for each x in m up to middle
add x to left
for each x in m after middle
add x to right
left = mergesort(left)
right = mergesort(right)
result = merge(left, right)
return result
Q.5.
Ans.: In computer science, radix sort is a sorting algorithm that sorts integers by
processing individual digits. Because integers can represent strings of
characters (e.g., names or dates) and specially formatted floating point
numbers, radix sort is not limited to integers.
Most digital computers internally represent all of their data as electronic
representations of binary numbers, so processing the digits of integer
representations by groups of binary digit representations is most convenient.
Two classifications of radix sorts are least significant digit (LSD) radix sorts
and most significant digit (MSD) radix sorts. LSD radix sorts process the
integer representations starting from the least significant digit and move
towards the most significant digit. MSD radix sorts work the other way
around.
The integer representations that are processed by sorting algorithms are often
called "keys," which can exist all by themselves or be associated with other
data. LSD radix sorts typically use the following sorting order: short keys
come before longer keys, and keys of the same length are sorted
lexicographically. This coincides with the normal order of integer
89
Ans.: Quicksort sorts by employing a divide and conquer strategy to divide a list
into two sub-lists.
The steps are :
Pick an element, called a pivot, from the list.
Reorder the list so that all elements which are less than the pivot come
before the pivot and so that all elements greater than the pivot come
after it (equal values can go either way). After this partitioning, the
pivot is in its final position. This is called the partition operation.
Recursively sort the sub-list of lesser elements and the sub-list of
greater elements.
The base case of the recursion are lists of size zero or one, which are always
sorted.
In simple pseudocode, the algorithm might be expressed as:
function quicksort(array)
var list less, greater
if length(array) 1
return array
select a pivot value pivot from array
for each x in array
if x < pivot then append x to less
90
Ans.: A binary search algorithm (or binary chop) is a technique for finding a
particular value in a sorted list. It makes progressively better guesses, and
closes in on the sought value by selecting the median element in a list,
comparing its value to the target value, and determining if the selected value
is greater than, less than, or equal to the target value. A guess that turns out to
be too high becomes the new top of the list, and a guess that is too low
becomes the new bottom of the list. Pursuing this strategy iteratively, it
narrows the search by a factor of two each time, and finds the target value.
The algorithm : The most common application of binary search is to find a
specific value in a sorted list. To cast this in the frame of the guessing game
(see Example below), realize that we are now guessing the index, or numbered
place, of the value in the list. This is useful because, given the index, other data
structures will contain associated information. Suppose a data structure
containing the classic collection of name, address, telephone number and so
forth has been accumulated, and an array is prepared containing the names,
numbered from one to N. A query might be: what is the telephone number for
a given name X. To answer this the array would be searched and the index (if
any) corresponding to that name determined, whereupon it would be used to
report the associated telephone number and so forth. Appropriate provision
must be made for the name not being in the list (typically by returning an
index value of zero), indeed the question of interest might be only whether X is
in the list or not.
low = 0
high = N
while (low < high) {
mid = (low + high)/2;
if (A[mid] < value)
low = mid + 1;
91
else
//can't be high = mid-1: here A[mid] >= value,
//so high can't be < mid if A[mid] == value
high = mid;
}
if (low < N) and (A[low] == value)
return low
else
return not_found
This algorithm has two other advantages. At the end of the loop, low points to
the first entry greater than or equal to value, so a new entry can be inserted if
no match is found. Moreover, it only requires one comparison; which could be
significant for complex keys in languages which do not allow the result of a
comparison to be saved.
Q.8.
Ans.: An internal sort is any data sorting process that takes place entirely within the
main memory of a computer. This is possible whenever the data to be sorted is
small enough to all be held in the main memory. For sorting larger datasets, it
may be necessary to hold only a chunk of data in memory at a time, since it
wont all fit. The rest of the data is normally held on some larger, but slower
medium, like a hard-disk. Any reading or writing of data to and from this
slower media can slow the sortation process considerably. This issue has
implications for different sort algorithms.
Consider a Bubblesort, where adjacent records are swapped in order to get
them into the right order, so that records appear to 'bubble' up and down
through the dataspace. If this has to be done in chunks, then when we have
sorted all the records in chunk 1, we move on to chunk 2, but we find that
some of the records in chunk 1 need to 'bubble through' chunk 2, and vice
versa (i.e., there are records in chunk 2 that belong in chunk 1, and records in
chunk 1 that belong in chunk 2 or later chunks). This will cause the chunks to
be read and written back to disk many times as records cross over the
92
Ans.: The answer depends on what you mean by quickest. For most sorting
problems, it just doesnt matter how quick the sort is because it is done
infrequently or other operations take significantly more time anyway. Even in
cases in which sorting speed is of the essence, there is no one answer. It
depends on not only the size and nature of the data, but also the likely order.
No algorithm is best in all cases.
There are three sorting methods in this authors toolbox that are all very fast
and that are useful in different situations. Those methods are quick sort, merge
sort, and radix sort.
The Quick Sort : The quick sort algorithm is of the divide and conquer type.
That means it works by reducing a sorting problem into several easier sorting
problems and solving each of them. A dividing value is chosen from the input
data, and the data is partitioned into three sets: elements that belong before
the dividing value, the value itself, and elements that come after the dividing
value. The partitioning is performed by exchanging elements that are in the
first set but belong in the third with elements that are in the third set but
belong in the first Elements that are equal to the dividing element can be put
in any of the three setsthe algorithm will still work properly.
The Merge Sort : The merge sort is a divide and conquer sort as well. It works
by considering the data to be sorted as a sequence of already-sorted lists (in
the worst case, each list is one element long). Adjacent sorted lists are merged
into larger sorted lists until there is a single sorted list containing all the
elements. The merge sort is good at sorting lists and other data structures that
93
are not in arrays, and it can be used to sort things that dont fit into memory. It
also can be implemented as a stable sort.
The Radix Sort : The radix sort takes a list of integers and puts each element
on a smaller list, depending on the value of its least significant byte. Then the
small lists are concatenated, and the process is repeated for each more
significant byte until the list is sorted. The radix sort is simpler to implement
on fixed-length data such as ints.
Q.10. What is the quickest Searching Method to use?
Ans.: A binary search, such as bsearch() performs, is much faster than a linear
search. A hashing algorithm can provide even faster searching. One
particularly interesting and fast method for searching is to keep the data in a
digital trie. A digital trie offers the prospect of being able to search for an item
in essentially a constant amount of time, independent of how many items are
in the data set.
A digital trie combines aspects of binary searching, radix searching, and
hashing. The term digital trie refers to the data structure used to hold the
items to be searched. It is a multilevel data structure that branches N ways at
each level.
94
Chapter-10
Graph
Q.1.
What is Graph?
Q.2.
Ans.: Choices of Representation : Two main data structures for the representation
of graphs are used in practice. The first is called an adjacency list, and is
implemented by representing each node as a data structure that contains a list
of all adjacent nodes. The second is an adjacency matrix, in which the rows
and columns of a two-dimensional array represent source and destination
vertices and entries in the array indicate whether an edge exists between the
vertices. Adjacency lists are preferred for sparse graphs; otherwise, an
adjacency matrix is a good choice. Finally, for very large graphs with some
regularity in the placement of edges, a symbolic graph is a possible choice of
representation.
Q..3
95
Ans.: Undirected Graph : An undirected graph G has two kinds of incidence matrix:
unoriented and oriented. The incidence matrix (or unoriented incidence
matrix) of G is a p q matrix (bij), where p and q are the numbers of vertices
and edges respectively, such that bij = 1 if the vertex vi and edge xj are
incident and 0 otherwise.
Multigraph : A multigraph with multiple edges (red) and a loop (blue). Not
all authors allow multigraphs to have loops.
96
Ans.: Incidence Matrix : The graph is represented by a matrix of size |V| (number
of vertices) by |E| (number of edges) where the entry [vertex, edge] contains
the edge's endpoint data (simplest case: 1 - connected, 0 - not connected).
The incidence matrix of a directed graph D is a p q matrix [bij] where p and
q are the number of vertices and edges respectively, such that bij = 1 if the
edge xj leaves vertex vi, 1 if it enters vertex vi and 0 otherwise. (Note that
many authors use the opposite sign convention.)
An oriented incidence matrix of an undirected graph G is the incidence matrix,
in the sense of directed graphs, of any orientation of G. That is, in the column
of edge e, there is a +1 in the row corresponding to one vertex of e and a -1 in
97
the row corresponding to the other vertex of e, and all other rows have 0. All
oriented incidence matrices of G differ only by negating some set of columns.
In many uses, this is an insignificant difference, so one can speak of the
oriented incidence matrix, even though that is technically incorrect.
The oriented or unoriented incidence matrix of a graph G is related to the
adjacency matrix of its line graph L(G) by the following theorem:
A(L(G)) = B(G)TB(G) 2Iq
where A(L(G)) is the adjacency matrix of the line graph of G, B(G) is the
incidence matrix, and Iq is the identity matrix of dimension q.
Adjacency Matrix : This is the n by n matrix A, where n is the number of
vertices in the graph. If there is an edge from some vertex x to some vertex y,
then the element ax,y is 1 (or in general the number of xy edges), otherwise it
is 0. In computing, this matrix makes it easy to find subgraphs, and to reverse
a directed graph.
Q.6.
Ans.: Graph data structures are non-hierarchical and therefore suitable for data sets
where the individual elements are interconnected in complex ways. For
example, a computer network can be modeled with a graph.
Hierarchical data sets can be represented by a binary or nonbinary tree. It is
worth mentioning, however, that trees can be seen as a special form of graph.
Operations : Graph algorithms are a significant field of interest within
computer science. Typical operations associated with graphs are: finding a
path between two nodes, like
depth-first search
and
breadth-
first search and finding the shortest path from one node to another, like
Dijkstra's algorithm. A solution to finding the shortest path from
each node to every other node also exists in the form of the FloydWarshall algorithm.
98
A directed graph can be seen as a flow network, where each edge has a
capacity and each edge receives a flow. The Ford-Fulkerson algorithm is used
to find out the maximum flow from a source to a sink in a graph.
The graphs can be represented in two ways. One is adjacency matrix and
adjacency list.
For example, let us consider the following graph
A----------->B
|
C ------------
Adjacency Matrix :
ABC
A 011
B 000
C 010
Adjacency List :
A ----> | B | ----> | C | ---- NULL
B ----> ---- NULL
C ----> | B | ---- NULL
Q.7.
Ans.: Depth-First Search (DFS) is an algorithm for traversing or searching a tree, tree
structure, or graph. One starts at the root (selecting some node as the root in
the graph case) and explores as far as possible along each branch before
backtracking.
99
The depth first search is well geared towards problems where we want to find
any solution to the problem (not necessarily the shortest path), or to visit all of
the nodes in the graph
This concept maps extremely well to a Depth First search. The basic concept is
to visit a node, then push all of the nodes to be visited onto the stack. To find
the next node to visit we simply pop a node of the stack, and then push all the
nodes connected to that one onto the stack as well and we continue doing this
until all nodes are visited. It is a key property of the Depth First search that we
not visit the same node more than once, otherwise it is quite possible that we
will recurs infinitely. We do this by marking the node as we visit it, then
unmarking it after we have finished our recursions. This action allows us to
visit all the paths that exist in a graph; however for large graphs this is mostly
infeasible so we sometimes omit the marking the node as not visited step to
just find one valid path through the graph (which is good enough most of the
time).
Q.8.
Ans.: In graph theory, breadth-first search (BFS) is a graph search algorithm that
begins at the root node and explores all the neighboring nodes. Then for each
of those nearest nodes, it explores their unexplored neighbour nodes, and so
on, until it finds the goal.
How it works : BFS is a uninformed
100
An example map of
The breadth-first tree one gets when running BFS on the given map and
starting in
Frankfurt.
101
Algorithm (Informal) :
(1)
(2)
Pull a node from the beginning of the queue and examine it.
o
If the searched element is found in this node, quit the search and
return a result.
(3)
If the queue is empty, every node on the graph has been examined -quit the search and return "not found".
(4)
C Implementation :
Algorithm of Breadth-First Search :
void BFS(VLink G[], int v) {
int w;
VISIT(v);
visited[v] = 1;
ADDQ(Q,v);
while(!QMPTYQ(Q)) {
v = DELQ(Q);
/*Dequeue v*/
102
w = FIRSTADJ(G,v);
while(w != -1) {
if(visited[w] == 0) {
VISIT(w);
ADDQ(Q,w);
visited[w] = 1;
}
W = NEXTADJ(G,v);
}
}
}
Main Algorithm of apply Breadth-first search to graph G=(V,E)
void TRAVEL_BFS(VLink G[], int visited[], int n) {
int i;
for(i = 0; i < n; i ++) {
visited[i] = 0;
}
for(i = 0; i < n; i ++)
if(visited[i] == 0)
BFS(G,i);
}
C++ implementation
This is the implementation of the above informal algorithm, where the "so-farunexamined" is handled by the parent array.
Suppose we have a struct:
struct Vertex {
...
std::vector<int> out;
...
};
103
and an array of vertices: (the algorithm will use the indexes of this
array, to handle the vertices)
std::vector<Vertex> graph(vertices);
the algorithm starts from start and returns true if there is a directed
path from start to end:
bool BFS(const std::vector<Vertex>& graph, int start, int end) {
std::queue<int> next;
std::map<int,int> parent;
parent[start] = -1;
next.push(start);
while (!next.empty()) {
int u = next.front();
next.pop();
// Here is the point where you can examine the u th vertex of graph
// For example:
if (u == end) return true;
for (std::vector<int>::const_iterator j = graph[u].out.begin();
graph[u].out.end(); ++j) {
// Look through neighbors.
int v = *j;
if (parent.count(v) == 0) {
// If v is unvisited.
parent[v] = u;
next.push(v);
!=
}
}
}
return false;
}
It also stores the parents of each node, from which you can get the path.
104
Chapter-11
Tree
Q.1.
What is Tree?
Ans.: A tree is a non-empty collection of vertices & edges that satisfies certain
requirements. A vertex is a simple object (node) that can have a name and
carry other associated information. An edge is a connection between two
vertices.
A Tree is a finite set of a zero or more vertices such that there is one specially
designated vertex called Root and the remaining vertices are partitioned into a
collection of sub-trees, each of which is also a tree. A node may not have
children, such node is known as Leaf (terminal node). The line from parent to
a child is called a branch or an edge. Children to same parent are called
siblings.
Q.2.
science, a binary
tree is a tree data structure in which
each node has at most two children.
Ans.:
In computer
another is
A simple binary tree of size 9 and height 4, with a root node whose value is 2
In other words, A binary tree consists of
a node (called the root node) and
105
the keys of all the nodes in the left sub-tree are less than that of the root,
(b)
the keys of all the nodes in the right sub-tree are greater than that of the
root,
(c)
the left and right sub-trees are themselves ordered binary trees.
Q.3.
Ans.:
Q.4.
Ans.:
106
A rooted binary tree is a rooted tree in which every node has at most
two children.
A full binary tree, or proper binary tree, is a tree in which every node
has zero or two children.
A perfect binary tree (sometimes complete binary tree) is a full binary
tree in which all leaves are at the same depth.
A complete binary tree may also be defined as a full binary tree in
which all leaves are at depth n or n-1 for some n. In order for a tree to
be the latter kind of complete binary tree, all the children on the last
level must occupy the leftmost spots consecutively, with no spot left
unoccupied in between any two. For example, if two nodes on the
bottommost level each occupy a spot with an empty spot between the
two of them, but the rest of the children nodes are tightly wedged
together with no spots in between, then the tree cannot be a complete
binary tree due to the empty spot.
A rooted complete binary tree can be identified with a free magma.
An almost complete binary tree is a tree in which each node that has a
right child also has a left child. Having a left child does not require a
node to have a right child. Stated alternately, an almost complete binary
tree is a tree where for a right child, there is always a left child, but for a
left child there may not be a right child.
The number of nodes n in a complete binary tree can be found using
this formula: n = 2h + 1 - 1 where h is the height of the tree.
The number of leaf nodes n in a complete binary tree can be found
using this formula: n = 2h where h is the height of the tree.
Q.5.
Ans.: In computer science, a binary search tree (BST) is a binary tree data structure
which has the following properties :
each node has a value;
a total order is defined on these values;
107
the left subtree of a node contains only values less than the node's
value;
the right subtree of a node contains only values greater than or equal to
the node's value.
The major advantage of binary search trees is that the related sorting
algorithms and search algorithms such as in-order traversal can be very
efficient. Binary search trees are a fundamental data structure used to
construct more abstract data structures such as sets, multisets, and associative
arrays. If a BST allows duplicate values, then it represents a multiset. This kind
of tree uses non-strict inequalities. Everything in the left subtree of a node is
strictly less than the value of the node, but everything in the right subtree is
either greater than or equal to the value of the node. If a BST doesn't allow
duplicate values, then the tree represents a set with unique values, like the
mathematical set. Trees without duplicate values use strict inequalities,
meaning that the left subtree of a node only contains nodes with values that
are less than the value of the node, and the right subtree only contains values
that are greater. The choice of storing equal values in the right subtree only is
arbitrary; the left would work just as well. One can also permit non-strict
equality in both sides. This allows a tree containing many duplicate values to
be balanced better, but it makes searching more complex.
Q.6.
Ans.:
108
would be if it were present, so it does not lie in the tree at all. A comparison may be
made with binary search, which operates in nearly the same way but using random
access on an array instead of following links. Here is the search algorithm in the
Python programming language: <source lang="python">
def search_binary_tree(node, key):
if node is None:
return None # key not found
if key < node.key:
return search_binary_tree(node.left, key)
else if key > node.key:
return search_binary_tree(node.right, key)
else: # key is equal to node key
return node.value # found key
</source> This operation requires O(log n) time in the average case,
but needs O(n) time in the worst-case, when the unbalanced tree
resembles a linked list (degenerate tree).
Insertion : Insertion begins as a search would begin; if the root is not
equal to the value, we search the left or right subtrees as before. Eventually, we will
reach an external node and add the value as its right or left child, depending on the
node's value. In other words, we examine the root and recursively insert the new
node to the left subtree if the new value is less than the root, or the right subtree if the
new value is greater than or equal to the root. Here's how a typical binary search tree
insertion might be performed in C++: <source lang="cpp">
/* Inserts the node pointed to by "newNode" into the subtree rooted at
"treeNode" */
void InsertNode(struct node *&treeNode, struct node *newNode)
{
if (treeNode == NULL)
treeNode = newNode;
109
key,
value),
node.value, node.right)
else:
return TreeNode(node.left, node.key, node.value,
binary_tree_insert(node.right, key, value))
</source> The part that is rebuilt uses (log n) space in the average
case and (n) in the worst case (see big-O notation). In either version,
this operation requires time proportional to the height of the tree in the
worst case, which is O(log n) time in the average case over all trees, but
(n) time in the worst case. Another way to explain insertion is that in
order to insert a new node in the tree, its value is first compared with
the value of the root. If its value is less than the root's, it is then
110
compared with the value of the root's left child. If its value is greater, it
is compared with the root's right child. This process continues, until the
new node is compared with a leaf node, and then it is added as this
node's right or left child, depending on its value. There are other ways
of inserting nodes into a binary tree, but this is the only way of
inserting nodes at the leaves and at the same time preserving the BST
structure.
Deletion : There are several cases to be considered:
Deleting a leaf: Deleting a node with no children is easy, as we
can simply remove it from the tree.
Deleting a node with one child: Delete it and replace it with its
child.
Deleting a node with two children: Suppose the node to be
deleted is called N. We replace the value of N with either its inorder successor (the left-most child of the right subtree) or the inorder predecessor (the right-most child of the left subtree).
111
if (node->left == NULL) {
struct node *temp = node;
node = node->right;
delete temp;
} else if (node->right == NULL) {
struct node *temp = node;
node = node->left;
delete temp;
} else {
// In-order predecessor (rightmost child of left subtree)
// Node has two children - get max of left subtree
struct node **temp = &node->left; // get left node of the original
node
// find the rightmost child of the subtree of the left node
while ((*temp)->right != NULL) {
temp = &(*temp)->right;
}
// copy the value from the in-order predecessor to the original
node
node->value = (*temp)->value;
// then delete the predecessor
DeleteNode(*temp);
}
}
112
</source> Although this operation does not always traverse the tree
down to a leaf, this is always a possibility; thus in the worst case it
requires time proportional to the height of the tree. It does not require
more even when the node has two children, since it still follows a single
path and does not visit any node twice.
Sort
A binary search tree can be used to implement a simple but inefficient
sorting algorithm. Similar to heapsort, we insert all the values we wish
to sort into a new ordered data structure in this case a binary search
tree and then traverse it in order, building our result: <source
lang="python">
def build_binary_tree(values):
tree = None
for v in values:
tree = binary_tree_insert(tree, v)
return tree
def traverse_binary_tree(treenode):
if treenode is None: return []
else:
left, value, right = treenode
return (traverse_binary_tree(left), [value],
traverse_binary_tree(right))
</source>
The
worst-case
time
of
build_binary_tree
is
<math>\Theta(n^2)</math> if you feed it a sorted list of values, it
chains them into a linked list with no left subtrees. For example,
build_binary_tree([1, 2, 3, 4, 5]) yields the tree (None, 1, (None, 2,
(None, 3, (None, 4, (None, 5, None))))). There are several schemes for
overcoming this flaw with simple binary trees; the most common is the
self-balancing binary search tree. If this same procedure is done using
such a tree, the overall worst-case time is O(nlog n), which is
asymptotically optimal for a comparison sort. In practice, the poor
cache performance and added overhead in time and space for a tree-
113
Ans.: Traversal : Once the binary search tree has been created, its elements can be
retrieved in order by recursively traversing the left subtree of the root node,
accessing the node itself, then recursively traversing the right subtree of the
node, continuing this pattern with each node in the tree as it's recursively
accessed. The tree may also be traversed in pre-order or post-order traversals.
<source lang="python">
def traverse_binary_tree(treenode):
if treenode is None: return
left, nodevalue, right = treenode
traverse_binary_tree(left)
visit(nodevalue)
traverse_binary_tree(right)
</source> Traversal requires (n) time, since it must visit every node. This
algorithm is also O(n), and so it is asymptotically
optimal.
Traversing A Binary Tree : Traversing a binary
tree comes in handy when you would like to do
print out of all the data elements in the tree. We
demonstrate three types of traversals in our
tutorial.
All traversal descriptions refer to :
These three types are as follows :
Pre Order Traversal : A pre order
traversal prints the contents of a sorted tree, in
pre order. In other words, the contents of the
114
root node are printed first, followed by left subtree and finally the right subtree. So in
Figure , an in order traversal would result in the following string: FCADJHIK
PreOrder (T)
If T < > Null
then print (T.data)
else print(empty tree)
If T.lp < > null
then PreOrder(T.lp)
If T.rp < > null
then preorder (T.rp)
end.
In Order Traversal : An in order traversal prints the contents of a
sorted tree, in order. In other words, the lowest in value first, and then increasing in
value as it traverses the tree. The order of a traversal would be 'a' to 'z' if the tree uses
strings or characters, and would be increasing numerically from 0 if the tree contains
numerical values. So in Figure , an in order traversal would result in the following
string: ACDFHIJK
InOrder (T)
If T < > null
print (empty tree)
If T.lp < > null
then InOrder(T.lp)
print (T.data)
If T.rp < > null
then InOrder (T.lp)
end.
Post Order Traversal : A post order traversal prints the contents of a
sorted tree, in post order. In other words, the contents of the left subtree are printed
115
first, followed by right subtree and finally the root node. So in Figure , an in order
traversal would result in the following string: ADCIHKJF.
PostOrder (T)
If T = null
then print (empty tree)
If T.lp < > null
then PostOrder(T.lp)
If T.rp < > null
then PostOrder(T.lp)
Print(T.data)
end.
Q.8.
What is a Heap?
/ \
L
I M
Storage of Heap Data : The typical storage method for a heap, or any almost
complete binary tree, works as follows. Begin by numbering the nodes level by
level from the top down, left to right. For example, consider the following heap.
The numbering has been added below the nodes.
116
C
0
/
/ \
I M
3 4 5
Then store the data in an array as shown below :
The advantage of this method over using the usual pointers and nodes is that
there is no wasting of space due to storing two pointer fields in each node.
Instead, starting with the current index, CI, one calculates the index to use as
follows :
Parent(CI) = (CI - 1) / 2
RightChild(CI) = 2 * (CI + 1)
LeftChild(CI) = 2 * CI + 1
For example, if we start at node H (with index 1), the right child is at index 2 *
(1 + 1) = 4, that is, node I.
Inserting into a Heap : This is done by temporarily placing the new item at
the end of the heap (array) and then calling a FilterUp routine to make any
needed adjustments on the path from this leaf to the root. For example, let's
insert E into the following heap :
C
/
H
/ \
\
K
/
117
I M
/ \
/ \
I M
Of course, the new tree might not be a heap. The FilterUp routine now checks
the parent, K, and sees that things would be out of order as they are. So K is
moved down to where E was. Then the parent above that, C, is checked. It is in
order relative to the target item E, so the C is not moved down. The hole left
behind is filled with E, then, as this is the correct position for it.
C
/
/ \
L
/ \
I M
For practice, let's take the above heap and insert another item, D. First, place D
temporarily in the next available position :
C
/
/ \
L
/ \
I M
/
D
Then the FilterUp routine checks the parent, L, and discovers that L must be
moved down. Then the parent above that, H, is checked. It too must be moved
118
down. Finally C is checked, but it is OK where it is. The hole left where the H
had been is where the target D is then inserted.
C
/
/ \
H
/ \
I M
/
L
Things have now been adjusted so that we again have a heap!
Removing from a Heap : We always remove the item from the root. That way
we always get the smallest item. The problem is then how to adjust the binary
tree so that we again have a heap (with one less item).
The algorithm works like this: First, remove the root item and replace it
temporarily with the item in the last position. Call this replacement the target.
A FilterDown routine is then used to check the path from the root to a leaf for
the correct position for this target. The path is chosen by always selecting the
smaller child at each node. For example, let's remove the C from this heap :
C
/ \
D
E
/ \ / \
H I M K
/
L
First we remove the C and replace it with the last item (the target), L :
L
/
D
/ \
\
E
/ \
119
H I M K
The smaller child of L is D. Since D is out of order compared to the target L,
we move D up. The smaller child under where D had been is H. When H is
compared to L we see that the H too needs to be moved up. Since we are now
at a leaf, this empty leaf is where the target L is put.
D
/ \
H
E
/ \ / \
L I M K
For another example, let's remove the E from the following heap :
E
/
/ \
J
/ \
N K
/\
X Y P
First remove the E and replace it with the target P (the last item) :
P
/
G
/ \
J
\
/ \
N K
/\
X Y
Now use the FilterDown routine to filter the P down to its correct position by
checking the smaller child, G, which should be moved up, and then the
smaller child below that, J, which should also be moved up. Finally, the
smaller child, X, under where J had been is checked, but it does not get moved
since it is OK relative to the target P. The P is then placed in the empty node
above X. We then have the following heap:
120
G
/
J
/ \
P
\
/ \
N K
/\
X Y
Q.9.
Ans.: Heapsort is performed by somehow creating a heap and then removing the
data items one at a time. The heap could start as an empty heap, with items
inserted one by one. However, there is a relatively easy routine to convert an
array of items into a heap, so that method is often used. This routine is
described below. Once the array is converted into a heap, we remove the root
item (the smallest), readjust the remaining items into a heap, and place the
removed item at the end of the heap (array). Then we remove the new item in
the root (the second smallest), readjust the heap, and place the removed item
in the next to the last position, etc.
Heapsort is Theta(n * lg(n)), either average case or worst case. This is great for
a sorting algorithm! No appreciable extra storage space is needed either. On
average, quicksort (which is also Theta(n * lg(n)) for the average case) is faster
than heapsort. However, quicksort has that bad Theta(n^2) worst case running
time.
Example Trace of Heapsort : Let's heapsort the following array :
To convert this to a heap, first go to the index of the last parent node. This is
given by (HeapSize - 2) / 2. In this case, (9 - 2) / 2 = 3. Thus K is the last parent
in the tree. We then apply the FilterDown routine to each node from this index
down to index 0. (Note that this is each node from 3 down to 0, not just the
nodes along the path from index 3 to index 0.)
121
In our example, the array corresponds directly to the following binary tree.
Note that this is not yet a heap.
P
/ \
S
C
/ \ / \
K
M L
/\
X E
Applying FilterDown at K gives the following. (Note that E is the smaller child
under K.)
P
/
/ \
E
/ \
M L
/\
X K
Now apply FilterDown at index 2, that is, at node C. (Under C, A is the smaller
child.)
P
/
/ \
E
/ \
M L
/\
X K
Next, apply FilterDown at index 1, that is, at node S. Check the smaller child,
E, and then the smaller child under that, namely K. Both E and K get moved
up.
P
122
/ \
K
/ \
M L
/\
X S
Finally, apply FilterDown at index 0, that is, at the root node. We check the
smaller child, A, and then the smaller child, C, relative to the target P. Both A
and C get moved up.
A
/
/ \
K
/ \
M L
/\
X S
Now we have a heap! The first main step of heapsort has been completed. The
other main component of heapsort was described earlier: to repeatedly remove
the root item, adjust the heap, and put the removed item in the empty slot
toward the end of the array (heap).
First we remove the A, adjust the heap by using FilterDown at the root node,
and place the A at the end of the heap (where it is not really part of the heap at
all and so is not drawn below as connected to the tree).
C
/
/ \
K
/.
(the target is S)
/ \
M S
123
X A
Of course, all of this is really taking place in the array that holds the heap. At
this point it looks like the following. Note that the heap is stored from index 0
to index 7. The A is after the end of the heap.
Next we remove the C, adjust the heap by using FilterDown at the root node,
and place the C at the end of the heap:
E
/
(the target is X)
\
/ \
X
/ \
M S
..
C A
Next we remove the E, adjust the heap by using FilterDown at the root node,
and place the E at the end of the heap :
K
/
(the target is P)
\
/ \
/ .
P S
..
C A
Next we remove the K, adjust the heap by using FilterDown at the root node,
and place the K at the end of the heap :
L
(the target is S)
124
/ \
. .
P K
..
C A
Next we remove the L, adjust the heap by using FilterDown at the root node,
and place the L at the end of the heap :
M
/
(the target is P)
\
/ .
. .
L K
..
C A
Next we remove the M, adjust the heap by using FilterDown at the root node,
and place the M at the end of the heap :
P
/
(the target is X)
\
. .
. .
L K
..
C A
Next we remove the P, adjust the heap by using FilterDown at the root node,
and place the P at the end of the heap :
S
/
(the target is S)
.
. .
. .
L K
125
..
C A
Next we remove the S, adjust the heap (now a trivial operation), and place the
S at the end of the heap :
X
.
(the target is X)
.
. .
. .
L K
..
C A
Since only the item X remains in the heap, and since we have removed the
smallest item, then the second smallest, etc., the X must be the largest item and
should be left where it is. If you now look at the array that holds the above
items you will see that we have sorted the array in descending order:
Q.10.
Define
Hash Tables.
Ans.: In computer science, a hash table, or a hash map, is a data structure that
associates keys with values. The primary operation it supports efficiently is a
lookup: given a key (e.g. a person's name), find the corresponding value (e.g.
that person's telephone number). It works by transforming the key using a
hash function into a hash, a number that is used as an index in an array to
locate the desired location ("bucket") where the values should be.
Hash tables support the efficient insertion of new entries, in expected O(1)
time. The time spent in searching depends on the hash function and the load
126
of the hash table; both insertion and search approach O(1) time with well
chosen values and hashes.
Hashing means the act of taking some value and producing a number from the
value. A hash function is a function that does this. Every equivalence predicate
e has a set of acceptable hash functions for that predicate; a hash funtion hash
is acceptable iff (e obj1 obj2) (= (hash obj1) (hash obj2)).
A hash function h is good for a equivalence predicate e if it distributes the
result numbers (hash values) for non-equal objects (by e) as uniformly as
possible over the numeric range of hash values, especially in the case when
some (non-equal) objects resemble each other by e.g. having common
subsequences. This definition is vague but should be enough to assert that e.g.
a constant function is not a good hash function.
Basic Operation : A hash table works by transforming the key using a hash
function into a hash, a number that is used as an index in an array to locate the
desired location ("bucket") where the values should be. The number is
normally converted into the index by taking a modulo, or sometimes bit
masking is used where the array size is a power of two. The optimal hash
function for any given use of a hash table can vary widely, however,
depending on the nature of the key.
Typical operations on a hash table include insertion, deletion and lookup
(although some hash tables are precalculated so that no insertions or deletions,
only lookups are done on a live system). These operations are all performed in
amortized constant time, which makes maintaining and accessing a huge hash
table very efficient.
It is also possible to create a hash table statically where, for example, there is a
fairly limited fixed set of input values - such as the value in a single byte (or
possibly two bytes ) from which an index can be constructed directly (see
section below on creating hash tables). The hash table can also be used
simultaneously for tests of validity on the values that are disallowed.
Q.11.
127
pointers that would normally be null point to the inorder predecessor of the
node."
A threaded binary tree makes it possible to traverse the values in the binary
tree via a linear traversal that is more rapid than a recursive in-order traversal.
It is also possible to discover the parent of a node from a threaded binary tree,
without explicit use of parent pointers or a stack, albeit slowly. This can be
useful however where stack space is limited, or where a stack of parent
pointers is unavailable.
This is possible, because if a node (k) has a right child (m) then m's left pointer
must be either a child, or a thread back to k. In the case of a left child, that left
child must also have a left child or a thread back to k, and so we can follow
m's left children until we find a thread, pointing back to k. The situation is
similar for when m is the left child of k
In pseudocode,
function getParent( node : pointer to a node )
begin
if node == tree.root then
begin
return nil
end
x = node
y = node
while true do
begin
if IsThread(Y, Right) then
begin
p = y.right
if (p == nil) or (p.left <> node) then
begin
p=x
while not IsThread(p, Left) do
128
p = p.left
p = p.left
end
return p
end
if IsThread(Y, Left) then
begin
p = x.left
if (p == nil) or (p.left <> node) then
begin
p=y
while not IsThread(p, Right) do
p = p.right
p = p.right
end
return p
end
x = x.left
y = y.right
end
Q.12. Define AVL Trees.
Ans.: An example of an unbalanced non-AVL tree
In computer science, an AVL tree is a self-balancing binary search tree, and the
first such data structure to be
invented[citation needed]. In an AVL
tree the heights of the two child
subtrees of any node differ by at
most one, therefore it is also called
height-balanced. Lookup, insertion,
129
and deletion all take O(log n) time in both the average and worst cases.
Additions and deletions may require the tree to be rebalanced by one or more
tree rotations.
The AVL tree is named after its two inventors, G.M. Adelson-Velsky and E.M.
Landis, who published it in their 1962 paper "An algorithm for the
organization of information."
The balance factor of a node is the height of its right subtree minus the height
of its left subtree. A node with balance factor 1, 0, or -1 is considered balanced.
A node with any other balance factor is considered unbalanced and requires
rebalancing the tree. The balance factor is either stored directly at each node or
computed from the heights of the subtrees.
AVL trees are often compared with red-black trees because they support the
same set of operations and because red-black trees also take O(log n) time for
the basic operations. AVL trees perform better than red-black trees for lookupintensive applications.[1] The AVL tree balancing algorithm appears in many
computer science curricula.
The same tree after being height-balanced.
Explanation : First, see binary tree for an explanation of a normal binary tree.
An AVL tree operates exactly like a normal binary tree, except additional work
is done after an insertion and a deletion.
The problem with normal binary trees is that if data is added in-order then the
tree isn't a tree at all - it's a list. For example, if we had five data to add to a
tree where each datum is an integer, and we added the integers 1, 2, 3, 4 and 5,
in that order, the tree would not branch at all - it would be a single long line.
130
This is a problem because the whole point of a binary tree is that searching is
fast because when the tree is balanced, each step in the search eliminates half
of the tree at that point. (Imagine a very large, fully balanced tree; you start at
the root node, and go left or right. In doing so, you've just eliminated half the
elements from your search!)
So to solve this problem, an AVL tree can be used, which as mentioned, acts as
a normal binary tree but does additional processing after an add or delete, so
that the tree remains balanced, no matter what order data is placed (or
removed) from the tree.
Now, to perform balancing work on the tree, we have to know when the tree
is unbalanced - because we have to know when we need to fix things. One
possible way to do this is to keep track in each node of the tree how many
nodes exist on the left and right of each node. When we add a node, or delete a
node, we travel up the tree from the point the node is added or deleted,
updating the node counts. If the number of nodes is different, we know that
the tree to the left and right cannot be balanced, because there are a different
number of elements on each side.
However, this doesn't quite work - the problem is that the number of elements
in a subtree doesn't tell you anything about how they are arranged. They
could be properly balanced, or they could be a long list!
In fact what you need to keep track of is the depth of the subtree. A full
subtree with a depth of three would have fourteen elements - and it would be
perfectly balanced. A subtree with a depth of three which is unbalanced might
have only three elements in (a list) - and so be in need of rebalancing.
Each time an element is added, we in fact update a count of the depth of the
subtree on the left and right of each node. We travel up the tree from the point
of addition, updating those values by adding one. We then travel back up the
same path, this time rearranging the tree so that the subtree depths remain
equal on each side.
(In fact, subtree depths must be equal or differ only by one - after all, we could
have three elements on the left and two on the right, which would still be as
balanced as possible. If we rebalanced that tree, all we'd do is then have two
elements on the left and three on the right; we wouldn't gain anything).
131
Rebalancing the tree involves performing left and right rotation operations on
unbalanced nodes, which adjusts the physical shape of the tree which keeping
it logically valid (e.g. binary search down the tree remains correct).
In fact, the tree is rebalanced every time a node is inserted or deleted, which
specifically limits the things that can have to be done to rebalance the tree,
because the tree can never be more than one sub-tree depth out of balance.
Operations : The basic operations of an AVL tree generally involve carrying
out the same algorithms as would be carried out on an unbalanced binary
search tree, but preceded or followed by one or more of the so-called "AVL
rotations."
Insertion : Insertion into an AVL tree may be carried out by inserting
the given value into the tree as if it were an unbalanced binary search tree, and then
retracing one's steps toward the root updating the balance factor of the
nodes.[citation needed]
If the balance factor becomes -1, 0, or 1 then the tree is still in AVL form,
and no rotations are necessary.
If the balance factor becomes 2 or -2 then the tree rooted at this node is
unbalanced, and a tree rotation is needed. At most a single or double
rotation will be needed to balance the tree.[citation needed]
Only the nodes traversed from the insertion point to the root of the tree
need be checked, and rotations are a constant time operation, and
because the height is limited to O(log(n)), the execution time for an
insertion is O(log(n)).
Deletion : If the node is a leaf, remove it. If the node is not a leaf,
replace it with either the largest in its left subtree or the smallest in its right subtree,
and remove that node. Thus the node that is removed has at most one child. After
deletion retrace the path back up the tree to the root, adjusting the balance factors as
needed.
The retracing can stop if the balance factor becomes -1 or 1 indicating
that the height of that subtree has remained unchanged. If the balance
factor becomes 0 then the height of the subtree has decreased by one
132
133
2.
( )
( )
( )
3.
4.
5.
134
(a)
(b)
(c)
(d)
6.
( )
( )
7.
Which of the following is not a basic data structure that could be used to implement an
abstract data type?
(a)
Array
(b)
Linked List
(c)
Hash table
(d)
Heap
( )
8.
9.
10.
11.
12.
13.
Linear
Quadratic
( )
( )
( )
( )
( )
( )
135
14.
Which of the following abstract data types are not used by integer Abstract data type
group?
(a)
short
(b)
int
(c)
float
(d)
long
( )
15.
If the depth of a tree is 3 levels, then what is the size of the tree?
(a)
4
(b)
2
(c)
8
(d)
6
( )
16.
17.
( )
( )
( )
18.
19.
20.
If there exists at least one path between every pair of vertices in a graph, the graph is
known as:
(a)
Complete graph
(b)
Disconnected graph
(c)
Connected graph
(d)
Euler graph
( )
21.
136
(c)
22.
23.
24.
25.
(n k
)(n k 1
)/2edges
(d)
(
nk
)(
nk 1
)/2edges
( )
( )
( )
( )
( )
26.
Which of the following sorting algorithms has average case and worst case running
time of?
(a)
Bubble sort
(b)
Insertion sort
(c)
Merge sort
(d)
Quick sort
( )
27.
( )
Which of the following data structure store the homogeneous data elements?
(a)
Arrays
(b)
Records
(c)
Pointers
(d)
None of the above
( )
28.
29.
30.
137
( )
( )
31.
The post order traversal of a binary tree is DEBFCA. Find out the preorder traversal:
(a)
ABFCDE
(b)
ADBFEC
(c)
ABDECF
(d)
ABDCEF
( )
32.
( )
O(log n)
On
( log n)
( )
O(log n)
On
( log n)
( )
33.
34.
35.
36.
( )
138
(d)
37.
38.
39.
40.
( )
( )
A video game server keeps a list of people waiting to play. The list should be a:
(a)
Binary search tree
(b)
Stack
(c)
Queue
(d)
Static array
( )
( )
Binary Sort
Both (b) and (c)
A sort which compares adjacent elements in a list and switches where necessary is:
(a)
insertion sort
(b)
heap sort
(c)
quick sort
(d)
bubble sort
( )
________
139
DESCRIPTIVE PART II
Year- 2011
Time allowed: 2 Hours
Maximum Marks : 30
Attempt any four descriptive type questions out of the six. All questions carry 7 marks
each.
Q.1
(a)
(b)
Q.2
(a)
(b)
Q.3
(a)
(b)
Q.4
Q.5
(a)
(b)
Q. 6
Write an algorithm for creation of Singly Linked List. Also write algorithms
for insertion and deletion of elements from the singly linked list.
Discuss Huffman encoding scheme with an example.
140
( )
2.
The time factor when determining the efficiency of an algorithm is measured by:
(a)
Counting microseconds
(b)
Counting the number of key operations
(c)
Counting the number of statement
(d)
Counting the Kilobytes of algorithm
( )
3.
4.
The space factor when determining the efficiency of algorithm is measured by:
(a)
Counting the maximum memory needed by the algorithm
(b)
Counting the minimum memory needed by the algorithm
(c)
Counting the average memory needed by the algorithm
(d)
Counting the maximum disk space needed by the algorithm
( )
( )
5.
6.
141
A queue is a :
(a)
Sequential Organization of data
(b)
Listing of data
(c)
Indexing of data
(d)
None of the above
( )
7.
8.
O (log n)
O (n log n)
( )
O (log n)
O (n log n)
( )
9.
10.
Each array declaration need not give, implicitly or explicitly, the information about:
(a)
the name of array
(b)
the data type of array
(c)
the first data from the set to be stored
(d)
the index set of the array
( )
11.
( )
( )
12.
13.
142
(a)
(c)
Sorting
Inserting
(b)
(d)
Merging
Traversal
( )
14.
15.
16.
( )
17.
18.
( )
( )
19.
20.
(b)
(c)
(d)
21.
143
(b)
(d)
One
Three
( )
( )
22.
Which of the following abstract data types are not used by Integer Abstract Data Type
group?
(a)
Short
(b)
Int
(c)
Float
(d)
Long
( )
23.
24.
( )
( )
( )
25.
26.
144
27.
( )
28.
29.
( )
Liner array is a :
(a)
List of finite number n of heterogeneous data elements
(b)
List of finite number, n of homogenous data elements
(c)
(a) and (b) both
(d)
None of the above
( )
How many null branches are there in a binary tree with 20 nodes:
(a)
Zero
(b)
Thirty
(c)
Twenty one
(d)
None of the above
( )
( )
30.
31.
32.
33.
(a)
(b)
(c)
(d)
34.
35.
145
LIFO lists
FIFO lists
Linked lists
None of the above
( )
( )
( )
36.
37.
( )
Data items that are divided into sub items are called:
(a)
Elementary item
(b)
Group item
(c)
(a) and (b) Both
(d)
None of the above
( )
( )
38.
39.
146
40.
Answer Key
1. (c)
2. (a)
3. (b)
4. (a)
5. (a)
6. (a)
7. (b)
8. (b)
9. (c)
10. (c)
11. (d)
12. (b)
13. (d)
14. (a)
15. (b)
16. (b)
17. (b)
18. (a)
19. (b)
20. (b)
21. (d)
22. (c)
23. (c)
24. (c)
25. (a)
26. (a)
27. (c)
28. (a)
29. (b)
30. (b)
31. (c)
32. (a)
33. (b)
34. (b)
35. (b)
36. (a)
37. (a)
38. (a)
39. (a)
40. (a)
__________
DESCRIPTIVE PART II
147
Year- 2010
Time allowed: 2 Hours
Maximum Marks : 30
Attempt any four descriptive type questions out of the six. All questions carry 7 marks
each.
Q.1
(a)
(b)
Q.2
(a)
(b)
Explain string functions for inserting and deleting string from the text.
Describe the pattern matching algorithm with suitable examples.
Q.3
(a)
(b)
Q.4
(a)
What is linear search? Compare the linear search method with Binary Search
Method.
Explain Bubble Sort Algorithm. Sort the following list using bubble sort.
61,8,32,53,81,64.
(b)
Q.5
(a)
(b)
Q. 6
148
OBJECTIVE PART- I
Year - 2009
Time allowed : One Hour
Maximum Marks : 20
The question paper contains to 40 multiple choice questions with four choices and
student will have to pick the correct one (each carrying mark).
1.
2.
3.
4.
5.
6.
7.
( )
( )
(b)
(d)
O (n)
O (n2)
( )
(b)
(d)
Queue
Graph
( )
(b)
(d)
0
1
( )
( )
(c)
(d)
8.
149
( )
( )
9.
If char * name = Dishita",; statement is executed successfully, then what will be the
value of * name?
(a)
D
(b)
Dishita
(c)
Garbage
(d)
None of the above
( )
10.
( )
What is the minimum number of field with each node of doubly linked list?
(a)
1
(b)
2
(c)
3
(d)
4
( )
( )
11.
12.
13.
14.
(b)
(d)
( )
( )
150
15.
( )
16.
17.
A linear list of elements in which deletion can be done from one end and insertion can
take place only at the other end is known is:
(a)
Queue
(b)
Stacks
(c)
Tree
(d)
Branch
( )
18.
19.
( )
( )
( )
20.
21.
22.
151
( )
23.
Which method of traversal does not use stack to hold nodes that are waiting to be
processed >
(a)
Breadth First
(b)
Depth first
(c)
D-search
(d)
None of the above
( )
24.
( )
( )
25.
26.
A balanced binary tree is a binary tree in which the height of the two subtree of every
node never differs by more than:
(a)
2
(b)
1
(c)
3
(d)
None of the above
( )
27.
28.
( )
Which of the following abstract data types can be used to represent a many to many
relation?
(a)
Tree, only
(b)
Plex, only
(c)
Graph, only
(d)
Both B and A
( )
152
29.
30.
31.
32.
33.
34.
35.
(b)
(d)
( )
( )
A technique which collects all detected space in free storage list is called:
(a)
Static memory allocation
(b)
Garbage collection
(c)
Dynamic memory
(d)
None of the above
( )
( )
( )
( )
n +1 nodes
log2 n nodes
( )
36.
37.
38.
39.
40.
153
( )
( )
(b)
(d)
Pendant vertex
Null vertex
( )
Traversing means:
(a)
Accessing and Processing each record exactly once
(b)
Arranging and data in some given order
(c)
Finding the location of the record with a given key
(d)
None of the above
( )
Stack is:
(a)
Static data structure
(b)
In built data structure
(c)
Dynamic data structure
(d)
None of the above
( )
Answer Key
1. (a)
2. (b)
3. (c)
4. (a)
5. (b)
6. (c)
7. (a)
8. (a)
9. (a)
10. (b)
11. (c)
12. (a)
13. (c)
14. (a)
15. (a)
16. (b)
17. (a)
18. (b)
19. (a)
20. (c)
21. (c)
22. (b)
23. (a)
24. (a)
25. (a)
26. (b)
27. (c)
28. (c)
29. (d)
30. (b)
31. (b)
32. (b)
33. (b)
34. (c)
35. (d)
36. (d)
37. (b)
38. (a)
39. (a)
40. (b)
________
154
DESCRIPTIVE PART - II
Year- 2009
Time allowed: 2 Hours
Maximum Marks : 30
Attempt any four descriptive type questions out of the six. All questions carry 7 marks
each.
Q.1
(a)
(b)
Q.2
(a)
(b)
Q.3
(a)
(b)
Q.4
(a)
(b)
Explain the traversal algorithms for a binary tree by taking suitable example.
Short the following list by using heal sort algorithm.
52,7,41,72,23,92,48,15
Q.5
(a)
155
A
A
A
A
(b)
Q.6
What do you mean by Hashing? What is Hash Collision? How do you recover
from the hash collision? Explain you answer by giving a suitable example?
________
156
1.
2.
3.
space used
None
( )
( )
A node contains :
(a)
Information and link field
(b)
Information and data item
(c)
Address and link field
(d)
All of the above
( )
4.
Operating system periodically collect all the deleted space into the free storage list is
called:
(a)
Fragmentation
(b)
Garbage collection
(c)
Overflow
(d)
Underflow
( )
5.
Overflow means:
(a)
NO empty space available
(b)
No item is available
(c)
Error
(d)
none
6.
( )
(b)
(c)
(d)
7.
157
( )
(b)
(d)
( )
8.
Data structure that take insertion and deletion only at beginning or the end, not in the
middle:
(a)
Linked list and linear array
(b)
Stack and queues
(c)
Stack and linked list
(d)
Linked list and queues
( )
9.
10.
11.
12.
13.
(b)
(d)
PUSH
LIFO
( )
( )
(b)
(d)
CD
+AB
( )
( )
( )
(b)
(d)
log n
n1
158
14.
A ..is a linear list of elements in which deletion can take place only at one
end and insertion at other end?
(a)
Stack
(b)
Linked list
(c)
Queue
(d)
Tree
( )
15.
16.
17.
18.
19.
20.
21.
22.
( )
(b)
(d)
Stack
Tree
( )
( )
( )
( )
(b)
(d)
Stack
Tree
( )
(b)
(d)
Stack
Queue
( )
(b)
(d)
G = (B,C)
G = (A,C)
( )
23.
24.
25.
26.
27.
28.
159
(b)
(d)
O (n log2 n)
O (n)
( )
(b)
(d)
O (n)
None
( )
( )
( )
(b)
(d)
7
None
A class is a :
(a)
Abstract data type
(b)
User defined data type
(c)
Binding of data and member function
(d)
All of the above
( )
(a)
(c)
29.
30.
Graph
Tree
(b)
(d)
Multigraph
Weighted graph
( )
BCE
BAED
( )
160
31.
32.
33.
(a)
ABCEA
(c)
BADC
Degree of C i..e. deg (c) is (refer fig A ):
(a)
2
(c)
4
(b)
(d)
CDEA
None
( )
(b)
(d)
3
1
( )
(b)
(d)
BAC
CDE
( )
(b)
(d)
ABDECF
None
( )
DBEACF
None
( )
DBEACF
NONE
( )
(a)
(c)
34.
35.
36.
37.
38.
DBEACF
DEBFCA
( )
( )
Flow lines
(c)
39.
40.
161
Both A & B
(d)
None
( )
(b)
(d)
Subroutine
None
( )
Root node
None
( )
Recursion means:
(a)
function calling itself
(c)
Null function
Answer Key
1. c)
2. (b)
3. (a)
4. (b)
5. (a)
6. (a)
7. (b)
8. (b)
9. (b)
10. (b)
11. (d)
12. (b)
13. (a)
14. (c)
15. (b)
16. (d)
17. (a)
18. (a)
19. (a)
20. (d)
21. (c)
22. (a)
23. (a)
24. (a)
25. (a)
26. (a)
27. (d)
28. (a)
29. (b)
30. (a)
31. (c)
32. (a)
33. (b)
34. (a)
35. (a)
36. (c)
37. (d)
38. (c)
39. (a)
40. (a)
________
162
DESCRIPTIVE PART - II
Year- 2008
Time allowed: 2 Hours
Maximum Marks : 30
Attempt any four descriptive type questions out of the six. All questions carry 7 marks
each.
Q.1
(a)
(b)
Q.2
(a)
(b)
(i)
(ii)
(iii)
Q.3
(a)
(b)
Q.4
(a)
(b)
Q.5
(a)
What is binary tree? Consider a following list and insert an item in order into
an empty binary search tree?
Describe an algorithm for find a minimum spanning tree T of a weighted
graph G.
(b)
Q.6
163
2.
( )
( )
3.
Which of the following sorting algorithm is based on the 'Divide and Conquer'
paradigm?
(a)
Quick sort
(b)
Merge Sort
(c)
Heap Sort
(d)
All of the above
( )
4.
5.
( )
164
6.
The initial configuration of a queue is P,Q, R,S (P is the front end). To the
configuration S,R,Q one needs a minimum of:
(a)
2 addition and 3 deletion
(b)
3 addition and 3 deletion
(c)
3 addition and 4 deletion
(d)
3 addition and 2 deletion
( )
7.
The depth n of the complete binary tree in with a nodes is gives by:
(a)
log2 (n +1) 1
(b)
log2 n+1
(c)
log2 (n1) + 1
(d)
log2 n
( )
( )
8.
9.
One of the more popular balanced trees was introduced in 1962 by adelson-velski and
Landis is known as:
(a)
AVL Tree
(b)
B Tree
(c)
M-way search tree
(d)
None of the above
( )
10.
(a)
(c)
11.
(b)
(d)
Binary tree
Binary search tree
( )
e1
e2
165
e3
e4
(a)
(b)
(c)
(d)
e5
Directed graph
Multigraph
AVL tree
None of the above
( )
12.
The operation of finding the location of a given item in a collection of items is called:
(a)
Sorting
(b) Searching
(c)
Listing
(d)
None of the above
( )
13.
( )
( )
( )
14.
15.
16.
The notation in which operation symbol is placed before its two operands, is called:
(a)
Infix notation
166
(b)
(c)
(d)
17.
Polish notation
Suffix notation
None of the above
( )
( )
18.
When a called function in turn calls another function a process of chaining occurs. A
special case of this process, where a function calls itself is called.
(a)
Recursion
(b)
Deletion
(c)
Insertion
(d)
Overloading
( )
19.
( )
( )
( )
( )
20.
21.
22.
23.
(b)
(d)
Null string
Both A and B
The variables which can be accessed only within a particular program of subprogram
are known as:
(a)
Local variables
(b)
Global variable
(c)
Auto variables
(d)
24.
25.
26.
27.
28.
167
External variables
( )
( )
( )
( )
( )
(a)
(c)
29.
Directed graph
Unconnected graph
(b)
(d)
Undirected graph
AVL tree
( )
A special list maintained with the linked list in memory, which consists of unused
memory cells and has its own pointer is called:
(a)
List of available space
(b)
Free storage list
(c)
Free pool
(d)
All of the above
( )
168
30.
( )
31.
What is the minimum number of fields with each elements of a doubly linked list?
(a)
1
(b)
2
(c)
3
(d)
4
( )
32.
float
ch
( )
33.
The running time T (n), where 'n' is the input size of recursive algorithm is given as
follows: T (n) = c +T (n 1 ;, if n >1, )
D =1, if n<_1
The order of algorithm is:
(a)
n2
(b)
n
(c)
n3
(d)
nn
( )
34.
If we use a 16-bit word length, the maximum size of the integer value is:
(a)
2161
(b)
2151
(c)
2191
(d)
215
( )
35.
A linear list of elements in which deletions can take place only at one end and
insertions can take place only at other end is called:
(a)
Stack
(b)
Queue
(c)
Deque
(d)
Linked list
( )
36.
Sometimes new data are to be inserted into a data structure but there is no available
space i.e. the free storage list is empty. This situation is usually called:
(a)
Underflow
(b)
Overflow
(c)
Overflow
(d)
None of the above
( )
37.
38.
( )
(a)
(b)
(c)
(d)
39.
40.
169
( )
(b)
(d)
( )
A header list where the last node points back to the header node is called :
(a)
A grounded header list
(b)
A circular header list
(c)
Both (A) and (B)
(d)
None of the above
( )
Answer Key
1. (a)
2. (a)
3. (a)
4. (d)
5. (b)
6. (a)
7. (b)
8. (a)
9. (a)
10. (a)
11. (b)
12. (b)
13. (a)
14. (a)
15. (a)
16. (b)
17. (b)
18. (a)
19. (a)
20. (a)
21. (b)
22. (d)
23. (a)
24. (d)
25. (a)
26. (c)
27. (c)
28. (b)
29. (d)
30. (d)
31. (c)
32. (c)
33. (a)
34. (a)
35. (b)
36. (b)
37. (b)
38. (a)
39. (a)
40. (b)
________
170
DESCRIPTIVE PART - II
Year- 2007
Time allowed: 2 Hours
Maximum Marks : 30
Attempt any four descriptive type questions out of the six. All questions carry 7 marks
each.
Q.1
(a)
What is string? Explain various string operations with suitable examples and
show how these operations are used in word processing?
Q.2
(a)
(b)
Q.3
(a)
(b)
What is linked list? Give two advantages of linked lists over arrays.
What is complete binary tree? How is differ from binary tree?
Q.4
(a)
(b)
Q.5
(a)
V4
V4
V4
V4
V4
(b)
V4
171
b
a
Q.6
Sparse matrices;
(b)
Variables:
(c)
(d)
Hasing technique.
________
172
2.
( )
( )
3.
For a sequential search, the average number of comparisons for a file with records is:
(a)
(n+1)/2
(b)
log2 n
2
(c)
n
(d)
n/2
( )
4.
A data structure, in which an element is added and removed only from one end is
known is:
(a)
Queue
(b)
Stack
(c)
Array
(d)
5.
6.
173
( )
( )
( )
7.
What is the minimum number of fields with each element of a doubly linked list?
(a)
1
(b)
2
(c)
3
(d)
4
( )
8.
( )
( )
9.
10.
Which of the following sorting algorithm is based on the idea of "Divide" and
conquer?
(a)
Merge sort
(b)
Heap sort
(c)
Both B and A
(d)
None of the above
( )
174
11.
12.
13.
Bubble search
Selection search
( )
( )
( )
14.
The five items A B C D AND E are pushed in a stack, one after the another starting
from A. The stack is popped four times and each elements is inserted in a queue. The
two element are deleted from the queue and pushed back on the stack. Now one item is
popped from the stack. The popped items is:
(a)
A
(b)
B
(c)
C
(d)
D
( )
15.
( )
( )
( )
16.
17.
18.
Binary Search
Insertion
In which tree for every node the height of its left and right sub tree differ at last by
one?
(a)
Binary search tree
(b)
(c)
(d)
19.
175
AVL tree
Complete Tree
None of the above
( )
( )
20.
When of the following in turn calls another function a process of 'chaining' occurs. A
special case of this process, where a function calls itself is called:
(a)
Recursion
(b) Delection
(c)
Insertion
(d)
Overloading
( )
21.
Which of the following abstract data types can be used to represent a many to many
relation:
(a)
Tree
(b)
Graph
(c)
Both A and B
(d)
None of the above
( )
22.
In the balanced binary tree given below, how many nodes become unbalanced when a
node inserted as a child of the node "g"
a
e
b
d
(a)
(c)
23.
24.
1
7
(b)
(d)
3
8
( )
( )
If we use a 16- bit word length, the size of the integer value is limited to the range:
(a)
26 to 261
(b)
210 to 2101
176
(c)
(d)
25.
26.
28.
( )
( )
If there are n vertices in the graph then how many edges are needed to construct a
minimum spanning tree?
(a)
(c)
27.
215
215
n
n1
(b)
(d)
n+1
n2
( )
( )
(a)
(b)
(c)
(d)
29.
(A + (B * C)) (D * E)
(A+B)* C DE
ABC +*(D*E)
None of the above
( )
( )
30.
31.
177
( )
(a)
(c)
32.
Directed Graph
Unconnected graph
(b)
(d)
Undirected graph
AVL tree
( )
( )
33.
A linear list in which elements can be added or removed at either end but not in the
middle is called:
(a)
Queue
(b)
Dequeue
(c)
Stack
(d)
Linked list
( )
34.
Queue
Linked
( )
O (n log2 n)
O (log2n)
( )
35.
36.
(b)
(d)
178
(d)
37.
38.
( )
( )
( )
39.
When new data are to be inserted into a data structure but there is no available space,
this situation is called :
(a)
Overflow
(b)
Underflow
(c)
Compaction
(d)
Fragmentation
( )
40.
The variables which can be accessed by all modules in a program, are known as:
(a)
Local variables
(b)
Internal variables
(c)
Global variables
(d)
Auto variables
( )
Answer Key
1. (b)
2. (b)
3. (d)
4. (b)
5. (c)
6. (b)
7. (c)
8. (a)
9. (c)
10. (d)
11. (a)
12. (c)
13. (a)
14. (d)
15. (c)
16. (a)
17. (d)
18. (b)
19. (d)
20. (a)
21. (b)
22. (b)
23. (d)
24. (a)
25. (c)
26. (c)
27. (d)
28. (a)
29. (a)
30. (d)
31. (a)
32. (c)
33. (b)
34. (b)
35. (b)
36. (d)
37. (d)
38. (a)
39. (a)
40. (c)
_________
179
DESCRIPTIVE PART - II
Year- 2006
Time allowed: 2 Hours
Maximum Marks : 30
Attempt any four descriptive type questions out of the six. All questions carry 7 marks
each.
Q.1
(a)
(b)
Define array. Discuss the representation of linear arrays in memory and give
any two advantage of linked over arrays.
Q.2
What is a tree? Explain any four types of trees with the help of suitable examples.
Q.3
(a)
(b)
Q.4
180
(a)
(b)
(c)
(d)
Q.5
Write a short note on various data structure operations and explain binary search
algorithm.
Q.6
Recursion
(b)
Polish Notation
(c)
Data Types
(d)
Quick sort.
181
MCQ
1.
(c)
2.
The time factor when determining the efficiency of an algorithm is measured by:
(a)
Counting microseconds
(b)
Counting the number of key operations
(c)
Counting the number of statement
(d)
Counting the Kilobytes of algorithm
(a)
3.
4.
The space factor when determining the efficiency of algorithm is measured by:
(a)
Counting the maximum memory needed by the algorithm
(b)
Counting the minimum memory needed by the algorithm
(c)
Counting the average memory needed by the algorithm
(d)
Counting the maximum disk space needed by the algorithm
(a)
(a)
A queue is a :
(a)
Sequential Organization of data
(b)
Listing of data
(c)
Indexing of data
(d)
None of the above
(a)
5.
6.
7.
182
(c)
(d)
8.
9.
Pointer
All of the above
(b)
O (log n)
O (n log n)
(b)
O (log n)
O (n log n)
(c)
10.
Each array declaration need not give, implicitly or explicitly, the information about:
(a)
the name of array
(b)
the data type of array
(c)
the first data from the set to be stored
(d)
the index set of the array
(c)
11.
(d)
(b)
(d)
12.
13.
14.
15.
(a)
(b)
(c)
(d)
16.
183
(b)
17.
18.
(b)
(a)
(b)
(d)
19.
20.
21.
(b)
(d)
One
Three
184
22.
Which of the following abstract data types are not used by Integer Abstract Data Type
group?
(a)
Short
(b)
Int
(c)
Float
(d)
Long
(c)
23.
24.
(c)
(a)
(a)
(c)
25.
26.
27.
28.
(a)
(b)
(c)
(d)
29.
30.
31.
32.
33.
34.
185
the list must be sorted and one must have direct access to the middle element in
any sub list
the list must be sorted and one must have direct access to the last element in
any sub list
only list is sorted
None of the above
(a)
(b)
Liner array is a :
(a)
List of finite number n of heterogeneous data elements
(b)
List of finite number, n of homogenous data elements
(c)
(a) and (b) both
(d)
None of the above
(b)
How many null branches are there in a binary tree with 20 nodes:
(a)
Zero
(b)
Thirty
(c)
Twenty one
(d)
None of the above
(c)
(a)
(b)
186
(b)
(c)
(d)
35.
(b)
(b)
36.
37.
(a)
Data items that are divided into sub items are called:
(a)
Elementary item
(b)
Group item
(c)
(a) and (b) Both
(d)
None of the above
(a)
(a)
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
187
188
52.
53.
54.
(a)
O (n2)
(b)
(c)
o (n)
(d)
FRONT : = REAR : = NULL, refers to empty
(a)
Stack
(b)
(c)
Array
(d)
The fundamental operations used on a stack are:
(a)
PUSH
(b)
POP
(c)
Both A and B
(d)
None of the above
O (n log2 n)
O (log2n)
(b)
Queue
Linked
(b)
(c)
(a)
(c)
55.
56.
57.
Directed Graph
Unconnected graph
(b)
(d)
Undirected graph
AVL tree
(a )
(d)
(a)
189
58.
59.
60.
62.
63.
(a)
(A + (B * C)) (D * E)
(b)
(A+B)* C DE
(c)
ABC +*(D*E)
(d)
None of the above
Which of the following is an advantage o using pointers:
(a)
Pointers reduce the length and complexity of a program
(b)
They increase the execution speed
(c)
Pointers are more efficient in handling the data tables
(d)
All of the above
Floating point data types are represented by the word:
(a)
int
(b)
floating
(c)
float
(d)
char
(a)
(d)
(c)
If there are n vertices in the graph then how many edges are needed to construct a
minimum spanning tree?
(a)
(c)
61.
n
n1
(b)
(d)
n+1
n2
(c)
If we use a 16- bit word length, the size of the integer value is limited to the range:
(a)
26 to 261
(b)
210 to 2101
(c)
215
(d)
215
(a)
If we use a 16- bit word length, the size of the integer value is limited to the range:
(a)
26 to 261
(b)
210 to 2101
(c)
215
(d)
215
(a)
Which of the following is a non linear data structure?
190
(a)
(c)
64.
Tree only
Array
(b)
(d)
Graph only
Both tree and graph
(d)
In the balanced binary tree given below, how many nodes become unbalanced when a
node inserted as a child of the node "g"
a
e
b
c
65.
66.
67.
68.
69.
70.
(a)
1
(b)
3
(c)
7
(d)
8
(b)
Which of the following abstract data types can be used to represent a many to many
relation:
(a)
Tree
(b)
Graph
(c)
Both A and B
(d)
None of the above
(b)
When of the following in turn calls another function a process of 'chaining' occurs. A
special case of this process, where a function calls itself is called:
(a)
Recursion
(b) Delection
(c)
Insertion
(d)
Overloading
(a)
Which of the following is data structure operation?
(a)
Searching
(b)
Sorting
(c)
Traversing
(d)
All of the above
(d)
In which tree for every node the height of its left and right sub tree differ at last by
one?
(a)
Binary search tree
(b)
AVL tree
(c)
Complete Tree
(d)
None of the above
(d)
Which of the following is not a type of tree?
(a)
Binary
(b)
Binary Search
(c)
AVL
(d)
Insertion
(b)
The process memory allocation at run time is known as:
(a)
Dynamic memory allocation
(b)
Static memory allocation
71.
72.
(c)
Compaction
(d)
The collection of same type of data is called:
(a)
An array
(b)
A union
(c)
A structure
(d)
None of the above
191
fragmentation
(a)
(a)
(c)
73.
Which of the following sorting algorithm is based on the idea of "Divide" and
conquer?
(a)
Merge sort
(b)
Heap sort
(c)
Both B and A
(d)
None of the above
(d)
74.
75.
.76.
77.
Bubble search
Selection search
(a)
(c)
(a)
The five items A B C D AND E are pushed in a stack, one after the another starting
from A. The stack is popped four times and each elements is inserted in a queue. The
192
two element are deleted from the queue and pushed back on the stack. Now one item is
popped from the stack. The popped items is:
(a)
A
(b)
B
(c)
C
(d)
D
(d)
78.
79.
80.
(c)
(b)
(b)
81.
For a sequential search, the average number of comparisons for a file with records is:
(a)
(n+1)/2
(b)
log2 n
(c)
n2
(d)
n/2
(d)
82.
A data structure, in which an element is added and removed only from one end is
known is:
(a)
Queue
(b)
Stack
(c)
Array
(d)
None of the above
(b)
83.
(c)
84.
85.
86.
87.
88.
193
(b)
What is the minimum number of fields with each element of a doubly linked list?
(a)
1
(b)
2
(c)
3
(d)
4
(c)
Worst case complexity of quick sort algorithm is:
(a)
O (n2)
(b)
O (n log n)
(c)
O (lon n)
(d)
None of those
(a)
Average case complexity of heap sort algorithm is:
(a)
O (n log n)
(b)
O (n2)
(c)
O (n)
(d)
O (n log2 n)
(a)
(a)
89.
The notation in which operation symbol is placed before its two operands, is called:
(a)
Infix notation
(b)
Polish notation
(c)
Suffix notation
(d)
None of the above
(b)
90.
(b)
194
91.
When a called function in turn calls another function a process of chaining occurs. A
special case of this process, where a function calls itself is called.
(a)
Recursion
(b)
Deletion
(c)
Insertion
(d)
Overloading
(a)
92.
(a)
(a)
()
( )
93.
94.
95.
96.
(b)
(d)
Null string
Both A and B
The variables which can be accessed only within a particular program of subprogram
are known as:
(a)
Local variables
(b)
Global variable
(c)
Auto variables
(d)
External variables
( )
195
KEY TERMS
abstract data type A set of data values and associated operations that are precisely specified
independent of any particular implementation.
AlgorithmA computable set of steps to achieve a desired result.
asymptotic space complexity
When analyzing the running time or space usage of programs, we usually try to estimate the
time or space as function of the input size.
asymptotic bound
A curve representing the limit of a function. That is, the distance between a function and the
curve tends to zero. The function may or may not intersect the bounding curve.
Access vector A list of pointers providing access to a set of data items.
Algorithm A rule for arriving at an answer in a finite number of steps.
Ancestor A parent of a parent (or an ancestor).
Arc An edge on a directed graph.
Array An elementary data structure that resembles a table; typically, one data element is
stored in each array cell and the cells are distinguished by subscripts.
Attribute A property of an entity.
Binary tree A special type of tree in which each node has two branches.
Branch On a tree, a link between a parent and a child.
Child An immediate lower-level node in a tree.
Circular linked list A linked list in which the last node points back to the first node.
Cycle On a graph, a path that leads from a node back to the same node.
196
Data element An attribute that cannot be logically decomposed; the most basic unit of data
that has logical meaning.
Data structure A way of organizing data that considers both the data items and their
relationships to each other.
Descendant A child of a child (or a descendant).
Directed graph (digraph) A graph on which each edge (or arc) has a direction.
Doubly linked list A linked list in which each node contains both forward and backward
pointers.
Edge On a graph, a link between two nodes.
Entity An object (a person, group, place, thing, or activity) about which data are stored.
Field A data element physically stored on some medium.
File A set of related records.
Graph A set of nodes (or vertexes) linked by a set of edges.
Indegree On a directed graph, the number of arcs entering a given node.
Key The attribute or group of attributes that uniquely distinguishes one occurrence of an
entity.
Leaf (leaf node) On a tree, a node with no branches.
Linked list A list in which each node contains data plus a pointer to the next node.
List A series of nodes each of which holds a single data item; the most basic data structure.
Matrix A two-dimensional array.
Minimum spanning tree Within a graph, a subtree or spanning tree for which the sum of
arc weights is minimal.
197
Multi-linked list A linked list in which each node contains two or more pointers, thus
providing access to two or more other nodes.
Multi-way tree A tree in which each node holds n (two or more) values and can have (n +
1) branches.
Network (weighted graph) A graph on which the edges have values.
Node An entry in a list; often, a single data element or a single record.
Occurrence A single instance of an entity.
Ordered list A list in which the nodes are stored in data value or key order.
Outdegree On a directed graph, the number of arcs exiting from a given node.
Parent The immediate higher-level node in a tree.
Path On a graph, a sequence of edges that links a set of nodes; on a digraph, the paths
direction is significant.
Pointer A link to a data item; typically, a key value or an address.
Pop To remove an entry from the top of a stack.
Push To add an entry to the top of a stack.
Queue A special type of linked list in which insertions occur at the rear and deletions
occur at the front.
Record The set of fields associated with an occurrence of an entity.
Recursion A subroutine calling itself; a subroutine initiating a circular chain of calls that
returns eventually to itself.
Root (root node) A trees top (or base) node.
Siblings Two or more nodes that share the same level.
Singly linked list A linked list in which each node points only to the next node.
198
199
References
Data Structures and Algorithms (Addison-Wesley Series in Computer Science and
Information Pr)
2) data structure schaum series by lipschutz
3) Data Structure ( Tanenbaum book)
4) Data structure by Balaguruswamy.