Sei sulla pagina 1di 40

1

EEM 303
Data
Structures
2nd Year B.Tech.
Question Bank
Solutions
Session-2018-2019

By-Shivam Gautam
2

Unit 1_1
What is Data Structure?
Whenever we want to work with large amount of data, then organizing that data is very important.

A data structure can be defined as follows...


Data structure is a method of organizing large amount of data more efficiently so that any
operation on that data becomes easy

Based on the organizing method of a data structure, data structures are divided into two types.
Linear Data Structures- organizing the data in sequential order
Non - Linear Data Structures- organizing the data in random order

Applications of Data Structures-

An array refers to a set of similar elements. It consists of an index. This acts as a pointer to each element
of this structure. Unlike most other data storage types, arrays have a fixed length. Its elements are placed
in a contiguous fashion. Each of the data item has a fixed memory address. An array can have rows and
columns as well. If the value of the index is given for a single record, the values of the other records can
be computed with an easy mathematical calculation.
Applications: Implementation of other data structures, Execution of matrices and vectors, Dynamic
memory allocation, Pointer container, Control tables

By-Shivam Gautam
3

Stack refers to an orderly arrangement of data. It consists of just one end. This end is used for both, data
addition as well as removal. It is said to follow the LIFO pattern, which implies that the last data item to
enter is the first one to be removed. It is also sometimes termed as the pushdown stack. 'Push' and 'Pop'
are the two functions of this data structure. Push is a function defined for adding data, and Pop is for
popping out or deleting the data.
Applications: Evaluation of expressions, Backtracking, Runtime memory management, Arrangement of
books in a library

A queue is a list with a linear pattern which has two ends: front and rear. The front end allows deletion of
data items from the list. The rear end allows insertion of data items into the list. In case of a queue, the
input data doesn't need to be processed immediately. In fact, the data is processed in a FIFO fashion. It is
very efficient for scenarios wherein data is transferred between different processes.
Here, the data sent need not be received at the same rate at which it was sent. A certain system resource is
to be shared between different processes.
Applications: Disk scheduling, CPU scheduling, File IO, Data transmission

By-Shivam Gautam
4

A linked list is a collection of objects which are linked to each other in a linear pattern. Each of these
objects is called a node. The first object is called the front node or the head. Each of the nodes store some
data in them. One important feature of this type of list is that the data is not stored in contiguous
locations. Every object has two components - one is the data part and the other is the address of the node
to which it is pointing. The nodes are not continuous, and can lie in any part of the memory.
Applications: Representation of sparse matrices, Non-contiguous data storage, Implementation of non-
binary tree or other data structures, Dynamic memory management, Equalizing parenthesis, Symbol
tables

A tree consists of a set of nodes which are linked via pointers. Each structure has a root node and
branches containing the remaining data nodes. In case of an ordered tree, the nodes or objects are ordered
in a sequence. In case of an unordered tree, no ordering exists. A tree having no data or nodes is called an
empty or null tree.
Applications: Representation of data lists, Quickly accessible data storage, Representation of hierarchal
data, Routing of algorithms

A file is a collection of multiple records. Each record consists of one or more elements. These elements
are called fields. In case of this data structure, every record is assigned a field and a key. This data
structure is not the same as an array, because in the former, each record may be of a different data type.
Applications: Implementation of computer programs, Data comparison, Storage of data having varying
data types

Unit 1_2
By-Shivam Gautam
5

Algorithm is a step-by-step procedure, which defines a set of instructions to be executed in a certain order
to get the desired output. Algorithms are generally created independent of underlying languages, i.e. an
algorithm can be implemented in more than one programming language.
Example − Design an algorithm to add two numbers and display the result.
step 1 − START
step 2 − declare three integers a, b & c
step 3 − define values of a & b
step 4 − add values of a & b
step 5 − store output of step 4 to c
step 6 − print c
step 7 – STOP
An Algorithm’s efficiency may be denoted by it’s complexity. There are basically 2 types of complexities.
Space Complexity
Space complexity of an algorithm represents the amount of memory space required by the algorithm in its
life cycle. The space required by an algorithm is equal to the sum of the following two components −
A fixed part that is a space required to store certain data and variables, that are independent of the size
of the problem. Eg., constants used
A variable part is a space required by variables, whose size depends on the size of the problem. For
example, dynamic memory allocation, recursion stack space,
etc.
Space complexity S(P) of any algorithm P is S(P) = C + SP(I), where C is the fixed part and S(I) is the
variable part of the algorithm, which depends on instance characteristic I.

Time Complexity
Time complexity of an algorithm represents the amount of time required by the algorithm to run to
completion. Time requirements can be defined as a numerical function T(n), where T(n) can be measured
as the number of steps, provided each step consumes constant time.
For example, addition of two n-bit integers takes n steps. Consequently, the total computational time is T(n)
= c*n, where c is the time taken for the addition of two bits.
Here, we observe that T(n) grows linearly as the input size increases.

By-Shivam Gautam
6

Unit 1_3
A heuristic is a reasoning strategy that is used to solve a problem, make a decision or form a judgement
abut something. Heuristics are typically useful shortcuts.
Examples that employ heuristics include using a rule of thumb, an educated guess, an intuitive
judgment, a guesstimate, stereotyping, profiling, or common sense.
The travelling salesman problem (TSP) asks the following question: "Given a list of cities and the
distances between each pair of cities, what is the shortest possible route that visits each city and returns to
the origin city?"
Heuristic to Solve the Travelling Salesman Problem.
Brute Force Method
Algorithm for TSP using Brute-force method contains the following steps:
Step 1: calculate the total number of tours (where cities represent the number of nodes).
Step 2: draw and list all the possible tours.
Step 3: calculate the distance of each tour.
Step 4: choose the shortest tour; this is the optimal solution.

