Data Structure Note by Bhupendra Saud
Data Structure Note by Bhupendra Saud
Data Structure Note by Bhupendra Saud
com
Prerequisites:
Knowledge of C
Note:- The complete C programs involved in this note are not study in detailed for the
point of exam view these are only for practical purpose.
For point of exam view writing algorithms and functions are important
Unit 1:
Concept and definition of data structures
Information and its meaning
Array in C
The array as an ADT
One dimensional array
Two dimensional array
Multidimensional array
Structure
Union
Pointer
A static data structure is one whose capacity is fixed at creation. For example, array. A
dynamic data structure is one whose capacity is variable, so it can expand or contract at any
time. For example, linked list, binary tree etc.
Once an abstract data type has been designed, the programmer responsible for implementing
ep
that type is concerned only with choosing a suitable data structure and coding up the methods.
On the other hand, application programmers are concerned only with using that type and
calling its methods without worrying much about how the type is implemented.
itn
Data structure
Primitive Non-
Data structure Primitive
Data structure
Queue
Graphs
Array
Array is a group of same type of variables that have common name
Each item in the group is called an element of the array
Each element is distinguished from another by an index
All elements are stored contiguously in memory
The elements of the array can be of any valid type- integers, characters, floating-
point types or user-defined types
Types of Array:
1). One dimensional array:
The elements of the array can be represented either as a single column or as a
single row.
int marks[100];
DSA 2 By Bhupendra Saud
cs
Source: www.csitnepal.com
char section[12];
char name[10];
Following are some invalid array declarations in c:
int value[0];
int marks[0.5];
int number[-5];
Example 1: A program to read n numbers and to find the sum and average of those
numbers.
#include<stdio.h>
void main()
{
int a[100], i, n, sum=0;
float avg;
printf(Enter number of elements);
scanf(%d,&n);
printf(Enter %d numbers,n);
for(i=0;i<n;i++)
{
scanf(%d,&a[i]);
sum=sum+a[i];
//sum+=a[i];
}
avg=sum/n;
printf(sum=%d\n Average=%f, sum, avg);
}
a[6]=(1,5,7,6,22,90};
Suppose we want to insert 20 in array a, at location with index 4, it means the elements
ep
a[2] 7 a[2] 7
a[2] 7
a[3] 6 a[3] 6
a[3] 6
a[4] 22 a[4] 20
a[4] ..
a[5] 90 a[5] 22
{
printf(%d\t, a[i]);
ep
}
getch();
}
itn
a[2] 7 a[2] 7
a[2] 7
a[3] 6 a[3] 6
a[3] 6
a[4] 22 a[4] 22
a[4] 22
a[5] 90 a[5] 30
a[5]
a[6] 30 a[6] 10
a[6] 30
a[7] 10 a[7] 50
a[7] 10
a[8] 50 a[8] 8
a[8] 50
a[9] 8 a[9]
a[9] 8
Fig: - Deleting an element from one-dimensional array
C- code for above problem:
#include<stdio.h>
#include<conio.h>
void main()
{
int a[100], pos, i;
clrscr();
printf(Enter no of elements to be inserted);
scanf(%d, &n);
printf(Enter %d elements, n);
for(i=0;i<n;i++)
{
scanf(%d, &a[i]);
}
printf(Enter position at which you want to delete an element);
scanf(%d, &pos);
for(i=pos; i<n; i++)
{
a[i] = a[i+1];
}
n--;
printf(New array is:\n);
for(i=0; i<n; i++)
al
{
printf(%d\t, a[i]);
ep
}
}
itn
Traversing of an array:
Traversing means to access all the elements of the array, starting from first
element upto the last element in the array one-by-one.
printf(%d\t, a[i]);
}
ep
getch();
}
itn
c[0] 1
a[0] 1 b[0] 20 c[1] 5
c[2] 7
a[1] 5 b[1] 25 c[3] 6
c[4] 12
a[2] 7 b[2] 30 c[5] 15
c[6] 20
a[3] 6 b[3] 35 c[7] 25
c[8] 30
a[4] 12 c[9] 35
a[5] 15
}
DSA 7 By Bhupendra Saud
cs
Source: www.csitnepal.com
getch();
}
Two-Dimensional array:
When we declare two dimensional array, the first subscript written is for the number of
rows and the second one is for the column.
Declaration of 2- D array:
Return_type array_name[row_size][column_size];
Example;
int a[3][4];
float b[10][10];
int this first example, 3 represents number of rows and 4 represents number of columns.
Row 0 a[ 0 ][ 0 ] a[ 0 ][ 1 ] a[ 0 ][ 2 ] a[ 0 ][ 3 ]
Row 1 a[ 1 ][ 0 ] a[ 1 ][ 1 ] a[ 1 ][ 2 ] a[ 1 ][ 3 ]
Row 2
a[ 2 ][ 0 ] a[ 2 ][ 1 ] a[ 2 ][ 2 ] a[ 2 ][ 3 ]
Column subscript
Array name
Row subscript
{
for(j=0;j<c;j++)
{
itn
scanf(%d,&a[i][j]);
DSA 9 By Bhupendra Saud
cs
Source: www.csitnepal.com
}
}
//finding transpose of a matrix
for(i=0;i<r;i++)
{
for(j=0;j<c;j++)
{
t[i][j]=a[j][i];
}
}
printf(the original matrix is\n);
display(a, r, c); //function call
printf(the transposed matrix is\n);
display(t, r, c); //function call
}
void display(int x[][], int r, int c) //function definition
{
int i, j;
for(i=0;i<r;i++)
{
for(j=0;j<c;j++)
{
printf(%d\t,x [i][j]);
}
printf(\n);
}
}
Row-major implementation:
Row-major implementation is a linearization technique in which elements of array are
reader from the keyboard row-wise i.e. the complete first row is stored, and then the
complete second row is stored and so on. For example, an array a[3][3] is stored in the
memory as shown in fig below:
Column-major implementation:
al
i.e. at first the elements of the complete first column is stored, and then elements of
itn
Multi-Dimensional array
C also allows arrays with more than two dimensions. For example, a three
dimensional array may be declared by
int a[3][2][4];
Here, the first subscript specifies a plane number, the second subscript a row number
and the third a column number.
Plane 2
Plane 1
Plane 0
Row 0
Row 1
Structure:
A structure is a collection of one or more variables, possibly of different types,
grouped together under a single name.
An array is a data structure in which all the members are of the same data type. Structure
is another data structure in which the individual elements can differ in type. Thus, a
single structure might contain integer elements, floating-point elements and character
elements. The individual structure elements are referred to as members.
Defining a structure: A structure is defined as
struct structure_name
{
member 1;
member 2;
..
member n;
};
We can combine both template declaration and structure variable declaration in one
statement.
Eg,
struct Student
{
char name[2];
int roll;
char sec;
float marks;
al
Structure initialization:
Like any data type, a structure variable can be initialized as follows:
struct Student
{
char name[20];
int roll;
char sec;
float marks;
};
struct Student s1={Raju, 22, A, 55.5};
The s1 is a structure variable of type Student, whose members are assigned initial
values. The first member (name[20[) is assigned the string Raju, the second member
(roll) is assigned the integer value 22, the third member (sec) is assigned the character
A, and the fourth member (marks) is assigned the float value 55.5.
Example: program illustrates the structure in which read member elements of
structure and display them.
#include<stdio.h>
void main()
{
struct Student
{
char name[20];
int roll;
char sec;
float marks;
};
struct Student s1;
clrscr();
printf(Enter the name of a student);
gets(s1.name);
printf(Enter the roll number of a student);
scanf(%d,&s1.roll);
printf(Enter the section of a student);
scanf(%c,&s1.sec);
printf(Enter the marks obtained by the student);
scanf(%f,&s1.marks);
//displaying the records
printf(Name=%s\n Roll number =%d\n Section=%c\n Obtained marks=%f,s1.name,
s1.roll, s1.sec, s1.marks);
}
al
Unions:
Both structure and unions are used to group a number of different variables
together. Syntactically both structure and unions are exactly same. The main difference
between them is in storage. In structures, each member has its own memory location but
all members of union use the same memory location which is equal to the greatest
members size.
Declaration of union:
The general syntax for declaring a union is:
union union_name
{
data_type member1;
data_type member2;
data_type member3;
data_type memberN;
};
char sec;
float marks;
ep
Pointer Declaration
Pointer variables, like all other variables, must be declared before they may be used in a
C program. We use asterisk (*) to do so. Its general form is:
ata-type *ptrvar;
For example,
al
int* ptr;
ep
float *q;
char *r;
itn
Pointer initialization:
Once a pointer variable has been declared, it can be made to point to a variable
using an assignment statement as follows:
int marks;
int *marks_pointer;
Marks_pointer=&marks;
Pass by value: In this method, the value of each of the actual arguments in the calling
function is copied into corresponding formal arguments of the called function. With this
method the changes made to the formal arguments in the called function have no effect
on the values of actual arguments in the calling function. The following program
illustrates call by value.
#include<stdio.h>
#include<conio.h>
void main()
{
int a,b;
void swap(int, int );
clrscr();
a = 10;
b = 20;
swap(a,b);
al
}
void swap(int x, int y)
{
itn
int t;
DSA 17 By Bhupendra Saud
cs
Source: www.csitnepal.com
t = x;
x = y;
y = t;
printf("x = %d\ty = %d\n",x,y);
}
The output of the above program would be
x = 20 y = 10
a = 10 b = 20
Note that values of a and b are unchanged even after exchanging the values of x and y.
Pass by reference: In this method, the addresses of actual arguments in the calling
function are copied into formal arguments of the called function. This means that using
these addresses we would have an access to the actual arguments and hence we would
be able to manipulate them. The following program illustrates this fact.
#include<stdio.h>
#include<conio.h>
void main()
{
int a,b;
void swap(int*, int*);
clrscr();
a = 10;
b = 20;
swap(&a,&b);
printf("a = %d\tb = %d",a,b);
getch();
}
void swap(int *x, int *y)
{
int t;
t = *x;
*x = *y;
*y = t;
printf("x = %d\ty = %d\n",*x,*y);
}
The output of the above program would be
x = 20 y = 10
a = 20 b = 10
Note: We can use call by reference to return multiple values from the function.
In case of one dimensional array, an array name is really a pointer to the first element in
ep
the array. Therefore, if x is a one-dimensional array, then the address of the first array
element can be expressed as either &x[0] or simply x. Moreover, the address of the
itn
/* Program to read n numbers in an array and display their sum and average */
#include<stdio.h>
#include<conio.h>
#define SIZE 100
void main()
{
float a[SIZE],sum=0,avg;
int n,i;
clrscr();
printf("How many numbers?");
scanf("%d",&n);
printf("Enter numbers:\n");
for(i=0;i<n;i++)
{
scanf("%f",(a+i)); // scanf("%f",&a[i]);
sum=sum+*(a+i); //sum=sum+a[i];
}
avg=sum/n;
printf("Sum=%f\n",sum);
printf("Average=%f",avg);
getch();
}
/* using pointer write a program to add two 3 2 matrices and print the result in
matrix form */
#include<stdio.h>
#include<conio.h>
#define ROW 3
#define COL 2
void main()
{
int a[ROW][COL],b[ROW][COL],i,j,sum;
clrscr();
printf("Enter elements of first matrix:\n");
al
for(i=0;i<ROW;i++)
{
ep
for(j=0;j<COL;j++)
scanf("%d", (*(a+i)+j));
printf("\n");
itn
}
DSA 19 By Bhupendra Saud
cs
Source: www.csitnepal.com
printf("Enter elements of second matrix:\n");
for(i=0;i<ROW;i++)
{
for(j=0;j<COL;j++)
scanf("%d", (*(b+i)+j));
printf("\n");
}
printf("Addition matrix is:\n");
for(i=0;i<ROW;i++)
{
for(j=0;j<COL;j++)
{
sum = *(*(a+i)+j)+*(*(b+i)+j);
printf("%d\t",sum);
}
printf("\n");
}
getch();
}
*(*(s+i)+j)=*(*(a+i)+j)+*(*(b+i)+j);
}
ep
}
printf("Matrix A is:\n\n");
write(a,r,c);
itn
printf("Matrix B is:\n\n");
DSA 20 By Bhupendra Saud
cs
Source: www.csitnepal.com
write(b,r,c);
printf("Sum ofmatrix A and B is:\n\n");
write(s,r,c);
getch();
}
void read(int **x,,int r,int c)
{
int i,j;
for(i=0;i<r;i++)
{
for(j=0;j<c;j++)
{
scanf("%d",*(x+i)+j);
}
}
}
void write(int**y,int r,int c)
{
int i,j;
for(i=0;i<r;i++)
{
for(j=0;j<c;j++)
{
printf("%d\t",*(*(y+i)+j));
}
printf("\n");
}
}
for(i=0;i<r;i++)
{
ep
for(j=0;j<c;j++)
{
s[i][j]=a[i][j]+b[i][j];
itn
c. Traversing
d. Searching a particular element in the array
itn
#include<stdio.h>
{
DSA 23 By Bhupendra Saud
cs
Source: www.csitnepal.com
a[i+1] = a[i];
}
a[pos]=nel;
*n=*n+1;
printf("New array is:\n");
for(i=0; i<*n; i++)
{
printf("%d\t", a[i]);
}
}
printf("*********unsuccessful search*********");
}
itn
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
void read(int**,int,int);
void write(int**,int,int);
void main()
{
int **a;
int **b;
int **m;
int r1,c1,r2,c2,i,j,k;
clrscr();
printf("Enter no of row and columns of first matrix\n");
scanf("%d%d",&r1,&c1);
printf("Enter no of row and columns of second matrix\n");
scanf("%d%d",&r2,&c2);
for(i=0;i<r1;i++)
{
*(a+i)=(int*)malloc(sizeof(int)*c1);
*(m+i)=(int*)malloc(sizeof(int)*c2);
}
for(i=0;i<r2;i++)
{
*(b+i)=(int*)malloc(sizeof(int)*c2);
}
printf("Enter elements of first matrix);
read(a,r1,c1);
printf("Enter elements of Second matrix\n);
read(b,r2,c2);
for(i=0;i<r1;i++)
{
for(j=0;j<c2;j++)
{
*(*(m+i)+j)=0;
for(k=0;k<c1;k++)
{
(*(*(m+i)+j))+=*(*(a+i)+k)*(*(*(b+k)+j));
}
}
}
printf("Matrix A is:\n\n");
write(a,r1,c1);
printf("Matrix B is:\n\n");
write(b,r2,c2);
al
getch();
}
void read(int **x,int r,int c)
itn
{
DSA 25 By Bhupendra Saud
cs
Source: www.csitnepal.com
int i,j;
for(i=0;i<r;i++)
{
for(j=0;j<c;j++)
{
scanf("%d",*(x+i)+j);
}
}
}
Unit 2
Algorithm
Concept and definition
Design of algorithm
Characteristic of algorithm
Big O notation
Algorithm:
An algorithm is a precise specification of a sequence of instructions to be carried out in
order to solve a given problem. Each instruction tells what task is to be done. There
should be a finite number of instructions in an algorithm and each instruction should be
executed in a finite amount of time.
Properties of Algorithms:
Input: A number of quantities are provided to an algorithm initially before the
algorithm begins. These quantities are inputs which are processed by the
algorithm.
Definiteness: Each step must be clear and unambiguous.
al
Example:
f(x)=5x3+3x2+4 find big oh(O) of f(x)
solution:f(x)= 5x3+3x2+4<= 5x3+3x3+4x3 if x>0
<=12x3
=>f(x)<=c.g(x)
where c=12 and g(x)=x3
Thus by definition of big oh O(f(x))=O(x3)
Example:
f(n) = 3n2 + 4n + 7
g(n) = n2 , then prove that f(n) = (g(n)).
Proof: let us choose c1, c2 and n0 values as 14, 1 and 1 respectively then we can have,
f(n) <= c1*g(n), n>=n0 as 3n2 + 4n + 7 <= 14*n2 , and
f(n) >= c2*g(n), n>=n0 as 3n2 + 4n + 7 >= 1*n2
for all n >= 1(in both cases).
So c2*g(n) <= f(n) <= c1*g(n) is trivial.
Hence f(n) = Q (g(n)).
Efficiency:
Time Complexity: The algorithm above iterates up to n-2 times, so time complexity is
O(n).
Space Complexity: The space complexity is constant i.e. O(1).
{
ep
{
DSA 28 By Bhupendra Saud
cs
Source: www.csitnepal.com
temp = A[j];
A[j] = A[j+1];
A[j+1] = temp;
}
}
}
}
Time Complexity:
Inner loop executes for (n-1) times when i=0, (n-2) times when i=1 and so on:
Time complexity = (n-1) + (n-2) + (n-3) + . +2 +1
= O(n2)
Unit:-3
The stack
a. concept and definition
primitive operations
Stack as an ADT
Implementing PUSH and POP operation
Testing for overflow and underflow conditions
b. The infix, postfix and prefix
Concept and definition
Evaluating the postfix operation
Converting from infix to postfix
c. Recursion
Concept and definition
Implementation of:
Multiplication of natural numbers
Factorial
Fibonacci sequences
The tower of Hanoi
Introduction to Stack
A stack is an ordered collection of items into which new items may be inserted and
from which items may be deleted at one end, called the top of the stack. The deletion
and insertion in a stack is done from top of the stack.
The following fig shows the stack containing items:
Top D
C
B
al
A
ep
Applications of Stack:
Stack is used directly and indirectly in the following fields:
To evaluate the expressions (postfix, prefix)
To keep the page-visited history in a Web browser
To perform the undo sequence in a text editor
Used in recursion
To pass the parameters between the functions in a C program
Can be used as an auxiliary data structure for implementing algorithms
Can be used as a component of other data structures
Stack Operations:
The following operations can be performed on a stack:
PUSH operation: The push operation is used to add (or push or insert) elements in a
stack
When we add an item to a stack, we say that we push it onto the stack
The last item put into the stack is at the top
al
ep
POP operation: The pop operation is used to remove or delete the top element from
the stack.
itn
The PUSH and the POP operations are the basic or primitive operations on a stack.
Some others operations are:
CreateEmptyStack operation: This operation is used to create an empty stack.
IsFull operation: The isfull operation is used to check whether the stack is full
or not ( i.e. stack overflow)
IsEmpty operation: The isempty operation is used to check whether the stack
is empty or not. (i. e. stack underflow)
Top operations: This operation returns the current item at the top of the stack,
it doesnt remove it
The Stack ADT:
A stack of elements of type T is a finite sequence of elements of T together with the
operations
CreateEmptyStack(S): Create or make stack S be an empty stack
Push(S, x): Insert x at one end of the stack, called its top
Top(S): If stack S is not empty; then retrieve the element at its top
Pop(S): If stack S is not empty; then delete the element at its top
IsFull(S): Determine if S is full or not. Return true if S is full stack; return false
otherwise
IsEmpty(S): Determine if S is empty or not. Return true if S is an empty stack;
return false otherwise.
Implementation of Stack:
Stack can be implemented in two ways:
1. Array Implementation of stack (or static implementation)
2. Linked list implementation of stack (or dynamic)
to -1(top=-1).
itn
#define MAX 10
DSA 31 By Bhupendra Saud
cs
Source: www.csitnepal.com
sruct stack
{
int items[MAX]; //Declaring an array to store items
int top; //Top of a stack
};
typedef struct stack st;
if top=MAXSIZE-1 then
print Stack Overflow and Exit
else
itn
ii) Algorithm for POP (removing an item from the stack) operation
This algorithm deletes the top element of the stack and assign it to a variable item
OR
Alternatively we can define the push function as give below:
void push()
{
int item;
if(top == MAXSIZE - 1) //Checking stack overflow
printf("\n The Stack Is Full");
else
{
printf("Enter the element to be inserted");
scanf("%d",&item); //reading an item
top= top+1; //increase top by 1
stack[top] = item; //storing the item at the top of
the stack
}
}
The C function for POP operation
void pop(stack *s)
{
if(isempty(s))
printf("\n\nstack Underflow: Empty Stack!!!");
else
al
printf("\nthe deleted item is %d:\t",s->items[s->top--]);/*deletes top element and
decrease top by 1 */
ep
OR
itn
push(s,element);
break;
case 2:
itn
display(s);
DSA 34 By Bhupendra Saud
cs
Source: www.csitnepal.com
break;
case 3: clrscr();
pop(s);
break;
case 4:
flag=0;
break;
default:
printf("\n Invalid Choice");
}
}while(flag);
getch();
}
/*Function to create an empty stack*/
void create_empty_stack(st *s)
{
s->top=-1;
}
/*Function to check whether the stack is empty or not */
int isempty(st *s)
{
if(s->top==-1)
return 1;
else
return 0;
}
/*function to check whether the stack is full or not*/
int isfull(st *s)
{
if(s->top==MAX-1)
return 1;
else
return 0;
}
/* push() function definition */
void push(st *s, int element)
{
if(isfull(s)) /* Checking Overflow condition */
printf("\n \nThe stack is overflow: Stack Full!!\n");
else
s->items[++(s->top)]=element;
}
/* Function for displaying elements of a stack*/
void display(st *s)
{
int i;
if(isempty(s))
printf("\nThe Stack does not contain any Elements");
else
{
al
printf("\nThe elements in the stack is/are:\n");
for(i=s->top;i>=0;i--)
ep
printf("%d\n",s->items[i]);
}
itn
}
DSA 35 By Bhupendra Saud
cs
Source: www.csitnepal.com
/* the POP function definition*/
void pop(st *s)
{
if(isempty(s))
printf("\n\nstack Underflow: Empty Stack!!!");
else
printf("\n\nthe deleted item is %d:\t",s->items[s->top--]);
}
exit(1);
}
ep
}while(ch<4);
getch();
}
itn
/*******push function**************/
DSA 36 By Bhupendra Saud
cs
Source: www.csitnepal.com
void push(st *s,int d)
{
if(s->tos==MAX-1)
{
printf("Stack is full\n");
}
else
{
++s->tos;
s->item[s->tos]=d;
}
}
/***********pop function**************/
int pop(st *s)
{
int itm;
if(s->tos==-1)
{
printf("Stack is empty\n");
return(0);
}
else
{
itm=s->item[s->tos];
s->tos--;
return(itm);
}
}
/*************display function********************/
void display(st *s)
{
int i;
if(s->tos==-1)
printf("There is no data item to display\n");
else
{
for(i=s->tos; i>=0; i--)
{
printf("%d\t", s->item[i]);
}
}
}
Prefix
ep
Postfix
itn
Precedence rule:
ep
While converting infix to postfix you have to consider the precedence rule, and the
precedence rules are as follows
itn
Illustration:
A + (B * C). Infix form
A + (B * C) Parenthesis for emphasis
A + (BC*) Convert the multiplication
A (BC*) + Convert the addition
ABC*+ Post-fix form
Consider an example:
(A + B) * ((C - D) + E) / F Infix form
(AB+) * ((C D) + E) / F
(AB+) * ((CD-) + E) / F
(AB+) * (CD-E+) / F
(AB+CD-E+*) / F
AB+CD-E+*F/ Postfix form
Examples al
ep
xercise: Convert the infix expression listed in the above table into postfix notation and
itn
verify yourself.
DSA 39 By Bhupendra Saud
cs
Source: www.csitnepal.com
Algorithm to convert infix to postfix notation
Let here two stacks opstack and poststack are used and otos & ptos represents the
opstack top and poststack top respectively.
ABC+-D*EF+$ (postfix) .
ep
itn
A+B-C (infix)
=(+AB)-C
=-+ABC (prefix)
Example Consider an example:
A $ B * C D + E / F / (G + H) infix form
= A $ B * C D + E / F /(+GH)
=$AB* C D + E / F /(+GH)
=*$ABC-D+E/F/(+GH)
=*$ABC-D+(/EF)/(+GH)
=*$ABC-D+//EF+GH
= (-*$ABCD) + (//EF+GH)
=+-*$ABCD//EF+GH which is in prefix form.
Consider an example
345*+
=3 20 +
=23 (answer)
=1 3 4 + * 2 $ 3 +
=1 7 * 2 $ 3 +
ep
=7 2 $ 3 +
=49 3 +
= 52
itn
1. Scan one character at a time from left to right of given postfix expression
1.1 if scanned symbol is operand then
read its corresponding value and push it into vstack
1.2 if scanned symbol is operator then
pop and place into op2
op and place into op1
compute result according to given operator and push result into vstack
2. pop and display which is required value of the given postfix expression
3. return
Trace of Evaluation:
Consider an example to evaluate the postfix expression tracing the algorithm
ABC+*CBA-+*
123+*321-+*
Scanned value Op2 Op1 Result vstack
character
A 1 . . 1
B 2 .. 12
C 3 .. 123
+ . 3 2 5 15
* 5 1 5 5
C 3 . 53
B 2 . 532
A 1 . . 5321
- . 1 2 1 531
+ . 1 3 4 54
* . 4 5 20 20
=/82
=4
ep
itn
}
}
ep
}
printf("The reault is:");
res=pop();
itn
printf("%d", res);
DSA 43 By Bhupendra Saud
cs
Source: www.csitnepal.com
getch();
}
/***********insertion function*************/
void push(int val)
{
vstack[++tos]=val;
}
/***********deletion function***************/
int pop()
{
int n;
n=vstack[tos--];
return(n);
}
}
else //operators
ep
{
if(precedency(opstack[otos])>precedency(infix[i]))
{
itn
poststack[++ptos]=opstack[otos--];
DSA 44 By Bhupendra Saud
cs
Source: www.csitnepal.com
opstack[++otos]=infix[i];
}
opstack[++otos]=infix[i];
}
}
while(otos!=-1)
{
poststack[++ptos]=opstack[otos];
otos--;
}
/********for displaying***************/
for(i=0;i<l1;i++)
{
printf("%c",poststack[i]);
}
getch();
}
/****************precedency function*********************/
int precedency(char ch)
{
switch(ch)
{
case '$':
return(4);
// break;
case'*':
case'/':
return(3);
// break;
case'+':
case'-':
return(2);
// break;
default:
return(1);
}
}
Recursion:
Recursion is a process by which a function calls itself repeatedly, until some
specified condition has been satisfied. The process is used for repetitive computations in
which each action is stated in terms of a previous result.
In order to solve a problem recursively, two conditions must be satisfied. First, the
problem must be written in a recursive form, and second, the problem statement must
al
Example:
/*calculation of the factorial of an integer number without using recursive function*/
#include<stdio.h>
#include<conio.h>
void main()
{
int n;
long int facto;
long int factorial(int n);
al
printf("Enter value of n:");
scanf("%d",&n);
ep
facto=factorial(n);
printf("%d! = %ld",n,facto);
getch();
itn
}
DSA 46 By Bhupendra Saud
cs
Source: www.csitnepal.com
long int factorial(int n)
{
long int facto=1;
int i;
if(n==0)
return 1;
else {
for(i=1;i<=n;i++)
facto=facto*i;
return facto;
}
}
int fibo(int k)
{
if(k == 1 || k == 2)
return 1;
else
return fibo(k-1)+fibo(k-2);
}
if(n == 1)
return 1;
ep
else
return n + sum_natural(n-1);
itn
Objective:
Transfer all disks from origin pole to destination pole using intermediate pole for
temporary storage.
Conditions:
Move only one disk at a time.
Each disk must always be placed around one of the pole.
Never place larger disk on top of smaller disk.
Algorithm: - To move a tower of n disks from source to dest (where n is positive integer):
1. If n ===1:
1.1. Move a single disk from source to dest.
2. If n > 1:
2.1. Let temp be the remaining pole other than source and dest.
2.2. Move a tower of (n 1) disks form source to temp.
2.3. Move a single disk from source to dest.
2.4. Move a tower of (n 1) disks form temp to dest.
3. Terminate.
}
}
ep
itn
Advantages of Recursion:
The code may be much easier to write.
To solve some problems which are naturally recursive such as tower of Hanoi.
Disadvantages of Recursion:
Recursive functions are generally slower than non-recursive functions.
May require a lot of memory to hold intermediate results on the system stack.
It is difficult to think recursively so one must be very careful when writing
recursive functions.
Unit 4
Queues
a) Concept and definition
b) Queue as ADT
c) Implementation of insert and delete operation of
Linear queue
Circular queue
d) Concept of priority queue
What is a queue?
> A Queue is an ordered collection of items from which items may be deleted at
one end (called the front of the queue) and into which items may be inserted at the other
al
Operations on queue:
MakeEmpty(q): To make q as an empty queue
Enqueue(q, x): To insert an item x at the rear of the queue, this is also called by
names add, insert.
Dequeue(q): To delete an item from the front of the queue q. this is also known as
Delete, Remove.
IsFull(q): To check whether the queue q is full.
IsEmpty(q): To check whether the queue q is empty
Traverse (q): To read entire queue that is display the content of the queue.
Enqueue(A): Enqueue(B,C,D):
Dequeue(A): Dequeue(B):
al
ep
itn
Applications of queue:
Task waiting for the printing
Time sharing system for use of CPU
For access to disk storage
Task scheduling in operating system
Implementation of queue:
There are two techniques for implementing the queue:
Array implementation of queue(static memory allocation)
Linked list implementation of queue(dynamic memory allocation)
In array implementation of queue, an array is used to store the data elements. Array
implementation is also further classified into two types
ep
Linear queue:
Algorithm for insertion (or Enqueue ) and deletion (Dequeue) in queue:
Declaration of a Queue:
# define MAXQUEUE 50 /* size of the queue items*/
struct queue
{
int front;
int rear;
int items[MAXQUEUE];
};
typedef struct queue qt;
return 0;
}
ep
11 22 33 44 55
al
0 1 2 3 4 5 6 front=2, rear=6
ep
f r
This queue is considered full, even though the space at beginning is vacant.
itn
/**********insert function*************/
void insert(qu *q)
ep
{ int d;
printf("Enter data to be inserted\n");
scanf("%d",&d);
itn
Circular queue:
A circular queue is one in which the insertion of a new element is done at very
first location of the queue if the last location of the queue is full.
al
ep
itn
int front;
int rear;
ep
int items[MAXSIZE];
};
typedef struct cqueue cq;
itn
}
else
ep
{
q->front=(q->front+1)%MAXSIZE;
itn
return(q->items[q->front]);
DSA 57 By Bhupendra Saud
cs
Source: www.csitnepal.com
}
}
/*implementation of circular queue with secrifying one cell */
#include<stdio.h>
#include<conio.h>
#define SIZE 20
struct cqueue
{
int item[SIZE];
int rear;
int front;
};
typedef struct cqueue qu;
void insert(qu*);
void delet(qu*);
void display(qu*);
void main()
{
int ch;
qu *q;
q->rear=SIZE-1;
q->front=SIZE-1;
clrscr();
printf("Menu for program:\n");
printf("1:insert\n2:delete\n3:display\n4:exit\n");
do
{
printf("Enter youer choice\n");
scanf("%d",&ch);
switch(ch)
{
case 1:
insert(q);
break;
case 2:
delet(q);
break;
case 3:
display(q);
break;
case 4:
exit(1);
break;
default:
printf("Your choice is wrong\n");
break;
}
}while(ch<5);
getch();
}
al
/**********insert function*************/
void insert(qu *q)
ep
{
int d;
if((q->rear+1)%SIZE==q->front)
itn
printf("Queue is full\n");
DSA 58 By Bhupendra Saud
cs
Source: www.csitnepal.com
else
{
q->rear=(q->rear+1)%SIZE;
printf ("Enter data to be inserted\n");
scanf("%d",&d);
q->item[q->rear]=d;
}
}
/**********delete function*****************/
void delet(qu *q)
{
if(q->rear==q->front)
printf("Queue is empty\n");
else
{
q->front=(q->front+1)%SIZE;
printf("Deleted item is:");
printf("%d\n",q->item[q->front]);
}
}
/**************display function***********/
void display(qu *q)
{
int i;
if(q->rear==q->front)
printf("Queue is empty\n");
else
{
printf("Items of queue are:\n");
for(i=(q->front+1)%SIZE;i!=q->rear;i=(i+1)%SIZE)
{
printf("%d\t",q->item[i]);
}
printf("%d\t",q->item[q->rear]);
}
}
void delet(qu*);
void display(qu*);
void main()
itn
{
DSA 59 By Bhupendra Saud
cs
Source: www.csitnepal.com
int ch;
qu *q;
q->rear=SIZE-1;
q->front=SIZE-1;
clrscr();
printf("Menu for program:\n");
printf("1:insert\n2:delete\n3:display\n4:exit\n");
do
{
printf("Enter youer choice\n");
scanf("%d",&ch);
switch(ch)
{
case 1:
insert(q);
break;
case 2:
delet(q);
break;
case 3:
display(q);
break;
case 4:
exit(1);
break;
default:
printf("Your choice is wrong\n");
break;
}
}while(ch<5);
getch();
}
/**********insert function*************/
void insert(qu *q)
{
int d;
if(count==SIZE)
printf("Queue is full\n");
else
{
q->rear=(q->rear+1)%SIZE;
printf ("Enter data to be inserted\n");
scanf("%d",&d);
q->item[q->rear]=d;
count++;
}
}
/**********delete function*****************/
al
void delet(qu *q)
{
ep
if(count==0)
printf("Queue is empty\n");
else
itn
{
DSA 60 By Bhupendra Saud
cs
Source: www.csitnepal.com
q->front=(q->front+1)%SIZE;
printf("Deleted item is:");
printf("%d\n",q->item[q->front]);
count--;
}
}
/**************display function***********/
void display(qu *q)
{
int i;
if(q->rear==q->front)
printf("Queue is empty\n");
else
{
printf("Items of queue are:\n");
for(i=(q->front+1)%SIZE; i!=q->rear; i=(i +1)%SIZE)
{
printf("%d\t",q->item[i]);
}
printf("%d\t",q->item[q->rear]);
}
}
Priority queue:
A priority queue is a collection of elements such that each element has been
assigned a priority and the order in which elements are deleted and processed comes
from the following rules:.
An element of higher priority is processed before any element of lower priority.
If two elements has same priority then they are processed according to the order in
which they were added to the queue.
The best application of priority queue is observed in CPU scheduling.
The jobs which have higher priority are processed first.
If the priority of two jobs is same this jobs are processed according to their
position in queue.
A short job is given higher priority over the longer one.
arbitrarily but from which only the smallest item can be removed.
ep
al
ep
break;
}
ep
}while(ch<5);
getch();
}
itn
/**********insert function*************/
DSA 64 By Bhupendra Saud
cs
Source: www.csitnepal.com
void insert(pq *q)
{
int d;
if(q->rear==SIZE-1)
printf("Queue is full\n");
else
{
printf ("Enter data to be inserted\n");
scanf("%d",&d);
q->rear++;
q->item[q->rear]=d;
}
}
/**********delete function*****************/
void delet(pq *q)
{
int i, temp=0, x;
x=q->item[q->front];
if(q->rear<q->front)
{
printf("Queue is empty\n");
return 0;
}
else
{
for(i=q->front+1; i<q->rear; i++)
{
if(x>q->item[i])
{
temp=i;
x=q->item[i];
}
}
for(i=temp;i< q->rear-1;i++)
{
q->item[i]=q->item[i+1];
}
q->rear--;
return x;
}
}
/************display function***********/
void display(pq *q)
{
int i;
if(q->rear < q->front)
printf("Queue is empty\n");
else
al
{
printf("Items of queue are:\n");
ep
for(i=(q->front i<=q->rear;i++)
{
printf("%d\t",q->item[i]);
itn
}
DSA 65 By Bhupendra Saud
cs
Source: www.csitnepal.com
}
}
Unit 4
Linked List:
a) Concept and definition
b) Inserting and deleting nodes
c) Linked implementation of a stack (PUSH / POP)
d) Linked implementation of a queue (insert / delete)
e) Circular linked list
Stack as a circular list (PUSH / POP)
Queue as a circular list (Insert / delete)
f) Doubly linked list (insert / delete)
Linked List:
A linked list is a collection of nodes, where each node consists of two parts:
info: the actual element to be stored in the list. It is also called data field.
al
link: one or two links that points to next and previous node in the list. It is also
called next or pointer field.
ep
Illustration:
itn
The NULL value of the next field of the linked list indicates the last node and we define
macro for NULL and set it to 0 as below:
#define NULL 0
Creating a Node:
To create a new node, we use the malloc function to dynamically allocate memory
for the new node.
After creating the node, we can store the new item in the node using a pointer to that
nose.
The following steps clearly shows the steps required to create a node and storing an
item.
return(p);
}
ep
Inserting Nodes:
To insert an element or a node in a linked list, the following three things to be done:
Allocating a node
Assigning a data to info field of the node
Adjusting a pointer and a new node may be inserted
At the beginning of the linked list
At the end of the linked list
At the specified position in a linked list
Insertion requires obtaining a new node ans changing two links
The C function to insert a node at the beginning of the singly linked list:
void InsertAtBeg(int newItem)
{
NodeType *NewNode;
NewNode=getNode();
NewNode->info=newItem;
NewNode->next=head;
head=NewNode;
}
al
ep
itn
NewNode=(NodeType*)malloc(sizeof(NodeType));
2. Assign data to the info field of new node
NewNode->info=newItem;
itn
The C function to insert a node after the given node in singly linked list:
void InsertAfterNode(NodeType *p int newItem)
{
NodeType *NewNode;
NewNode=getNode();
NewNode->info=newItem;
if(p==NULL)
{
printf(Void insertion);
exit(1);
}
else
{
NewNode->next=p->next;
p->next =NewNode..
}
}
The C function to insert a node at the specified position in a singly linked list:
void InsertAtPos(int newItem)
{
NodeType *NewNode;
int pos , i ;
printf( Enter position of a node at which you want to insert a new node);
scanf(%d,&pos);
if(head==NULL)
{
al
printf(void insertion);
exit(1).
ep
}
else
{
itn
temp=head;
DSA 71 By Bhupendra Saud
cs
Source: www.csitnepal.com
for(i=1; i<pos-1; i++)
{
temp=temp->next;
}
NewNode=getNode();
NewNode->info=newItem;
NewNode->next=temp->next;
temp->next =NewNode;
}
}
Deleting Nodes:
A node may be deleted:
From the beginning of the linked list
from the end of the linked list
from the specified position in a linked list
The C function to deleting the first node of the singly linked list:
void deleteBeg()
{
NodeType *temp;
if(head==NULL)
{
printf(Empty list);
exit(1).
}
else
{
temp=head;
printf(Deleted item is %d , head->info);
head=head->next;
free(temp);
}
al
}
ep
The C function to deleting the last node of the singly linked list:
let *head be the pointer to first node in the current list
void deleteEnd()
{
NodeType *temp;
if(head==NULL)
{
printf(Empty list);
return;
}
else if(head->next==NULL)
{
temp=head;
head=NULL;
printf(Deleted item is %d, temp->info);
free(temp);
}
else
{
temp=head;
while(temp->next->next!=NULL)
{
temp=temp->next;
}
printf(deleted item is %d' , temp->next->info):
free(temp->next);
temp->next=NULL;
}
}
An algorithm to delete a node after the given node in singly linked list:
let *head be the pointer to first node in the current list and *p be the pointer to the node
after which we want to delete a new node.
al
4. free(q)
DSA 73 By Bhupendra Saud
cs
Source: www.csitnepal.com
5. End
The C function to delete a node after the given node in singly linked list:
let *p be the pointer to the node after which we want to delete a new node.
void deleteAfterNode(NodeType *p)
{
NodeType *q;
if(p==NULL || p->next==NULL )
{
printf(Void insertion);
exit(1);
}
else
{
q=p->next;
p->next=q->next;
free(q);
}
}
The C function to delete a node at the specified position in a singly linked list
void deleteAtSpecificPos()
{
NodeType *temp *p;
int pos, i;
if(head==NULL)
{
printf(Empty list);
al
return;
}
ep
else
{
printf(Enter position of a node which you wand to delete);
itn
scanf(%d , &pos);
DSA 74 By Bhupendra Saud
cs
Source: www.csitnepal.com
temp=head;
for(i=1; i<pos-1; i++)
{
temp=temp->next;
}
p=temp->next;
` printf(Deleted item is %d, p->info);
temp->next =p->next;
free(p);
}
}
Complete program:
/******Various operations on singly linked list**************/
#include<stdio.h>
al
#include<conio.h>
#include<malloc.h> //for malloc function
ep
case 7:
info_sum();
break;
itn
case 8:
DSA 76 By Bhupendra Saud
cs
Source: www.csitnepal.com
count_nodes();
break;
case 9:
exit(1);
break;
default:
printf("invalid choice\n");
break;
}
}while(choice<10);
getch();
}
/************function definitions**************/
void insert_atfirst(int item)
{
NodeType *nnode;
nnode=(NodeType*)malloc(sizeof(NodeType));
nnode->info=item;
nnode->next=head;
head=nnode;
}
NodeType *temp;
temp=head;
nnode=( NodeType *)malloc(sizeof(NodeType));
itn
nnode->info=item;
DSA 77 By Bhupendra Saud
cs
Source: www.csitnepal.com
if(head==NULL)
{
nnode->next=NULL;
head=nnode;
}
else
{
while(temp->next!=NULL)
{
temp=temp->next;
}
nnode->next=NULL;
temp->next=nnode;
}
}
void delet_first()
{
NodeType *temp;
if(head==NULL)
{
printf("Void deletion|n");
return;
}
else
{
temp=head;
head=head->next;
free(temp);
}
}
void delet_last()
{
NodeType *hold,*temp;
if(head==NULL)
{
printf("Void deletion|n");
return;
}
else if(head->next==NULL)
{
hold=head;
head=NULL;
free(hold);
}
else
{
temp=head;
while(temp->next->next!=NULL)
{
al
temp=temp->next;
}
ep
hold=temp->next;
temp->next=NULL;
free(hold);
itn
}
DSA 78 By Bhupendra Saud
cs
Source: www.csitnepal.com
}
void delet_nthnode()
{
NodeType *hold,*temp;
int pos, i;
if(head==NULL)
{
printf("Void deletion|n");
return;
}
else
{
temp=head;
printf("Enter position of node which node is to be deleted\n");
scanf("%d",&pos);
for(i=1;i<pos-1;i++)
{
temp=temp->next;
}
hold=temp->next;
temp->next=hold->next;
free(hold);
}
}
void info_sum()
{
NodeType *temp;
temp=head;
while(temp!=NULL)
{
printf("%d\t",temp->info);
temp=temp->next;
}
}
void count_nodes()
{
int cnt=0;
NodeType *temp;
temp=head;
while(temp!=NULL)
{
cnt++;
temp=temp->next;
}
printf("total nodes=%d",cnt);
}
}
Linked list implementation of Stack:
Push function:
let *top be the top of the stack or pointer to the first node of the list.
al
void push(item)
ep
{
NodeType *nnode;
int data;
itn
void pop()
{
NodeType *temp;
if(top==0)
{
printf("Stack contain no elements:\n");
return;
}
else
{
temp=top;
top=top->next;
printf("\ndeleted item is %d\t",temp->info);
free(temp);
}
}
void main()
{
int choice, item;
itn
clrscr();
DSA 80 By Bhupendra Saud
cs
Source: www.csitnepal.com
do
{
printf("\n1.Push \n2.Pop \n3.Display\n4:Exit\n");
printf("enter ur choice\n");
scanf("%d",&choice);
switch(choice)
{
case 1:
printf("\nEnter the data:\n");
scanf("%d",&item);
push(item);
break;
case 2:
pop();
break;
case 3:
display();
break;
case 4:
exit(1);
break;
default:
printf("invalid choice\n");
break;
}
}while(choice<5);
getch();
}
/**************push function*******************/
void push(int item)
{
NodeType *nnode;
int data;
nnode=( NodeType *)malloc(sizeof(NodeType));
if(top==0)
{
nnode->info=item;
nnode->next=NULL;
top=nnode;
}
else
{
nnode->info=item;
nnode->next=top;
top=nnode;
}
}
/******************pop function********************/
void pop()
al
{
NodeType *temp;
ep
if(top==0)
{
printf("Stack contain no elements:\n");
itn
return;
DSA 81 By Bhupendra Saud
cs
Source: www.csitnepal.com
}
else
{
temp=top;
top=top->next;
printf("\ndeleted item is %d\t",temp->info);
free(temp);
}
}
/**************display function***********************/
void display()
{
NodeType *temp;
if(top==0)
{
printf("Stack is empty\n");
return;
}
else
{
temp=top;
printf("Stack items are:\n");
while(temp!=0)
{
printf("%d\t",temp->info);
temp=temp->next;
}
}
}
rear
void insert(int item)
{
NodeType *nnode;
nnode=( NodeType *)malloc(sizeof(NodeType));
al
ep
if(rear==0)
{
nnode->info=item;
itn
nnode->next=NULL;
DSA 82 By Bhupendra Saud
cs
Source: www.csitnepal.com
rear=front=nnode;
}
else
{
nnode->info=item;
nnode->next=NULL;
rear->next=nnode;
rear=nnode;
}
}
Delete function:
let *rear and *front are pointers to the first node of the list initially and insertion of
node in linked list done at the rear part and deletion of node from the linked list done
from front part.
void delet()
{
NodeType *temp;
if(front==0)
{
printf("Queue contain no elements:\n");
return;
}
else if(front->next==NULL)
{
temp=front;
rear=front=NULL;
printf("\nDeleted item is %d\n",temp->info);
free(temp);
}
else
{
temp=front;
front=front->next;
printf("\nDeleted item is %d\n",temp->info);
free(temp);
}
}
void insert(int);
DSA 83 By Bhupendra Saud
cs
Source: www.csitnepal.com
void delet();
void display();
void main()
{
int choice, item;
clrscr();
do
{
printf("\n1.Insert \n2.Delet \n3.Display\n4:Exit\n");
printf("enter ur choice\n");
scanf("%d",&choice);
switch(choice)
{
case 1:
printf("\nEnter the data:\n");
scanf("%d",&item);
insert(item);
break;
case 2:
delet();
break;
case 3:
display();
break;
case 4:
exit(1);
break;
default:
printf("invalid choice\n");
break;
}
}while(choice<5);
getch();
}
/**************insert function*******************/
void insert(int item)
{
NodeType *nnode;
nnode=( NodeType *)malloc(sizeof(NodeType));
if(rear==0)
{
nnode->info=item;
nnode->next=NULL;
rear=front=nnode;
}
else
{
nnode->info=item;
al
nnode->next=NULL;
rear->next=nnode;
ep
rear=nnode;
}
}
itn
/******************delet function********************/
DSA 84 By Bhupendra Saud
cs
Source: www.csitnepal.com
void delet()
{
NodeType *temp;
if(front==0)
{
printf("Queue contain no elements:\n");
return;
}
else if(front->next==NULL)
{
temp=front;
rear=front=NULL;
printf("\nDeleted item is %d\n",temp->info);
free(temp);
}
else
{
temp=front;
front=front->next;
printf("\nDeleted item is %d\n",temp->info);
free(temp);
}
}
/**************display function***********************/
void display()
{
NodeType *temp;
temp=front;
printf("\nqueue items are:\t");
while(temp!=NULL)
{
printf("%d\t",temp->info);
temp=temp->next;
}
}
In a circular linked list there are two methods to know if a node is the first node or not.
itn
set newnode->info=item
set newnode->next=start
set start=newnode
itn
set last->next=newnode
DSA 86 By Bhupendra Saud
cs
Source: www.csitnepal.com
end else
4. End
}
}
C function to insert a node at the end of a circular linked list:
void InsertAtEnd(int Item)
{
NodeType *newnode;
newnode=(NodeType*)malloc(sizeof(NodeType));
if(start==NULL)
{
newnode->info=item;
newnode->next=newnode;
al
start=newnode;
last newnode;
ep
}
else
{
itn
}
}
{
temp=start;
ep
start=start->next;
printf( the deleted element=%d, temp->info);
last->next=start;
itn
free(temp)
DSA 88 By Bhupendra Saud
cs
Source: www.csitnepal.com
}
}
C function to delete a node from the end of a circular linked list:
void DeleteLast()
{
if(start==NULL)
{
printf(Empty list);
exit(1);
}
else if(start==last) //for only one node
{
temp=start;
printf(deleted element=%d, temp->info);
free(temp);
start=last=NULL;
}
else
{
temp=start;
while( temp->next!=last)
temp=temp->next;
hold=temp->next;
last=temp;
last->next=start;
printf(the deleted element=%d, hold->info);
free(hold);
}
}
return(0);
ep
}
itn
POP function:
void POP()
{
NodeType *temp;
if(pstack==NULL)
{
printf(Stack underflow\n');
exit(1);
}
else if(pstack->next==pstack) //for only one node
{
printf(poped item=%d, pstack->info);
pstack=NULL;
}
else
{
temp=pstack->next;
al
pstack->next=temp->next;
printf(poped item=%d, temp->info);
ep
free(temp);
}
itn
Insertion function:
void insert(int item)
{
NodeType *nnode;
nnode=( NodeType *)malloc(sizeof(NodeType));
nnode->info=item;
if(pq==NULL)
pq=nnode;
else
{
nnode->next=pq->next;
pq->next=nnode;
pq=nnode;
}
}
Deletion function:
}
else if(pq->next==pq) //for only one node
ep
{
printf(poped item=%d, pq->info);
pq=NULL;
itn
}
DSA 91 By Bhupendra Saud
cs
Source: www.csitnepal.com
else
{
temp=pq->next;
pq->next=temp->next;
printf(poped item=%d, temp->info);
free(temp);
}
}
NodeType *newnode;
newnode=(NodeType*)malloc(sizeof(NodeType));
newnode->info=item;
itn
newnode->prev=newnode->next=NULL;
DSA 92 By Bhupendra Saud
cs
Source: www.csitnepal.com
newnode->next=head;
head->prev=newnode;
head=newnode;
}
3. set temp=head->prev
4. set temp->next=newnode
5. set newnode->prev=temp
itn
6. set newnode->next=head
DSA 94 By Bhupendra Saud
cs
Source: www.csitnepal.com
7. set head->prev=newnode
8. End
Algorithm to delete a node from the beginning of a circular doubly linked list:
1. if head->next==NULL then
print empty list and exit
2. else
set temp=head->next;
set head->next=temp->next
set temp->next=head
free(temp)
3. End
Algorithm to delete a node from the end of a circular doubly linked list:
1. if head->next==NULL then
print empty list and exit
2. else
set temp=head->prev;
set head->left=temp->left
free(temp)
3. End
Unit 6
Tree data structure:
a) Concept and definition
b) Binary tree
c) Introduction and application
d) operations
e) Types of binary tree
Complete binary tree
Strictly binary tree
Almost complete binary tree
f) Huffman algorithm
g) Binary search tree
insertion
deletion
searching
h) Tree traversal
al
Pre-order traversal
In-order traversal
ep
post-order traversal
itn
A has 3 children, B, C, D
A is parent of B
Characteristics of trees:
Non-linear data structure
combines advantages of an ordered array
searching as fast as in ordered array
insertion and deletion as fast as in linked list
Application:
Directory structure of a file store
Structure of arithmetic expressions
Hierarchy of an organization
Degree of a node:
The degree of a node is the number of children of that node.
In above tree the degree of node A is 3.
al
Degree of a Tree:
ep
Height of a node:
The height of a node is the maximum path length from that node to a leaf node. A leaf
node has a height of 0.
Height of a tree:
The height of a tree is the height of the root.
Depth of a node:
Depth of a node is the path length from the root to that node. The root node has a depth of 0.
Depth of a tree:
Depth of a tree is the maximum level of any leaf in the tree.
This is equal to the longest path from the root to any leaf.
Level of a node:
the level of a node is 0, if it is root; otherwise it is one more then its parent.
Illustration:
Binary Trees:
ep
A binary tree is a finite set of elements that are either empty or is partitioned into three
itn
disjoint subsets. The first subset contains a single element called the root of the tree. The other
DSA 97 By Bhupendra Saud
cs
Source: www.csitnepal.com
two subsets are themselves binary trees called the left and right sub-trees of the original tree. A
left or right sub tree can be empty.
Each element of a binary tree is called a node of the tree. The following figure shows a
binary tree with 9 nodes where A is the root.
at level d. A complete binary tree with depth d has 2d leaves and 2d -1 non-leaf nodes(internal)
Fig Almost complete binary tree but not strictly binary tree.
Since node E has a left son but not a right son.
Tree traversal:
The tree traversal is a way in which each node in the tree is visited exactly once in a
symmetric manner.
There are three popular methods of traversal
Pre-order traversal
In-order traversal
Post-order traversal
Pre-order traversal:
The preorder traversal of a nonempty binary tree is defined as follows:
Visit the root node
Traverse the left sub-tree in preorder
Traverse the right sub-tree in preorder
printf(%c, root->info);
preorder(root->left);
ep
preorder(root->right);
}
}
itn
Post-order traversal:
The post-order traversal of a nonempty binary tree is defined as follows:
Traverse the left sub-tree in post-order
Traverse the right sub-tree in post-order
Visit the root node
The post-order traversal output of the given tree is: H I D E B F G C A
C function for post-order traversing:
void post-order(struct bnode *root)
{
if(root!=NULL)
{
post-order(root->left);
post-order(root->right);
printf(%c, root->info);
}
}
2. end
itn
insert(18)
BST insertion algorithm:
To insert the element elem into a BST:
1. Set parent to null, and set curr to the BSTs root.
2. Repeat:
2.1. If curr is null:
2.1.1. Replace the null link from which curr was taken
(either the BSTs root or parents left child or parents right child) by a
link to a newly-created leaf node with element elem.
2.1.2. Terminate.
2.2. Otherwise, if elem is equal to currs element:
2.2.1. Terminate.
al
al
ep
itn
temp=find_min(root->right);
root->info=temp->info;
itn
root->right=delete(root->right, root->info);
DSA 106 By Bhupendra Saud
cs
Source: www.csitnepal.com
}
else
{
temp=root;
if(root->left==NULL)
root=root->right;
else if(root->right==NULL)
root=root->left;
free(temp);
}
return(temp);
}
/**********find minimum element function**********/
struct bnode *find_min(struct bnode *root)
{
if(root==NULL)
return0;
else if(root->left==NULL)
return root;
else
return(find_min(root->left));
}
Huffman algorithm:
In Huffman Algorithm, a set of nodes assigned with values if fed to the algorithm.
Initially 2 nodes are considered and their sum forms their parent node. When a new
element is considered, it can be added to the tree. Its value and the previously calculated
sum of the tree are used to form the new node which in turn becomes their parent.
al
Let us take any four characters and their frequencies, and sort this list by increasing
ep
frequency.
Since to represent 4 characters the 2 bit is sufficient thus take initially two bits for each
itn
al
ep
itn
Left branch is 0
Right branch is 1
nb=3*3+5*3+7*2+10*1=09+15+14+10=48bits
(50-48)/50*100%=4%
ep
Since in this small example we save about 4% space by using Huffman algorithm. If we
take large example with a lot of characters and their frequencies we can save a lot of space.
itn
Unit 7
Sorting:
a) Introduction
b) Bubble sort
c) Insertion sort
d) Selection sort
e) Quick sort
f) Merge sort
g) Comparison and efficiency of sorting
Introduction:
Sorting
Sorting is among the most basic problems in algorithm design. We are given a sequence
of items, each associated with a given key value. The problem is to permute the items so that
they are in increasing (or decreasing) order by key. Sorting is important because it is often the
first step in more complex algorithms. Sorting algorithms are usually divided into two classes,
internal sorting algorithms, which assume that data is stored in an array in main memory, and
external sorting algorithm, which assume that data is stored on disk or some other device that
is best accessed sequentially. We will only consider internal sorting. Sorting algorithms often
have additional properties that are of interest, depending on the application. Here are two
important properties.
In brief the sorting is a process of arranging the items in a list in some order that is either
ascending or descending order.
Let a[n] be an array of n elements a0,a1,a2,a3........,an-1 in memory. The sorting of the array
a[n] means arranging the content of a[n] in either increasing or decreasing order.
i.e. a0<=a1<=a2<=a3<.=.......<=an-1
consider a list of values: 2 ,4 ,6 ,8 ,9 ,1 ,22 ,4 ,77 ,8 ,9
After sorting the values: 1, 2, 4, 4, 6, 8, 8,9 , 9 , 22, 77
In-place: The algorithm uses no additional array storage, and hence (other than perhaps the
systems recursion stack) it is possible to sort very large lists without the need to allocate
additional working storage.
Stable: A sorting algorithm is stable if two elements that are equal remain in the same relative
al
position after sorting is completed. This is of interest, since in some sorting applications you
ep
sort first on one key and then on another. It is nice to know that two items that are equal on the
itn
Algorithm
BubbleSort(A, n)
{
for(i = 0; i <n-1; i++)
{
for(j = 0; j < n-i-1; j++)
{
if(A[j] > A[j+1])
al
{
ep
temp = A[j];
A[j] = A[j+1];
A[j+1] = temp;
itn
}
DSA 111 By Bhupendra Saud
cs
Source: www.csitnepal.com
}
}
}
Time Complexity:
Inner loop executes for (n-1) times when i=0, (n-2) times when i=1 and so on:
Time complexity = (n-1) + (n-2) + (n-3) + . +2 +1
= O(n2)
There is no best-case linear time complexity for this algorithm.
Space Complexity:
Since no extra space besides 3 variables is needed for sorting
Space complexity = O(n)
Selection Sort:
Idea: Find the least (or greatest) value in the array, swap it into the leftmost(or rightmost)
component (where it belongs), and then forget the leftmost component. Do this repeatedly.
Let a[n] be a linear array of n elements. The selection sort works as follows:
pass 1: Find the location loc of the smallest element int the list of n elements a[0], a[1], a[2],
a[3], ......,a[n-1] and then interchange a[loc] and a[0].
Pass 2: Find the location loc of the smallest element int the sub-list of n-1 elements a[1], a[2],
a[3], ......,a[n-1] and then interchange a[loc] and a[1] such that a[0], a[1] are sorted.
..................... and so on.
Then we will get the sorted list a[0]<=a[1]<= a[2]<=a[3]<= ......<=a[n-1].
Algorithm:
SelectionSort(A)
{
for( i = 0;i < n ;i++)
{
least=A[i];
p=i;
for ( j = i + 1;j < n ;j++)
{
if (A[j] < A[i])
least= A[j]; p=j;
}
}
swap(A[i],A[p]);
}
Time Complexity:
Inner loop executes for (n-1) times when i=0, (n-2) times when i=1 and so on:
Time complexity = (n-1) + (n-2) + (n-3) + . +2 +1
= O(n2)
al
There is no best-case linear time complexity for this algorithm, but number of swap
operations is reduced greatly.
ep
Space Complexity:
Since no extra space besides 5 variables is needed for sorting
itn
Suppose an array a[n] with n elements. The insertion sort works as follows:
pass 1: a[0] by itself is trivially sorted.
Pass 2: a[1] is inserted either before or after a[0] so that a[0], a[1] is sorted.
Pass 3: a[2] is inserted into its proper place in a[0],a[1] that is before a[0], between a[0] and
a[1], or after a[1] so that a[0],a[1],a[2] is sorted.
.....................................................
pass N: a[n-1] is inserted into its proper place in a[0],a[1],a[2],........,a[n-2] so that
a[0],a[1],a[2],............,a[n-1] is sorted with n elements.
Example:
al
ep
itn
Quick Sort:
Quick sort developed by C.A.R Hoare is an unstable sorting. In practice this is the
fastest sorting method. It possesses very good average case complexity among all the sorting
algorithms. This algorithm is based on the divide and conquer paradigm. The main idea
behind this sorting is partitioning of the elements.
Steps for Quick Sort:
Divide: partition the array into two nonempty sub arrays.
al
Combine: two sub arrays are already sorted in place so no need to combine.
itn
Example: a[]={5, 3, 2, 6, 4, 1, 3, 7}
(1 3 2 3 4) 5 (5 7)
and continue this process for each sub-arrays and finally we get a sorted array.
Algorithm:
QuickSort(A,l,r)
{
f(l<r)
{
p = Partition(A,l,r);
QuickSort(A,l,p-1);
QuickSort(A,p+1,r);
}
}
Partition(A,l,r)
{
x =l;
y =r ;
p = A[l];
while(x<y)
{
while(A[x] <= p)
al
x++;
while(A[y] >=p)
ep
y--;
if(x<y)
itn
swap(A[x],A[y]);
DSA 115 By Bhupendra Saud
cs
Source: www.csitnepal.com
}
A[l] = A[y];
A[y] = p;
return y; //return position of pivot
}
Time Complexity:
Best Case:
Divides the array into two partitions of equal size, therefore
T(n) = 2T(n/2) + O(n) , Solving this recurrence we get,
T(n)=O(nlogn)
Worst case:
when one partition contains the n-1 elements and another partition contains only one element.
Therefore its recurrence relation is:
T(n) = T(n-1) + O(n), Solving this recurrence we get
T(n)=O(n2)
Average case:
Good and bad splits are randomly distributed across throughout the tree
T1(n)= 2T'(n/2) + O(n) Balanced
T'(n)= T(n 1) + O(n) Unbalanced
Solving:
B(n)= 2(B(n/2 1) + (n/2)) + (n)
= 2B(n/2 1) + (n)
= O(nlogn)
=>T(n)=O(nlogn)
Merge Sort
To sort an array A[l . . r]:
Divide
Divide the n-element sequence to be sorted into two sub-sequences of n/2 elements
Conquer
Sort the sub-sequences recursively using merge sort. When the size of the sequences
is 1 there is nothing more to do
Combine
Merge the two sorted sub-sequences
Example: a[]={4, 7, 2, 6, 1, 4, 7, 3, 5, 2, 6}
al
ep
itn
al
ep
itn
Time Complexity:
Recurrence Relation for Merge sort:
T(n) = 1 if n=1
T(n) = 2 T(n/2) + O(n) if n>1
Solving this recurrence we get
T(n) = O(nlogn)
Space Complexity:
It uses one extra array and some extra variables during sorting, therefore
al
Unit 8: Searching:
a) Introduction
b) Sequential search
c) Binary search
d) Comparison and efficiency of searching
e) Hashing
probing (Linear and Quadratic)
Introduction:
Searching is a process of finding an element within the list of elements stored in any order or
randomly. Searching is divided into two categories Linear and Binary search.
Sequential Search:
In linear search, access each element of an array one by one sequentially and see
whether it is desired element or not. A search will be unsuccessful if all the elements are
accessed and the desired element is not found.
In brief, Simply search for the given element left to right and return the index of the element, if
found. Otherwise return Not Found.
Algorithm:
LinearSearch(A, n,key)
{
for(i=0;i<n;i++)
{
if(A[i] == key)
return i;
}
al
Analysis:
Time complexity = O(n)
itn
Running example:
Take input array a[] = {2 , 5 , 7, 9 ,18, 45 ,53, 59, 67, 72, 88, 95, 101, 104}
al
ep
itn
Hashing:
It is an efficient searching technique in which key is placed in direct accessible address for
rapid search.
Hashing provides the direct access of records from the file no matter where the record is in
the file. Due to which it reduces the unnecessary comparisons. This technique uses a
hashing function say h which maps the key with the corresponding key address or
location.
A function that transforms a key into a table index is called a hash function.
A common hash function is
h(x)=x mod SIZE
if key=27 and SIZE=10 then
al
hash address=27%10=7
ep
itn
Hash collision:
If two or more than two records trying to insert in a single index of a hash table then such
a situation is called hash collision.
Some popular methods for minimizing collision are:
Linear probing
Quadratic probing
Rehashing
Chaining
Hashing using buckets etc
But here we need only first two methods for minimizing collision
Linear probing:
A hash-table in which a collision is resolved by putting the item in the next empty place
within the occupied array space.
It starts with a location where the collision occurred and does a sequential search through a
hash table for the desired empty location.
Hence this method searches in straight line, and it is therefore called linear probing.
Disadvantage:
Clustering problem
al
Example:
ep
Insert keys {89, 18, 49, 58, 69} with the hash function
h(x)=x mod 10 using linear probing.
itn
solution:
DSA 122 By Bhupendra Saud
cs
Source: www.csitnepal.com
when x=89:
h(89)=89%10=9
insert key 89 in hash-table in location 9
when x=18:
h(18)=18%10=8
insert key 18 in hash-table in location 8
when x=49:
h(49)=49%10=9 (Collision occur)
so insert key 49 in hash-table in next possible vacant location of 9 is 0
when x=58:
h(58)=58%10=8 (Collision occur)
insert key 58 in hash-table in next possible vacant location of 8 is 1
(since 9, 0 already contains values).
when x=69:
h(89)=69%10=9 (Collision occur)
insert key 69 in hash-table in next possible vacant location of 9 is 2
(since 0, 1 already contains values).
Quadratic Probing:
Quadratic probing is a collision resolution method that eliminates the primary
clustering problem take place in a linear probing.
When collision occur then the quadratic probing works as follows:
(Hash value + 12)% table size
if there is again collision occur then there exist rehashing.
al
when x=18:
h(18)=18%10=8
insert key 18 in hash-table in location 8
when x=49:
h(49)=49%10=9 (Collision occur)
so use following hash function,
h1(49)=(49 + 1)%10=0
hence insert key 49 in hash-table in location 0
when x=58:
h(58)=58%10=8 (Collision occur)
so use following hash function,
h1(58)=(58 + 1)%10=9
again collision occur use again the following hash function ,
h2(58)=(58+ 22)%10=2
insert key 58 in hash-table in location 2
when x=69:
h(89)=69%10=9 (Collision occur)
so use following hash function,
h1(69)=(69 + 1)%10=0
again collision occur use again the following hash function ,
h2(69)=(69+ 22)%10=3
insert key 69 in hash-table in location 3
al
ep
Unit:9
Graph:
a) Introduction
b) Representation of Graph
Array
Linked list
c) Traversals
Depth first Search
Breadth first search
d) Minimum spanning tree
Kruskal's algorithm
Graph:
A Graph is a pair G = (V,E) where V denotes a set of vertices and E denotes the set of
edges connecting two vertices. Many natural problems can be explained using graph for
example modeling road network, electronic circuits, etc. The example below shows the road
network.
Types of Graph:
Simple Graph:
We define a simple graph as 2 tuple consists of a non empty set of vertices V and a
set of unordered pairs of distinct elements of vertices called edges. We can represent graph as
al
G = (V, E). This kind of graph has no loops and can be used for modeling networks that do not
ep
have connection to themselves but have both ways connection when two vertices are connected
itn
Multigraph:
A multigraph G =(V, E) consists of a set of vertices V, a set of edges E, and a function f
from E to {{u, v}|u, v V, u v}. The edges e1 and e2 are called multiple or parallel edges if
f(e1) = f(e2). In this representation of graph also loops are not allowed. Since simple graph has
single edges every simple graph is a multigraph. The figure below is an example of a
multigraph.
Pseudograph:
A pseudograph G =(V, E) consists of a set of vertices V, a set of edges E, and a
function f from E to {{u, v}|u, v V}. An edge is a loop if f(e) = {u, u} = {u} for some u V.
The figure below is an example of a multigraph
Directed Graph:
A directed graph (V, E) consists of a set V of vertices, a set E of edges that are ordered
pairs of elements of V. The below figure is a directed graph. In this graph loop is allowed but
no two vertices van have multiple edges in same direction.
al
Directed Multigraph:
ep
itn
Terminologies:
Two vertices u, v are adjacent vertices of a graph if {u, v} is an edge.
The edge e is called incident with the vertices u and v if e = {u, v}. This edge is also said to
connect u and v. where u and v are end points of the edge.
Degree of a vertex in an undirected graph is the number of edges incident with it, except a
loop at a vertex. Loop in a vertex counts twice to the degree. Degree of a vertex v is denoted by
deg (v).A vertex of degree zero is called isolated vertex and a vertex with degree one is called
pendant vertex.
Example: Find the degrees of the vertices in the following graph.
Solution:
deg(a) = deg(f) = deg(e) = 2 ; deg(b) = deg(c) = 3; deg(d) = 4
Representation of Graph
Generally graph can be represented in two ways namely adjacency lists(Linked list
representation) and adjacency matrix(matrix).
Adjacency List:
This type of representation is suitable for the undirected graphs without multiple edges,
and directed graphs. This representation looks as in the tables below.
al
ep
itn
If we try to apply the algorithms of graph using the representation of graphs by lists of edges,
or adjacency lists it can be tedious and time taking if there are high number of edges. For the
sake of the computation, the graphs with many edges can be represented in other ways. In this
class we discuss two ways of representing graphs in form of matrix.
Adjacency Matrix:
Given a simple graph G =(V, E) with |V| = n. assume that the vertices of the graph
are listed in some arbitrary order like v1, v2, , vn. The adjacency matrix A of G, with respect
to the order of the vertices is n-by-n zero-one matrix (A = [aij]) with the condition,
Since there are n vertices and we may order vertices in any order there are n! possible order of
the vertices. The adjacency matrix depends on the order of the vertices, hence there are n!
possible adjacency matrices for a graph with n vertices.
In case of the directed graph we can extend the same concept as in undirected graph as
dictated by the relation
al
If the number of edges is few then the adjacency matrix becomes sparse. Sometimes it will be
ep
Solution:
Let the order of the vertices be a, b, c, d, e, f, g
Graph Traversals
Breadth-first search:
This is one of the simplest methods of graph searching. Choose some vertex arbitrarily
al
as a root. Add all the vertices and edges that are incident in the root. The new vertices added
will become the vertices at the level 1 of the BFS tree. Form the set of the added vertices of
ep
level 1, find other vertices, such that they are connected by edges at level 1 vertices. Follow the
above step until all the vertices are added.
itn
Algorithm:
BFS(G,s) //s is start vertex
{
T = {s};
L =; //an empty queue
Enqueue(L,s);
while (L != )
{
v = dequeue(L);
for each neighbor w to v
if ( w L and w T )
{
enqueue( L,w);
al
}
}
itn
and form a path by starting at a root vertex by successively adding vertices and edges. This
process is continued until no possible path can be formed. If the path contains all the vertices
then the tree consisting this path is DFS tree. Otherwise, we must add other edges and vertices.
For this move back from the last vertex that is met in the previous path and find whether it is
possible to find new path starting from the vertex just met. If there is such a path continue the
process above. If this cannot be done, move back to another vertex and repeat the process. The
whole process is continued until all the vertices are met. This method of search is also called
backtracking.
Example:
Use depth first search to find a spanning tree of the following graph.
al
ep
itn
al
ep
itn
Analysis:
The complexity of the algorithm is greatly affected by Traverse function we can write
its running time in terms of the relation T(n) = T(n-1) + O(n), here O(n) is for each vertex at
most all the vertices are checked (for loop). At each recursive call a vertex is decreased.
Solving this we can find that the complexity of an algorithm is O(n2).
Kruskals Algorithm:
The problem of finding MST can be solved by using Kruskals algorithm. The idea
behind this algorithm is that you put the set of edges form the given graph G = (V,E) in
nondecreasing order of their weights. The selection of each edge in sequence then guarantees
that the total cost that would from will be the minimum. Note that we have G as a graph, V as a
set of n vertices and E as set of edges of graph G.
Example:
Find the MST and its weight of the graph.
al
ep
itn
Algorithm:
KruskalMST(G)
{
T = {V} // forest of n nodes
S = set of edges sorted in nondecreasing order of weight
while(|T| < n-1 and E !=)
{
Select (u,v) from S in order
Remove (u,v) from E
if((u,v) doesnot create a cycle in T))
T = T {(u,v)}
}
}
Analysis:
In the above algorithm the n tree forest at the beginning takes (V) time, the creation of
set S takes O(ElogE) time and while loop execute O(n) times and the steps inside the loop take
almost linear time (see disjoint set operations; find and union). So the total time taken is
O(ElogE)
al
ep
itn
Email: Saud.bhupendra427@gmail.com