Académique Documents
Professionnel Documents
Culture Documents
Second Semester
Computer Science and Engineering
CS6202 PROGRAMMING AND DATA STRUCTURES I
(Common to Computer and Communication Engineering and Information Technology)
(Regulation 2013)
Time : Three Hours Maximum : 100 marks
Answer ALL Questions
An Abstract Data Type (ADT) is defined as a mathematical model of the data objects
that make up a data type as well as the functions that operate on these objects. The definition
of ADT has the following two parts:
(i) Description of the way in which components are related to each other.
(ii)Statements of operations that can be performed on that data type.
Example: Objects such as lists, sets and graphs.
Logical behavior of ADT is defined by a set of values and a set of operations.
PART B (5 x 16 = 80 marks)
11. (a) Explain the various control statements in C language with example in detail. (16)
Control statements enable us to specify the flow of program control; ie, the order in which
the instructions in a program must be executed. They make it possible to make decisions, to
perform tasks repeatedly or to jump from one section of code to another.
They are as follows:
1. Branching statements(Discussed above)
2. Iteration(or)Looping statements
3. Jump statements
Iteration statements:
Iteration statements are used to execute a particular set of instructions repeatedly until a
particular condition is met or for a fixed number of iterations.
THE FOR STATEMENT:
The for statement or the for loop repeatedly executes the set of instructions that comprise the
body of the for loop until a particular condition is satisfied.
Syntax:
for(initialization; termination; increment/decrement)
{
//statements to be executed
}
The for loop consists of three expressions:
The initialization expression, which initializes the looping index. The looping index
controls the looping action. The initialization expression is executed only once, when the
loop begins.
The termination expression, which represents a condition that must be true for the loop to
continue execution.
The increment/decrement expression is executed after every iteration to update the value of
the looping index.
The following program uses the for loop to print the Fibonacci series: 0,1,1,2,3,5,8,13 to n
terms.
#include<stdio.h>
int main()
{
int i,n, a, b, sum=0;
printf("Enter the number of terms:");
scanf("%d",&n); a=0; b=1;
printf("%d %d",a,b);
for(i=2;i<n;i++)
{
sum=a+b;
printf(" %d",sum);
a=b;
b=sum;
}
return 0;
}
Output:
Enter the number of terms:
5
01123
The while statement:
The while statement executes a block of statements repeatedly while a particular condition is
true.
while (condition) { //statement(s) to be executed }
The statements are executed repeatedly until the condition is true. Example: Program to
calculate the sum of the digits of a number (eg, 456; 4+5+6 = 15)
#include<stdio.h>
int main()
{
int n, a,sum=0;
printf("\n Enter a number:");
scanf("%d", &n);
while(n>0)
{
a=n%10; //extract the digits of the number
sum=sum+a; //sum the digits
n=n/10; //calculate the quotient of a number when divided by 10.
}
printf("\n Sum of the digits=\t %d",sum);
return 0;
}
Output:
Enter a number
123
Sum of the digits= 6
The above program uses the while loop to calculate the sum of the digits of a number.
Useful when alternative functions maybe used to perform similar tasks on data (eg
sorting).
One common use is in passing a function as a parameter in a function call.
Can pass the data and the function to be used to some control function.
Greater flexibility and better code reuse.
Declaration:
Syntax:
It is optional to use the address operator & infront of the functions name. When you
mention the name of a function but are not calling it, theres nothing else you could possibly
be trying to do except for generating a pointer to it. Similar to the fact that a pointer to the first
element of an array is generated automatically when an array appears in an expression
}
funcPointer= firstExample; //assignment
funcPointer=&firstExample; //alternative using address operator
Case-I
Here, function used itself a pointer.
Example_1:
#include <stdio.h>
#include<conio.h>
void my_int_func(int x)
{
printf( "%d\n", x );
}
void main()
{
void (*foo)(int); /* the ampersand is actually optional */
foo = &my_int_func;
foo(10);
getch();
}
Example_2:
#include<stdio.h>
#include<conio.h>
int *big(int *, int *);
void main()
{
int a=100;
int b=97;
int *p;
p=big(&a,&b);
printf("%d is big", *p);
getch();
}
int *big(int *x, int *y)
{
if(*x>*y)
{
return x;
}
else
{
return y;
}
}
Output:
100 is big
Case-II
We can pass the argument to the function as pointer.
Example_1:
#include<stdio.h>
#include<conio.h>
Output:
15
The secret to passing variable number and type of arguments is the stdarg library. It
provides the va_list data-type, which can contain the list of arguments passed into a
function.
The stdarg library also provides several macros: var_arg, va_start, and va_end that are
useful for manipulating the argument-list.
#include <stdio.h>
#include <stdarg.h>
float avg( int Count, ... )
{
va_list Numbers;
va_start(Numbers, Count);
int Sum = 0;
for(int i = 0; i < Count; ++i )
Sum += va_arg(Numbers, int);
va_end(Numbers);
return (Sum/Count);
}
int main()
{
float Average = avg(10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
printf("Average of first 10 whole numbers : %f\n",
Average); return 0;
}
Output:
Average of first 10 whole numbers : 4.000000
12. (a) Explain the difference between structure and union with examples. (16)
Or
(b) Explain about file manipulations in detail with suitable program. (16)
A file is a collection of bytes stored on a secondary storage device, which is generally a disk
of some kind. The collection of bytes may be interpreted, for example, as characters, words,
lines, paragraphs and pages from a textual document; fields and records belonging to a
database; or pixels from a graphical image. In C, the stream is a common, logical interface to
the various devices that comprise the computer. In its most common form, a stream is a
logical interface to a file.
Essentially there are two kinds of files that programmers deal with text files and binary files.
ASCII Text files:
A text file can be a stream of characters that a computer can process sequentially. It is not
only processed sequentially but only in forward direction. For this reason a text file is usually
opened for only one kind of operation (reading, writing, or appending) at any given time.
Similarly, since text files only process characters, they can only read or write data one
character at a time.
Binary files:
A binary file is no different to a text file. It is a collection of bytes. In C Programming
Language a byte and a character are equivalent. Hence a binary file is also referred to as a
character stream. Binary files can be either processed sequentially or, depending on the needs
of the application they can be processed using random access techniques. In C Programming
Language, processing a file using random access techniques involves moving the current file
position to an appropriate place in the file before reading or writing data.
File pointer:
A file pointer is a pointer to a structure, which contains information about the file, including
its name, current position of the file, whether the file is being read or written, and whether
errors or end of the file have occurred. The user does not need to Know the details, because
the definitions obtained from stdio.h include a structure declaration called FILE. The only
declaration needed for a file pointer is symbolized by
FILE *fp;
This says that fp is the file pointer that points to a FILE structure.
File operations:
Opening Files:
We can use the fopen( ) function to create a new file or to open an existing file, this call will
initialize an object of the type FILE, which contains all the information necessary to control
the stream.
Following is the prototype of this function call:
FILE *fopen( const char * filename, const char * mode );
Here, filename is string literal, which you will use to name your file and access mode can
have one of the following values:
Mode Description
r Opens an existing text file for reading purpose.
w Opens a text file for writing, if it does not exist then a new file is created. Here our
program will start writing content from the beginning of the file.
a Opens a text file for writing in appending mode, if it does not exist then a new file is
created. Here our program will start appending content in the existing file content.
r+ Opens a text file for reading and writing both.
w+ Opens a text file for reading and writing both. It first truncate the file to zero length if
it exists otherwise create the file if it does not exist.
a+ Opens a text file for reading and writing both. It creates the file if it does not exist.
The reading will start from the beginning but writing can only be appended.
If you are going to handle binary files then you will use below mentioned access modes
instead of the above mentioned:
"rb", "wb", "ab", "ab+", "a+b", "wb+", "w+b", "ab+", "a+b"
Closing a File
To close a file, use the fclose( ) function.
The prototype of this function is:
int fclose( FILE *fp );
The fclose( ) function returns zero on success, or EOF if there is an error in closing the file.
This function actually, flushes any data still pending in the buffer to the file, closes the file,
and releases any memory used for the file. The EOF is a constant defined in the header file
stdio.h.
Reading a File
Following is the simplest function to read a single character from a file:
int fgetc( FILE * fp );
The fgetc() function reads a character from the input file referenced by fp. The return value is
the character read, or in case of any error it returns EOF. The following functions allow you
to read a string from a stream:
char *fgets( char *buf, int n, FILE *fp );
The functions fgets() reads up to n - 1 characters from the input stream referenced by fp. It
copies the read string into the buffer buf, appending a null character to terminate the string. If
this function encounters a newline character '\n' or the end of the file EOF before they have
read the maximum number of characters, then it returns only the characters read up to that
point including new line character.
We can also use int fscanf(FILE *fp, const char *format, ...) function to read strings from a
file but it stops reading after the first space character encounters. It can also be used to read
variables of different data types also. For example,
fscanf(fp,"%d%c%s",&a,&b,c); - Used to read integer variable a, character variable b and
string c.
Writing a File
Following is the simplest function to write individual characters to a stream:
int fputc( int c, FILE *fp );
The function fputc() writes the character value of the argument c to the output stream
referenced
by fp. It returns the written character written on success otherwise EOF if there is an error.
You
can use the following functions to write a null-terminated string to a stream:
int fputs( const char *s, FILE *fp );
The function fputs() writes the string s to the output stream referenced by fp. It returns a
nonnegative
value on success, otherwise EOF is returned in case of any error. You can use int
fprintf(FILE *fp,const char *format, ...) function as well to write a string into a file. It can
also be used to display variables of different data types also.
fprintf(fp,"%d\t%c\t%s",a,b,c); - Used to display integer variable a, character variable b and
string c.
Example Programs for File operations:
1. Creating a file and output some data
/* Program to create a file and write some data the file */
#include <stdio.h>
#include <stdio.h>
main( )
{
FILE *fp;
char stuff[25];
int index;
fp = fopen("TENLINES.TXT","w"); /* open for writing */
strcpy(stuff,"This is an example line.");
for (index = 1; index <= 10; index++)
fprintf(fp,"%s Line number %d\n", stuff, index);
fclose(fp); /* close the file before ending program */
}
After the program is executed the following is written to the file TENLINES.TXT
This is an example line Line number 1
This is an example line Line number 2
This is an example line Line number 3
This is an example line Line number 4
This is an example line Line number 5
This is an example line Line number 6
This is an example line Line number 7
This is an example line Line number 8
This is an example line Line number 9
This is an example line Line number 10
2. Reading:
#include <stdio.h>
void main()
{
FILE *fopen(), *fp;
int c;
fp = fopen("prog.c","r");
c = fgetc(fp) ;
while (c!= EOF)
{
putchar(c);
c = getc(fp);
}
fclose(fp);
}
File prog.c is opened in read mode and the file is read character by character till EOF
character and displayed in the screen.
3. Writing
#include <stdio.h>
int main()
{
FILE *fp;
file = fopen("file.txt","w");
/*Create a file and add text*/
fprintf(fp,"%s","This is just an example :)"); /*writes data to the file*/
fclose(fp); /*done!*/
return 0;
}
file.txt contains the line This is just an example after the program is executed.
3. Appending
#include <stdio.h>
int main()
{
FILE *fp
file = fopen("file.txt","a");
fprintf(fp," %s","This is just an example :)"); /*append some text*/
fclose(fp);
return 0;
}
file.txt before execution
Hello
file.txt after execution
Hello This is just an example
Binary I/O Functions:
There are following two functions, which can be used for binary input and output:
size_t fread(void *buffer, size_t size,size_t num, FILE *fp);
The fread() function reads from the file associated with fp, num number of objects, each
object size bytes long, into buffer pointed to by buffer. It returns the number of objects
actually read. If this value is 0, no objects have been read, and either end of file has been
encountered or an error has occurred.
size_t fwrite(void *buffer, size_t size,size_t num, FILE *fp);
The fwrite() function is the opposite of fread(). It writes to fil1 associated with fp, num
number of objects, each object size bytes long, from the buffer pointed to by buffer. It returns
the number of objects written. This value will be less than num only if an output error as
occurred.
int feof(FILE *fp);
The feof() function returns non-0 if the file associated with fp has reached the end of file,
otherwise it returns 0. This function works for both binary files and text files.
int ferror(FILE *fp);
The ferror() function returns non-0 if the file associated with fp has experienced an error,
otherwise it returns 0.
As a simple example, this program write an integer value to a file called MYFILE using its
internal, binary representation.
#include stdio.h /* header file */
#include stdlib.h
void main(void)
{
FILE *fp; /* file pointer */
int i;
/* open file for output */
if ((fp = fopen("myfile", "w"))==NULL){
printf("Cannot open file \n");
exit(1);
}
i=100;
if (fwrite(&i, 2, 1, fp) !=1){
printf("Write error occurred");
exit(1);
}
fclose(fp);
/* open file for input */
if ((fp =fopen("myfile", "r"))==NULL){
printf("Read error occurred");
exit(1);
}
fread(&i,2,1,fp);
printf("i is %d",i);
fclose(fp);
}
Output:
i is 100
Other functions:
rewind()
void rewind(FILE *fp);
We can position a file's current location to the start of the file using rewind().
The following example shows the usage of rewind() function.
#include <stdio.h>
int main()
{
char str[] = "This is a C program";
FILE *fp;
int ch;
/* First let's write some content in the file */
fp = fopen( "file.txt" , "w" );
fwrite(str , 1 , sizeof(str) , fp );
fclose(fp);
fp = fopen( "file.txt" , "r" );
while(!feof(fp))// Displays the contents in the file
{
ch = fgetc(fp);
printf("%c", ch);
}
rewind(fp);//Rewinds the file pointer to the beginning
printf("\n");
while(!feof(fp))//Displays again the contents of the file
{
ch = fgetc(fp);
printf("%c", ch);
}
fclose(fp);
return(0);
}
Let us assume we have a text file file.txt that have the following content
This is a C program
Now let us compile and run the above program to produce the following result
This is a C program
This is a C program
fseek()
int fseek(FILE *stream, long offset, int whence);
The fseek() function is used to set the file position indicator for the stream to a new position.
This function accepts three arguments. The first argument is the FILE stream pointer returned
by the fopen() function. The second argument offset tells the amount of bytes to seek. The
third argument whence tells from where the seek of offset number of bytes is to be done.
The available values for whence are SEEK_SET, SEEK_CUR, or SEEK_END. These three
values (in order) depict the start of the file, the current position and the end of the file.
Upon success, this function returns 0, otherwise it returns -1.
13. (a) Describe the creation of a doubly linked list and appending the list. give relevant
coding in C. (16)
Refer Lab program /Class program
Or
(b) Explain the following:
(i) Application of Lists
(ii) Polynomial manipulation (8 + 8 )
MULTIPLICATION OF POLYNOMIALS:
Multiplication of two polynomials however requires manipulation of each node such that the
exponents are added up and the coefficients are multiplied. After each term of first
polynomial is operated upon with each term of the second polynomial, then the result has to
be added up by comparing the exponents and adding the coefficients for similar exponents
and including terms as such with dissimilar exponents in the result
void Mul()
{
poly *ptr1, *ptr2, *newnode;
ptr1=list1;
ptr2=list2;
if(ptr1 == NULL && ptr2 == NULL)
return;
if(ptr1 == NULL) // I polynomial does not exist
list3 = list2;
elsif(ptr2 ==NULL) // II polynomial does not exist
list3 =list1;
else // Both polynomial exist
{
if(ptr1!=NULL && ptr2!= NULL)
{
while(ptr1!=NULL)
{ newnode=malloc(sizeof(struct poly));
while(ptr2!=NULL)
{
newnode->coeff = ptr1->coeff * ptr2 ->coeff;
newnode->power=ptr1->power + ptr2->power;
list3=create(list3,newnode);
ptr2=ptr2->next;
}
ptr2=list2;
ptr1=ptr1->next;
}
}
}
}
14. (a) Discuss about Stack ADT in detail. Explain any one application of Stack. (16)
STACK
A stack is a linear data structure which follows Last In First Out (LIFO) principle, in which
both insertion and deletion occur at only one end of the list called the Top. Example: pile of
coins.
}
}
int IsFull (Stack S)
{
if (Top = = Arraysize)
return (1);
}
ROUTINE TO POP AN ELEMENT FROM THE STACK
void pop (Stack S)
{
if (IsEmpty (S))
Error ("Empty Stack");
else
{
x = S [Top];
Top = Top - 1;
}
}
int IsEmpty (Stack S)
{
if (S[Top] = = -1)
return (1);
}
ROUTINE TO RETURN TOP ELEMENT OF THE STACK
int TopElement (Stack S)
{
if (! IsEmpty (s))
return S[Top];
else
Error ("Empty Stack");
return 0;
}
LINKED LIST IMPLEMENTATION OF STACK
Push operation is performed by inserting an element at the front of the list.
Pop operation is performed by deleting at the front of the list.
Top operation returns the element at the front of the list.
DECLARATION FOR LINKED LIST IMPLEMENTATION
Struct Node;
typedef Struct Node *Stack;
int IsEmpty (Stack S);
Stack CreateStack (void);
void MakeEmpty (Stack S);
void push (int X, Stack S);
int Top (Stack S);
void pop (Stack S);
/*Linked list declaration*/
Struct Node
{
int Element ;
Struct Node *Next;
};
ROUTINE TO CHECK WHETHER THE STACK IS EMPTY
/*Check whether the stack is empty or not */
int IsEmpty (Stack S)
{
if (SNext = = NULL)
return (1);
}
ROUTINE TO CREATE AN EMPTY STACK
/*To create an empty stack*/
Stack CreateStack ( )
{
Stack S;
S = malloc (Sizeof (Struct Node));
if (S = = NULL)
Error (" Outof Space");
MakeEmpty (s);
return S;
}
/*To make the stack empty*/
void MakeEmpty (Stack S)
{
if (S = = NULL)
Error (" Create Stack First");
else
while (! IsEmpty (s))
pop (s);
}
ROUTINE TO PUSH AN ELEMENT ONTO A STACK
/*Check whether enough memory space to insert*/
void push (int X, Stack S)
{
Struct Node * Temp;
Temp = malloc (sizeof (Struct Node));
if (Temp= = NULL)
Error ("Out of Space");
else
{
Temp Element = X;
Temp Next = S Next;
SNext = Temp;
}
}
ROUTINE TO RETURN TOP ELEMENT IN A STACK
int Top (Stack S)
{
if (! IsEmpty (s))
return SNextElement;
Error ("Empty Stack");
return 0;
}
ROUTINE TO POP FROM A STACK
void pop (Stack S)
{
Struct Node *Tempcell;
If (IsEmpty (S))
Error ("Empty Stack");
Else
{
Tempcell=SNext;
SNext=SNextNext;
Free (Tempcell);
}
}
Application of stack
The problem is moving a collection of N disks of decreasing size from one pillar to another
pillar. The movement of the disk is restricted by the following rules.
Rule 1: Only one disk could be moved at a time.
Rule 2: No larger disk could ever reside on a pillar on top of a smaller disk.
Rule 3: A 3rd pillar could be used as an intermediate to store one or more disks, while they
werebeing moved from sourced to destination.
Recursive Solution
N - represents the number of disks.
Step 1. If N = 1, move the disk from A to C.
Step 2. If N = 2, move the 1st disk from A to B. Then move the 2nd disk from A to C, Then
move the 1st disk from B to C.
Step 3. If N = 3, Repeat the step (2) to more the first 2 disks from A to B using C as
intermediate.
Then the 3rd disk is moved from A to C. Then repeat the step (2) to move 2 disks from
B to C using A as intermediate.
In general, to move N disks. Apply the recursive technique to move N - 1 disks from
A to B using C as an intermediate. Then move the Nth disk from A to C. Then again apply
the recursive technique to move N - 1 disks from B to C using A as an intermediate
Or
(b) Explain about Queue ADT in detail. Explain any one application of Queue with
suitable examples. (16)
[May2015]
Explain QUEUE ADT in detail. (8) [Dec2014]
QUEUE
A Queue is a Linear data structure which follows First In First Out (FIFO) principle, in which
insertion is performed at rear end and deletion is performed at front end.
DEQUEUE(Q) QUEUE Q ENQUEUE(Q)
OPERATIONS ON QUEUE
The fundamental operations performed on queue are: Enqueue and Dequeue.
Enqueue : The process of inserting an element in the queue.
Dequeue : The process of deleting an element from the queue.
EXCEPTIONAL CONDITIONS
Oveflow: Attempt to insert an element into the queue, when the queue is full is said to
be overflow.
Underflow: Attempt to delete an element from the queue, when the queue is empty is
said to be underflow.
IMPLEMENTATION OF QUEUE
Queue can be implemented in 2 ways.
1. Array Implementation
2. Linked List Implementation
ARRAY IMPLEMENTATION
In order to create a queue we require a one dimensional array Q(1:n) and two variables front
and rear. The conventions we shall adopt for these two variables are that front is always 1 less
than the actual front of the queue and rear always points to the last element in the queue.
Thus, front = rear if and only if there are no elements in the queue.
The initial condition is front = rear = -1.
The various queue operations to perform creation, deletion and display the elements in a
queue are as follows:
1. insertQ(): inserts an element at the end of queue Q.
2. deleteQ(): deletes the first element of Q.
3. displayQ(): displays the elements in the queue.
In this implementation queue Q is associated with two pointers namely rear pointer and front
pointer.
To insert an element X onto the Queue Q, the rear pointer is incremented by 1 and
then set Queue [Rear] = X
To delete an element, the Queue [Front] is returned and the Front Pointer is
incremented by 1.
ROUTINE TO ENQUEUE
void Enqueue (int X)
{
if (rear = = max _ Arraysize-1)
print (" Queue overflow");
else
{
rear = rear + 1;
Queue [rear] = X;
if(front==-1)
front=0;
}
}
ROUTINE FOR DEQUEUE
void delete ( )
{
if (front < 0)
print (" Queue Underflow");
else
{
X = Queue [front];
if (front = = rear)
{
front = -1;
rear = -1;
}
else
front = front + 1 ;
}
}
In Dequeue operation, if Front = Rear, then reset both the pointers to their initial values.
(i.e. F = -1, R = -1)
Or
(b) Write an algorithm to sort a set of numbers using quick sort. Trace the algorithm for
the following set of numbers. 88, 11, 22, 44, 66, 99, 32, 67, 54, 10 (16)
88 11 22 44 66 99 32 67 54 10
pivot
11 22 44 66 32 67 54 10 88 99
10 11 22 44 66 32 67 54 88 99
pivot
10 11 22 44 66 32 67 54 88 99
pivot
10 11 22 44 66 32 67 54 88 99
pivot
10 11 22 32 44 66 67 54 88 99
pivot
10 11 22 32 44 66 67 54 88 99
pivot
10 11 22 32 44 54 66 67 88 99
pivot
10 11 22 32 44 54 66 67 88 99
pivot
10 11 22 32 44 54 66 67 88 99
pivot
10 11 22 32 44 54 66 67 88 99
pivot
10 11 22 32 44 54 66 67 88 99