Unit 1_4
The eight queens puzzle is the problem of placing eight chess queens on an 8×8 chessboard so that no
two queens threaten each other. Thus, a solution requires that no two queens share the same row, column,
or diagonal.
Brute force algorithm
The basic idea of the brute force algorithm is to place the queens on all possible positions and check each
time if the queens cannot capture each other. If not then it has found a solution. Because of the vast
amount of possible positions (NN for a table of size N while each row has 1 queen), this algorithm is not
practical even for small table sizes (like N=12).

Unit 1_5
#include <stdio.h>
#include <math.h>
#define n 10000
void main()
{
int i,j,a[n];
for(i=0;i<n;i++)
a[i]=1;
for(i=2;i<sqrt(n);i++)
for(j=2*i;j<n;j+=i)

By-Shivam Gautam
7

a[j]=0;
for(i=2;i<n;i++)
if(a[i]==1)
printf("%d ,",i);
}

Unit 1_6
Advantages of functions:

1. Program development made easy : Work can be divided among project members
thus implementation can be completed in parallel.
2. Program testing becomes easy : Easy to locate and isolate a faulty function for
further investigation
3. Code sharing becomes possible : A function may be used later by many other
programs this means that a c programmer can use function written by others, instead of
starting over from scratch.
4. Code re-usability increases : A function can be used to keep away from rewriting the
same block of codes which we are going use two or more locations in a program. This
is especially useful if the code involved is long or complicated.
5. Increases program readability : It makes possible top down modular programming.
In this style of programming, the high level logic of the overall problem is solved first
while the details of each lower level functions is addressed later. The length of the
source program can be reduced by using functions at appropriate places.
6. Function facilitates procedural abstraction : Once a function is written, it serves as
a black box. All that a programmer would have to know to invoke a function would be
to know its name, and the parameters that it expects
7. Functions facilitate the factoring of code : Every C program consists of one main( )
function typically invoking other functions, each having a well-defined functionality.

Unit 1_7
#include <stdio.h>
#include <math.h>
void main()
{
int i, c=0,n;
printf("Enter n-");
scanf("%d",&n);
for(i=2;i<sqrt(n);i++)
if(n%i==0)
{c=1;break;}
if(c==0)
printf("Prime");
else printf("Not Prime");

By-Shivam Gautam
8

}
The time complexity of this program is O(√n).

Unit 1_8
#include <stdio.h>
typedef struct{
float real;
float imag;
}complex;
complex a,b,add,sub,mul;
void addition();
void subtract();
void multiply();
void addition()
{
add.real=a.real+b.real;
add.imag=a.imag+b.imag;
printf("\nAddition (%.2f)+i(%.2f)",add.real,add.imag);
}
void subtract()
{

sub.real=a.real-b.real;
sub.imag=a.imag-b.imag;
printf("\nSubtraction (%.2f)+i(%.2f)",sub.real,sub.imag);
}
void multiply()
{
mul.real=a.real*b.real-a.imag*b.imag;
mul.imag=a.real*b.imag+a.imag*b.real;
printf("\nMultiplication (%.2f)+i(%.2f)",mul.real,mul.imag);
}
void main()
{
printf("Enter real and imaginary part of complex no. 1\n");
scanf("%f%f",&a.real,&a.imag);
printf("Enter real and imaginary part of complex no. 2\n");
scanf("%f%f",&b.real,&b.imag);
printf("Entered complex nos. \n (%.2f)+i(%.2f) \n
(%.2f)+i(%.2f)",a.real,a.imag,b.real,b.imag);
addition();
subtract();
multiply();
}

By-Shivam Gautam
9

Unit 1_9
#define max 50
#include <stdio.h>
typedef struct
{
int roll;
char name[20];
float cgpa;
}student;
void main()
{
int n,pmax=0,i;
student stdt[max];
printf("enter no. of students-");
scanf("%d",&n);
for(i=0;i<n;i++)
{printf("\nEnter name, roll no, cgpa of student %d:",(i+1));
scanf("%s%d%f",stdt[i].name,&stdt[i].roll,&stdt[i].cgpa);
if(stdt[i].cgpa>stdt[pmax].cgpa)
pmax=i;}
printf("\nTopper Details");
printf("\nName-%s",stdt[pmax].name);
printf("\nRoll no.-%d",stdt[pmax].roll);
printf("\nCGPA-%.2f",stdt[pmax].cgpa);
}

Unit 1_10
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int roll;
char name[20];
float cgpa;
}student;
void main()
{
int n,pmax=0,i;
student *stdt;
printf("enter no. of students-");
scanf("%d",&n);

By-Shivam Gautam
10

stdt=(student*)calloc(n,sizeof(student));
for(i=0;i<n;i++)
{printf("\nEnter name, roll no, cgpa of student %d:",(i+1));
scanf("%s%d%f",(*(stdt+i)).name,& (*(stdt+i)).roll,& (*(stdt+i)).cgpa);
if((*(stdt+i)).cgpa>(*(stdt+pmax)).cgpa)
pmax=i;}
printf("\nTopper Details");
printf("\nName-%s",(*(stdt+pmax)).name);
printf("\nRoll no.-%d",(*(stdt+pmax)).roll);
printf("\nCGPA-%.2f",(*(stdt+pmax)).cgpa);
free(stdt);
}

Unit 1_11
#include <stdio.h>
#include <stdlib.h>
void main()
{
int i,j,m,n,k,d,c=0,s1,p,g;
char *a,*b,*s;
printf("Assumption: Second no. has greater n. of digits");
printf("\nEnter no. of digits in A\n");
scanf("%d",&m);
a=(char*)calloc(m+1,sizeof(char));
printf("Enter A\n");
scanf("%s",a);
printf("Enter no. of digits in B\n");
scanf("%d",&n);
b=(char*)calloc(m+1,sizeof(char));
printf("Enter B\n");
scanf("%s",b);
g=n+1;
s=(char*)calloc(g+1,sizeof(char));
p=g;
for(i=1;i<=m;i++)
{
s1=a[m-i]+b[n-i]+c-96;
s[p--]=(char)(s1%10+48);
c=s1/10;
}
for(i=m+1;i<=n;i++)
{
s1=b[n-i]+c-48;
s[p--]=(char)(s1%10+48);
}

By-Shivam Gautam
11

s[p]=c+48;
for(i=0;i<=g;i++)
printf("%c",s[i]);
free(a);free(b);free(s);
}

Unit 1_12
A function that calls itself is known as a recursive function. And, this technique is known as
recursion.
In recursion there are basically 2 cases-
•Base Case: case for which the answer is known (and can be expressed without recursion).
•General (recursive) case : The case for which the solution is expressed in terms of a smaller v
ersion of itself .
(a)
int maximum(int a[],int n,int max) (b)
{ int fib(int k)
if(n==0) {
return max; if(k==0||k==1)
if(max<a[n-1]) return k;
max=a[n-1]; return (fib(k-1)+fib(k-2));
maximum(a,n-1,max);} }

Drawbacks in Recursion
i. It requires extra storage space. The recursive calls and automatic variables are stored on the
stack. For every recursive calls separate memory is allocated to automatic variables with the
same name.
ii. Often the algorithm may require large amounts of memory if the depth of the recursion is very
large. If the programmer forgets to specify the exit condition in the recursive function, the
program will execute out of memory.
iii. The recursion function is not efficient in execution speed and time.
iv. Some function calls inside recursion are repeated or duplicated just like Fibonacci.

Unit 1_13
(a)

By-Shivam Gautam
12

(b)

(c)

By-Shivam Gautam
13

Unit 1_14
Editor:
A source code editor is a text editor program designed specifically for editingsource code of
computer programs. It may be a standalone application or it may be built into an integrated
development environment (IDE) or web browser.

Loader:
In computer systems a loader is the part of an operating system that is responsible
for loading programs and libraries. It is one of the essential stages in the process of starting
a program, as it places programs into memory and prepares them for execution.

Linker:
In computer science, a linker is a computer program that takes one or more object files
generated by a compiler and combines them into one, executable program. The linker combines
these separate files into a single, unified program; resolving the symbolic references as it goes
along.

Assembler:
An assembler is a program that converts assembly language into machine code. Most
programs are written in high-level programming languages and are compiled directly to
machine code using a compiler. However, in some cases, assembly code may be used to
customize functions and ensure they perform in a specific way.

Compiler:

By-Shivam Gautam
14

A compiler is a software program that transforms high-level source code that is written by a
developer in a high-level programming language into a low level object code (binary code) in
machine language, which can be understood by the processor.

Interpreter:
In computer science, an interpreter is a computer program that directly executes, i.e.
performs, instructions written in a programming or scripting language, without requiring them
previously to have been compiled into a machine language program.

Operating System:
An operating system or OS is a software program that enables the computer hardware to
communicate and operate with the computer software. Without a computer operating system, a
computer and software programs would be useless. Eg. Windows 10.

Integrated Development Environment (IDE):


An integrated development environment (IDE) is a software application that provides
comprehensive facilities to computer programmers for software development. An IDE normally
consists of a source code editor, build automation tools, and a debugger. Most
modern IDEs have intelligent code completion. Eg. CodeBlocks.

By-Shivam Gautam
15

Unit 2_1
The various operations performed on arrays are-

1. Traversing: It is used to access each data item exactly once so that it can be processed.
Complexity- O(n)
2. Searching: It is used to find out the location of the data item if it exists in the given
collection of data items.
(a) Linear Search -O(n)
(b) Binary Search -O(log(n))
3. Insertion: It is used to add a new data item in the given collection of data items.
Complexity- O(n)
4. Deletion: It is used to delete an existing data item from the given collection of data
items.
Complexity- O(n)
5. Updation: Update operation refers to updating an existing element from the array at a
given index.
Complexity- O(1)
6. Sorting: It is used to arrange the data items in some order i.e. in ascending or
descending order in case of numerical data and in dictionary order in case of
alphanumeric data.
(a) Bubble Sort- O(n2)
(b) Selection Sort- O(n2)
(c) Insertion Sort- O(n2)
7. Merging: It is used to combine the data items of two sorted files into single file in the
sorted form
Complexity- O(nlog(n))

Unit 2_2
(a) (b) (c)
int insert1() int insert2() int insert3()
{ { {
int i,pos; int i; int i;
for(i=0;i<n;i++) for(i=0;a[i]!=-9999;i++);
if(a[i]<=k&&a[i+1]>=k) for(i=n-1;i>=x;i--) a[i]=k;
break; a[i+1]=a[i];
pos=i+1; n=i+1;
for(i=n-1;i>=pos;i--) a[x]=k;
a[i+1]=a[i]; a[n]=-9999;
a[pos]=k; n++;
n++;} } }

By-Shivam Gautam
16

(d) (e)
int delete4() int delete5()
{ {
int b=0,e=n-1,i,mid,pos; int i;n--;
while(b<=e) for(i=x;i<n;i++)
{ a[i]=a[i+1];
mid=(b+e)/2; }
if(a[mid]>k)
e=mid-1;
if(a[mid]<k) (f)
b=mid+1; int delete6()
else {pos=mid;break;} {
} int i,pos;
if(b<=e) for(i=0;a[i]!=-9999;i++)
{ {
n--; if(a[i]==k)
for(i=pos;i<n;i++) pos=i;
a[i]=a[i+1]; if(i>=pos)
a[n]=0; a[i]=a[i+1];}
} n=i;
else printf("%d not found",k); a[n]=-9999;
} }

Unit 2_3
#include<stdio.h>
void main()
{
int arr[] = {1000, 11, 445, 1, 330, 3000};
int n= 6,p=0,max,min,i;
if (n == 1)
{
max = arr[0];
min = arr[0];
p++;
return;
}
else
if (arr[0] > arr[1])
{
max = arr[0];
min = arr[1];
p++;

By-Shivam Gautam
17

}
else
{
max = arr[1];
min = arr[0];
p++;
}

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


{
if (arr[i] > max)
{max = arr[i];p++;}
else if (arr[i] < min)
{min = arr[i];p++;}
}
printf("\nMinimum element is %d", min);
printf("\nMaximum element is %d", max);
printf("\nTotal no. of comparisons for %d elements = %d",n,p);
}
For 6 elements my program did only 3 comparisons.

Unit 2_4
#include <stdio.h>
#include <stdlib.h>
void main()
{int i=0,j=0,k=0,p=0,q=0,*a,*b,*c;
printf("Enter no. of elements in array 1\n");
scanf("%d",&p);
a=(int*)calloc(p,sizeof(int));
printf("Enter elements\n");
for(i=0;i<p;i++)
scanf("%d",&a[i]);
printf("Enter no. of elements in array 2\n");
scanf("%d",&q);
b=(int*)calloc(q,sizeof(int));
printf("Enter elements\n");
for(i=0;i<q;i++)
scanf("%d",&b[i]);
i=0;
c=(int*)calloc(p+q,sizeof(int));
while((i<p)&&(j<q))
{
if(a[i]<=b[j])
c[k]=a[i++];
else c[k]=b[j++];

By-Shivam Gautam
18

k++;
}
while(i<p)
c[k++]=a[i++];
while(j<q)
c[k++]=b[j++];
printf("Merged Array\n");
for(i=0;i<k;i++)
printf("%d ",c[i]);
free(a);freee(b);free(c);
}

Unit 2_5
1. Create arrays A[] and B[] of size m and n and take the input from user.
2. Create an array C[] whose size is equal to maximum of m and n.
3. Copy A to C.
4. Traverse B and do the following in every element in B.
C[i]=C[i]+B[i];

Unit 2_6
1. Create arrays A[] and B[] of size m and n and take the input from user.
2. Create an array C whose size is equal to (m+n-1).
3. Initialize all elements in C as 0’s
4. Traverse all elements in ‘A’with loop variable as ‘i’ and do the following for every
element in A. Traverse all elements in B with loop variable as ‘j’ and do the following in
every element in B.
C[i+j]=C[i+j]+A[i]*B[i];

Unit 2_7
Algorithm to add two polynomials using 2D arrays is as follows:-
Let p and q be the two polynomials represented by arrays-
1. while p and q are not null, repeat.
2. If powers of the two terms are equal then if the terms do not cancel then insert the sum
of the terms into the sum Polynomial Increment p Increment q
Else if ( the power of the first polynomial> power of second ) Then insert the term from
first polynomial into sum polynomial Increment p Else insert the term from second
polynomial into sum polynomial Increment q
3. Copy the remaining terms from the non empty polynomial into the sum polynomial.
4. The third step of the algorithm is to be processed till the end of the polynomials has not
been reached.

Unit 2_8
By-Shivam Gautam
19

Soln awaited….

Unit 2_9
#include <stdio.h>
typedef struct
{
int row;
int col;
int value;
}sparse_mat_term;

int pa=0,pb=0,na,nb,padd=1,i, j,k, n,sum,r,c,v;


sparse_mat_term a[10],b[10],add[20];

void insert(int,int,int,int);
void print(sparse_mat_term,int);
void addition();

void insert(int r, int c, int val,int ch)


{
switch(ch)
{
case 1:
a[pa].row=r;
a[pa].col=c;
a[pa++].value=val;
break;
case 2:
b[pb].row=r;
b[pb].col=c;
b[pb++].value=val;
break;
case 3:
add[padd].row=r;
add[padd].col=c;
add[padd++].value=val;
break;
}}
void printMat(sparse_mat_term mat[],int n)
{
printf("Row\tCol\tValue\n");
for(i=0;i<=n;i++)
printf("%d\t%d\t%d\n",mat[i].row,mat[i].col,mat[i].value);
}

By-Shivam Gautam
20

void addition()
{
add[0].row=a[0].row;
add[0].col=a[0].col;
if (a[0].row != b[0].row || a[0].col != b[0].col)
printf("Matrices can't be added");
else
{
pa=1;pb=1;
while (pa<=na && pb<=nb)
{
if(a[pa].row>b[pb].row||(a[pa].row==b[pb].row&&a[pa].col>b[pb].col))
{
insert(b[pb].row,b[pb].col,b[pb].value,3);
pb++;
}
else if (a[pa].row < b[pb].row || (a[pa].row == b[pb].row && a[pa].col < b[pb].col))
{
insert(a[pa].row,a[pa].col,a[pa].value,3);
pa++;
}
else
{
sum=0;
sum=a[pa].value+b[pb].value;
if (sum!= 0)
insert(a[pa].row,a[pa].col,sum,3);
pa++;
pb++;
}
}
while (pa <= na)
{insert(a[pa].row,a[pa].col,a[pa].value,3);pa++;}
while (pb <= nb)
{insert(b[pb].row,b[pb].col,b[pb].value,3);pb++;}
}
add[0].value=padd-1;
}
void main()
{
for(k=1;k<=2;k++)
{
printf("Input for Sparse matrix %d\n",k);
printf("Enter the no. of rows, columns and the no. of non-zero elements in the sparse matrix \n");
scanf("%d%d%d",&r,&c,&v);
insert(r,c,v,k);

By-Shivam Gautam
21

n=v;
for(i=1;i<=n;i++)
{
printf("Enter the row, col and value of the %d element \n",i);
scanf("%d%d%d",&r,&c,&v);
insert(r,c,v,k);
}
}
na=a[0].value;
nb=b[0].value;
printf("\nSparse Matrix A");
printMat(a,na);
printf("\nSparse Matrix B");
printMat(b,nb);
addition();
printf("\nAddition Matrix");
printMat(add,add[0].value);
}

Unit 2_10
#include <stdio.h>
typedef struct
{
int row;
int col;
int value;
}sparse_mat_term;
void main()
{
int i,j,n,pb;
sparse_mat_term a[10], b[10];
printf("Enter the no. of rows, columns and the no. of non-zero elements\n");
scanf("%d%d%d",&a[0].row,&a[0].col,&a[0].value);
n=a[0].value;
for(i=1;i<=n;i++)
{
printf("Enter the row, col and value of the element %d\n",i);
scanf("%d%d%d",&a[i].row,&a[i].col,&a[i].value);
}
b[0].row=a[0].col;
b[0].col=a[0].row;
b[0].value=a[0].value;
if(n>0)
{
pb=1;

By-Shivam Gautam
22

for(i=0;i<a[0].col;i++)
for(j=1;j<=n;j++)
{
if(a[j].col==i)
{
b[pb].row=a[j].col;
b[pb].col=a[j].row;
b[pb].value=a[j].value;
pb++;
}
}
printf("Row\tCol\tValue\n");
for(i=0;i<=n;i++)
printf("%d\t%d\t%d\n",b[i].row,b[i].col,b[i].value);
}}

Unit 2_11

(a) a ^ b ^ c (b) a + b - c * d / e (c) a / b * c + d – e


Scan Stack exp Scan Stack exp Scan Stack exp
( ( ( ( ( (
a ( a a ( a a ( a
^ (^ a + (+ a / (/ a
b (^ ab b (+ ab b (/ ab
^ (^ ab^ - (- ab+ * (* ab/
c (^ ab^c c (- ab+c c (* ab/c
) ab^c^ * (-* ab+c + (+ ab/c*
d (-* ab+cd d (+ ab/c*d
/ (-/ ab+cd* – (- ab/c*d+
e (-/ ab+cd*e e (+ ab/c*d+e
) ab+cd*e/- ) ab/c*d+e-
Converted Converted Converted
Expression=ab^c^ Expression=ab+cd*e/- Expression=ab/c*d+e-

By-Shivam Gautam
23

Unit 2_12
Infix to Postfix Conversion using Stack Data Structure
To convert Infix Expression into Postfix Expression using a stack data structure, We can use the
following steps...
1. Read all the symbols one by one from left to right in the given Infix Expression.
2. If the reading symbol is operand, then directly print it to the result (Output).
3. If the reading symbol is left parenthesis '(', then Push it on to the Stack.
4. If the reading symbol is right parenthesis ')', then Pop all the contents of stack until
respective left parenthesis is poped and print each poped symbol to the result.
5. If the reading symbol is operator (+ , - , * , / etc.,), then Push it on to the Stack. However,
first pop the operators which are already on the stack that have higher or equal
precedence than current operator and print them to the result.

Unit 2_13
Postfix Expression Evaluation using Stack Data Structure
A postfix expression can be evaluated using the Stack data structure. To evaluate a postfix
expression using Stack data structure we can use the following steps...
1. Read all the symbols one by one from left to right in the given Postfix Expression
2. If the reading symbol is operand, then push it on to the Stack.
3. If the reading symbol is operator (+ , - , * , / etc.,), then perform TWO pop operations and
store the two popped oparands in two different variables (operand1 and operand2). Then
perform reading symbol operation using operand1 and operand2 and push result back on
to the Stack.
4. Finally! perform a pop operation and display the popped value as final result.

Unit 2_14
#include<stdio.h>
#include<conio.h>
#define SIZE 10

int stack[SIZE], top = -1;

void push(int value){


if(top == SIZE-1)
printf("\nStack is Full!!! Insertion is not possible!!!");
else{
top++;
stack[top] = value;
printf("\nInsertion success!!!");
}
}
void pop(){

By-Shivam Gautam
24

if(top == -1)
printf("\nStack is Empty!!! Deletion is not possible!!!");
else{
printf("\nDeleted : %d", stack[top]);
top--;
}
}

Unit 2_15
#include<stdio.h>
#include<conio.h>
#define SIZE 10

int queue[SIZE], front = -1, rear = -1;

void enQueue(int value)


{
if(rear == SIZE-1)
printf("\nQueue is Full!!! Insertion is not possible!!!");
else{
if(front == -1)
front = 0;
rear++;
queue[rear] = value;
printf("\nInsertion success!!!");
}
}
void deQueue(){
if(front == rear)
printf("\nQueue is Empty!!! Deletion is not possible!!!");
else{
printf("\nDeleted : %d", queue[front]);
front++;
if(front == rear)
front = rear = -1;
}
}

Unit 2_16
Circular Queue:
• It is a linear data structure in which the operations are conducted on the basis of FIFO or First
In First Out principle. The last position is connected to the first position to make a circle.
Advantages
1. It takes up less memory than the linear queue.
2. A new item can be inserted in the location from where a previous item is deleted.

By-Shivam Gautam
25

3. Infinite number of elements can be added continuously but deletion must be used.

#define MAXSIZE 5
#include <stdio.h>
int Q[MAXSIZE],front=-1,rear=-1;
void main()
{
int ch,val;
void enqueue(int);
int dequeue();
printf("1-Enqueue\t2-Dequeue\t3-Exit\n");
printf("Enter Choice");
scanf("%d",&ch);
do
{
switch(ch)
{
case 1:
printf("Enter Element to be Inserted\n");
scanf("%d",&val);
enqueue(val);
break;
case 2:
printf("Deleted Element-%d\n",dequeue());
break;
}
printf("Enter Choice- ");
scanf("%d",&ch);
}while(ch!=3);
}
void enqueue(int x)
{
if(front==(rear+1)%MAXSIZE)
printf("Queue Full\n");
else
{
if(front==-1)
front=rear=0;
else rear=(rear+1)%MAXSIZE;
Q[rear]=x;
}
return;
}
int dequeue()
{
int num;
if(front==-1)
printf("Queue Empty\n");
else
{
num=Q[front];

By-Shivam Gautam
26

if(front==rear)
front=rear=-1;
else
front=(front+1)%MAXSIZE;
}return num;
}

Unit 2_17
(a) (b) }
int len(char s[]) char s3[]; (c)
{ void cnct( char s1[],char char s2[];
int i; s2[]) void copy(char s1[])
{ int i,j; {
for(i=0;s[i]!='\0';i++); for(i=0;s1[i]!='\0';i++) int i;
s3[i]=s1[i]; for(i=0;s1[i]!='\0';i++)
return i; for(j=0;s2[j]!='\0';j++) s2[i]=s1[i];
} {s3[i]=s2[j];i++;} }

Unit 2_18
int compare(char * s1, char * s2)
{
s1=tolower(s1);
s2=tolower(s2);
int i = 0;
while(s1[i] == s2[i])
{
if(s1[i] == '\0' && s2[i] == '\0')
break;
i++;
}
return s1[i] - s2[i];
}

By-Shivam Gautam
27

Unit 3_1
• Pointers in C language is a variable that stores/points the address of another variable. A Pointer in C
is used to allocate memory dynamically i.e. at run time. The pointer variable might be belonging to
any of the data type such as int, float, char, double, short etc.
• Pointer Syntax : data_type *var_name; Example : int *p; char *p;
• Where, * is used to denote that “p” is pointer variable and not a normal variable.

KEY POINTS TO REMEMBER ABOUT POINTERS IN C:


• Normal variable stores the value whereas pointer variable stores the address of the variable.
• The content of the C pointer always be a whole number i.e. address.
• Always C pointer is initialized to null, i.e. int *p = null.
• The value of null pointer is 0.
• & symbol is used to get the address of the variable.
• * symbol is used to get the value of the variable that the pointer is pointing to.
• If a pointer in C is assigned to NULL, it means it is pointing to nothing.
• Two pointers can be subtracted to know how many elements are available between these two pointers.
• But, Pointer addition, multiplication, division are not allowed.

Unit 3_2
Deleting a Specific Node from the list
We can use the following steps to delete a specific node from the single linked list...
• Step 1: Check whether list is Empty (head == NULL)

By-Shivam Gautam
28

• Step 2: If it is Empty then, display 'List is Empty!!! Deletion is not possible' and terminate the
function.
• Step 3: If it is Not Empty then, define two Node pointers 'temp1' and 'temp2' and initialize
'temp1' with head.
• Step 4: Keep moving the temp1 until it reaches to the exact node to be deleted or to the last node.
And every time set 'temp2 = temp1' before moving the 'temp1' to its next node.
• Step 5: If it is reached to the last node then display 'Given node not found in the list! Deletion
not possible!!!'. And terminate the function.
• Step 6: If it is reached to the exact node which we want to delete, then check whether list is
having only one node or not
• Step 7: If list has only one node and that is the node to be deleted, then set head = NULL and
delete temp1 (free(temp1)).
• Step 8: If list contains multiple nodes, then check whether temp1 is the first node in the list
(temp1 == head).
• Step 9: If temp1 is the first node then move the head to the next node (head = head → next) and
delete temp1.
• Step 10: If temp1 is not first node then check whether it is last node in the list (temp1 → next
== NULL).
• Step 11: If temp1 is last node then set temp2 → next = NULL and delete temp1 (free(temp1)).
• Step 12: If temp1 is not first node and not last node then set temp2 → next = temp1 → next and
delete temp1 (free(temp1)).

Unit 3_3
Operations on Singly linked List
In a single linked list we perform the following operations-
1. Insertion
In a single linked list, the insertion operation can be performed in three ways. They are as follows...
1. Inserting At Beginning of the list
2. Inserting At End of the list
3. Inserting At Specific location in the list
2. Deletion
In a single linked list, the deletion operation can be performed in three ways. They are as follows...
1. Deleting from Beginning of the list
2. Deleting from End of the list
3. Deleting a Specific Node
3. Traversal
In a single linked list, the traversal operation can be performed in two ways. They are as follows...
1. In Order Traversal
2. Reverse Order Traversal
4. Search for a specific node.
5. Display all the elements of Linked List

Operations that can be performed in Constant Time


1. Insertion at Beginning
2. Deletion at Beginning

By-Shivam Gautam
29

Unit 3_4

By-Shivam Gautam
30

Linked List vs Array


Advantages of Linked List over arrays:

1. Dynamic size.
As and when we need to, we can allocate memory to insert more nodes in the linked list.
We don’t have to know the size beforehand with linked lists.
2. Ease of insertion/deletion.
No shifting is required in insertion and deletion operations.
In an array, we have to shift elements to make space to insert a new one or shift elements to occupy
the position of a deleted element after deletion.
With linked lists, all we have to do is rewire pointers which takes constant time.
3. There is no possibility of memory wastage.
We are allocating memory only when needed.
The possibility of unused allocated memory does not arise with linked lists.

Drawbacks of Linked List compared to arrays:

1. Linked list support sequential access only.


Starting at a given node, we can only access the node that it contains a pointer to.
Random access is not allowed. So we cannot do binary search with linked lists.
2. Extra memory space for a pointer is required.
With each element of the list, we also need space to store the address of the next node.
Arrays only need space for the elements.
Arrays have better cache locality.
This affects run time and causes a pretty big difference in performance.

Unit 3_5
int isCircular(struct Node *head)
{
// An empty linked list is circular
if (head == NULL)
return 1;
// Next of head
struct Node *node = head->next;
// This loop would stop in both cases (1) If Circular (2) Not circular
while (node != NULL && node != head)
node = node->next;
// If loop stopped because of circular
// condition
if(node == head)
return 1;
else return 0;
}

Unit 3_6
By-Shivam Gautam
31

algorithm merge(A, B) is
inputs A, B : list
returns list

C := new empty list


while A is not empty and B is not empty do
if head(A) ≤ head(B) then
append head(A) to C
drop the head of A
else
append head(B) to C
drop the head of B

// By now, either A or B is empty. It remains to empty the other input list.


while A is not empty do
append head(A) to C
drop the head of A
while B is not empty do
append head(B) to C
drop the head of B

return C

Unit 3_7

By-Shivam Gautam
32

Advantages over singly linked list


1) A DLL can be traversed in both forward and backward direction.
2) The delete operation in DLL is more efficient if pointer to the node to be deleted is given.
3) We can quickly insert a new node before a given node.
In singly linked list, to delete a node, pointer to the previous node is needed. To get this previous node,
sometimes the list is traversed. In DLL, we can get the previous node using previous pointer.

Disadvantages over singly linked list ( Extra: Not asked in Question)


1) Every node of DLL Require extra space for an previous pointer. It is possible to implement DLL with
single pointer though.
2) All operations require an extra pointer previous to be maintained. For example, in insertion, we need to
modify previous pointers together with next pointers. For example in following functions for insertions at
different positions, we need 1 or 2 extra steps to set previous pointer.

Unit 3_8
Structure Assumed-
typedef struct node_type
{
int data;
struct node_type *next;
}node;

(i)
void insertAtEnd(int item)
{
node *p,*loc;
p= (node*)malloc(sizeof(node));
p-> data = item;
p->next=(node*)NULL;
if(head==(node*)NULL)
head=p;
else

By-Shivam Gautam
33

{loc=head;
while(loc -> next != (node*)NULL)
{loc=loc->next;}
loc->next=p;
}}
(ii)
void deleteSpecific(int value)
{
node *p, *loc,temp;
loc=(node*)NULL;
p=head;
while(p!=(node*)NULL)
{
if(p->data==value)
{loc=p;break;}
temp=p;
p=p->next;
}
if(loc!=(node*)NULL)
{
temp->next=loc->next;
p=temp;
free(loc);
}}
(iii)
void display()
{
node *p;
p=head;
while(p!=(node*)NULL)
{
printf(“%d\n”,p->data);
p=p->next;
}}
(iv)
print_rev_order(node *p)
{
if(p!=(node*)NULL)
print_rev_order(p->next);
printf(“(“%d\n”, p->data);
}
(v)
Soln. awaited…

Unit 3_9
Structure Assumed-
typedef struct node_type
{
struct node_type *prev;

By-Shivam Gautam
34

int data;
struct node_type *next;
}node;

(i)
void append(struct Node** head_ref, int new_data)
{
// 1. allocate node
struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
struct Node* last = *head_ref; //used in step 5
// 2. put in the data
new_node->data = new_data;
//3. This new node is going to be the last node, so make next of it as NULL
new_node->next = NULL;
//4. If the Linked List is empty, then make the new node as head
if (*head_ref == NULL) {
new_node->prev = NULL;
*head_ref = new_node;
return;
}
// 5. Else traverse till the last node
while (last->next != NULL)
last = last->next;
// 6. Change the next of last node
last->next = new_node;
// 7. Make last node as previous of new node
new_node->prev = last;
return;
}
(ii)
void deleteNode(struct Node** head_ref, struct Node* del)
{
/* base case */
if (*head_ref == NULL || del == NULL)
return;
/* If node to be deleted is head node */
if (*head_ref == del)
*head_ref = del->next;
/* Change next only if node to be deleted is NOT
the last node */
if (del->next != NULL)
del->next->prev = del->prev;
/* Change prev only if node to be deleted is NOT
the first node */
if (del->prev != NULL)
del->prev->next = del->next;
/* Finally, free the memory occupied by del*/
free(del);
}

(iii)

By-Shivam Gautam
35

void display()
{
node *ptr;
ptr=head;
while(ptr)
{
printf("%d\n",ptr->data);
ptr=ptr->next;
}}
(iv)
void display_rev()
{
node *ptr;
ptr=tail;
while(ptr)
{
printf("%d\n",ptr->data);
ptr=ptr->prev;
}}
(v)
Soln awaited…

Unit 3_10
Method :
Traverse linked list using two pointers. Move one pointer by one and other pointer by two. When the fast
pointer reaches end slow pointer will reach middle of the linked list.
void printMiddle(struct Node *head)
{
struct node *slow_ptr = head;
struct node *fast_ptr = head;

if (head!=NULL)
{
while (fast_ptr != NULL && fast_ptr->next != NULL)
{
fast_ptr = fast_ptr->next->next;
slow_ptr = slow_ptr->next;
}
printf("The middle element is [%d]\n\n", slow_ptr->data);
}
}

Unit 3_11
void reverse()
{
node *current = head;

By-Shivam Gautam
36

node *prev = NULL, *next = NULL;


while (current != NULL)
{
// Store next
next = current->next;// Reverse current node's pointer
current->next = prev;// Move pointers one position ahead.
prev = current;
current = next;
}
head = prev;
}

Unit 3_12
typedef struct node_type
{
int data;
struct node_type *next;
}node;
node *top,*ptr;
int count=0;
void create_empty_stack()
{
top=(node*)NULL;
}
void isempty()
{
if(top=(node*)NULL)
return 0;
return -1;
}
void push(int item)
{ptr=(node*)malloc(sizeof(node));
ptr->data=item;
if(top==(node*)NULL)
{
ptr->next=(node*)NULL;
top=ptr;
}
else
{
ptr->next=top;
top=ptr;
}count++;
}
int pop()
{
node *temp;
int x;
if(temp==(node*)NULL)

By-Shivam Gautam
37

{
printf("Trying to pop from an empty Stack\n");
return;
}
else
printf("The popped value is %d\n",temp->data);
x=temp->data;
top=temp->next;
free(temp);
count--;
return x;
}}

Unit 3_13
typedef struct node_type
{
struct node_type *prev;
int data;
sruct node_type *next;
}node;
node *front, *rear, *ptr;
void create_empty_Queue()
{
front=rear=(node*)NULL;
}
void enqueue(int item)
{
ptr=(node*)malloc(sizeof(node));
ptr->data=item;
if(rear==(node*)NULL)
{
ptr->next=ptr->prev=(node*)NULL;
front=rear=ptr;
}
else
{
ptr->next=rear;
ptr->prev=(node*)NULL;
(
rear->next)->prev=ptr;
}
rear=ptr;
return;
}
int dequeue()
{
int temp;
node *ptr;
if(front==(node*)NULL)

By-Shivam Gautam
38

printf("Cannot Dequeue");
else
{
ptr=front;
front=ptr->prev;
(ptr->prev)->next=(node*)NULL;
temp=ptr->data;
free(ptr);
return temp;
}}
}

Unit 3_14
#include<stdio.h>
#include<stdlib.h>
typedef struct link {
int coeff;
int pow;
struct link * next;
} my_poly;

void my_create_poly(my_poly **);


void my_show_poly(my_poly *);
void my_add_poly(my_poly **, my_poly *, my_poly *);

int main(void) {
int ch;
do {
my_poly * poly1, * poly2, * poly3;

printf("\nCreate 1st expression\n");


my_create_poly(&poly1);
printf("\nStored the 1st expression");
my_show_poly(poly1);

printf("\nCreate 2nd expression\n");


my_create_poly(&poly2);
printf("\nStored the 2nd expression");
my_show_poly(poly2);

my_add_poly(&poly3, poly1, poly2);


my_show_poly(poly3);

printf("\nAdd two more expressions? (Y = 1/N = 0): ");


scanf("%d", &ch);
} while (ch);
return 0;
}

By-Shivam Gautam
39

void my_create_poly(my_poly ** node) {


int flag; //A flag to control the menu
int coeff, pow;
my_poly * tmp_node; //To hold the temporary last address
tmp_node = (my_poly *) malloc(sizeof(my_poly)); //create the first node
*node = tmp_node; //Store the head address to the reference variable
do {
//Get the user data
printf("\nEnter Coeff:");
scanf("%d", &coeff);
tmp_node->coeff = coeff;
printf("\nEnter Pow:");
scanf("%d", &pow);
tmp_node->pow = pow;
//Done storing user data

//Now increase the Linked on user condition


tmp_node->next = NULL;

//Ask user for continuation


printf("\nContinue adding more terms to the polynomial list?(Y = 1/N = 0): ");
scanf("%d", &flag);
//printf("\nFLAG: %c\n", flag);
//Grow the linked list on condition
if(flag) {
tmp_node->next = (my_poly *) malloc(sizeof(my_poly)); //Grow the list
tmp_node = tmp_node->next;
tmp_node->next = NULL;
}
} while (flag);
}
void my_show_poly(my_poly * node) {
printf("\nThe polynomial expression is:\n");
while(node != NULL) {
printf("%dx^%d", node->coeff, node->pow);
node = node->next;
if(node != NULL)
printf(" + ");
}
}
void my_add_poly(my_poly ** result, my_poly * poly1, my_poly * poly2) {
my_poly * tmp_node; //Temporary storage for the linked list
tmp_node = (my_poly *) malloc(sizeof(my_poly));
tmp_node->next = NULL;
*result = tmp_node; //Copy the head address to the result linked list

//Loop while both of the linked lists have value


while(poly1 && poly2) {
if (poly1->pow > poly2->pow) {
tmp_node->pow = poly1->pow;
tmp_node->coeff = poly1->coeff;

By-Shivam Gautam
40

poly1 = poly1->next;
}
else if (poly1->pow < poly2->pow) {
tmp_node->pow = poly2->pow;
tmp_node->coeff = poly2->coeff;
poly2 = poly2->next;
}
else {
tmp_node->pow = poly1->pow;
tmp_node->coeff = poly1->coeff + poly2->coeff;
poly1 = poly1->next;
poly2 = poly2->next;
}

//Grow the linked list on condition


if(poly1 && poly2) {
tmp_node->next = (my_poly *) malloc(sizeof(my_poly));
tmp_node = tmp_node->next;
tmp_node->next = NULL;
}
}
//Loop while either of the linked lists has value
while(poly1 || poly2) {
//We have to create the list at beginning
//As the last while loop will not create any unnecessary node
tmp_node->next = (my_poly *) malloc(sizeof(my_poly));
tmp_node = tmp_node->next;
tmp_node->next = NULL;
if(poly1) {
tmp_node->pow = poly1->pow;
tmp_node->coeff = poly1->coeff;
poly1 = poly1->next;
}
if(poly2) {
tmp_node->pow = poly2->pow;
tmp_node->coeff = poly2->coeff;
poly2 = poly2->next;
}
}

printf("\nAddition Complete");
}

By-Shivam Gautam

Potrebbero piacerti anche