Data Structures Using C (Modern College5)
Data Structures Using C (Modern College5)
(CS-211)
S.Y.B.Sc.(Computer Science)
Semester I
Authors:
Prof. Mrs. Madhuri Ghanekar
Prof. Mrs. A. S. Bachav
Prof. Mrs. Smita Ghorpade
Prof. Mrs. G. S. Marane
Prof. Mrs. Sonali Ghule
1
Table of Contents
1. Sorting Techniques……………………………………………………………5
2. Searching Techniques………………………………………………………...11
3. Linked List……………………………………………………………………...14
4. Stack……..………………………………………………………………………28
5. Queue..………..…………………………………………………………………33
6. Trees....…………………………………………………………………………...40
7.Graph...…………………………………………………………………………...46
2
About the Work Book
1. Note Done 0
2. Incomplete 1
3.Late Complete 2
4.Needs Improvement 3
5.Complete 4
6.Well Done 5
3
Instructions to the Practical In-charge
4
SESSION 1: Sorting Techniques Start Date ___/____/______
Objectives
To learn about:
Sorting array elements in increasing/decreasing order
Various sorting methods and their time complexity
Searching methods and their time complexity
Reading
You should read the following topics before starting the exercise.
1. Numeric / Character arrays and Array of structures.
2. Compare the one element with another element of the array
3. Swap the content of one location with another location in the array.
4. How to find the time complexity of an algorithm?
Ready References
The time T(P) taken by a program P is the sum of the compile time and the
run (or execution) time. As compilation is a one time procedure, we
approximate time complexity to execution time.For this we calculate the
number of executable steps of any program which can be stored in a variable
stepcnt.
As these 2 operations are more time consuming, for sorting and searching
algorithms swapcnt and compcnt is calculated to find number of swaps and
number of comparisons along with the stepcnt.
5
Program Segment Comments
for (i=0; i< n; i++)
{ stepcnt ++; compcnt++; Checking i< n so compcnt++
if ( x[i] > x[j] ) Comparing 2 elements
{ compcnt++; So compcnt++
swapcnt++; Swapping of 2 elements
temp = x[i]; So swapcnt ++
x[i] = x[j];
x[j] = x[i]; Total 4 steps . so stepcnt += 4
stepcnt +=4;
}
Most of the applications store lots of data and to find the required data from
it, we must keep it in some sensible order. The sorting refers to the operation
of arranging data in some given order, such as increasing or decreasing, with
numerical or character data. There are various sorting methods are available.
Most commonly used methods are
(1) Bubble Sort (2)Insertion Sort (3)Merge Sort (4)Quick Sort
Algorithm Complexity
1. Accept n numbers into the array x The number of passes: n-1
2. Initialize i=0 In first pass n-1 comparisons
3. Repeat step 4 to 7 as long as (i<n) In second pass n-2 comparisons
4. if (x[j]>x[j+1]) and so on
interchange x[j] and x[j+1] Total=(n-1)+(n-2)+……+1= n(n-
5. Increment j 1)/2
6. if j<n-1-j got step 3 Time Complexity=O(n2)
7. Increment i Best case= O(n2)
8. stop Worst case= O(n2)
Example:
Original array x 57 25 48 92 12 37
After Pass 1 25 48 57 12 37 92
After Pass 2 25 48 12 37 57 92
After Pass 3 25 12 37 48 57 92
After Pass 4 12 25 37 48 57 92
After Pass 5 12 25 37 48 57 92
6
1.2.2 Insertion Sort
Place an element into correct position in growing sorted list of data. Assume
that we have a sorted list of i elements. We take the next element and add it to
the sorted list in such a position that a new list of (i+1) elements is sorted.
Algorithm Complexity
1. Accept n numbers into the array x Best case: If the initial data is
2. Let x[0] is sorted list of one element. sorted, only one comparison is
3. Let j=1 made in each pass. So the
4. Let newelem=x[j] and i=j-1 complexity is O(n).
5. Repeat step 6 to 7 as long as
(i>=0) and (newelem<x[i]) Worst case: If the initial data is in
6. Move x[i] at (i+1) position reverse order, total number of
7. i=i-1 comparisons for (n-1) passes will
8. Insert newelem at position (i+1) be
i.e. x[i+1]=newelem 1+2+3+……+(n-1)=n(n-1)/2
9. j=j+1 So the complexity is O(n2)
10. If j<n go to step 4
11. stop
Example:
Let x[0] is sorted list: 57 25 48 12 36
Pass-1: newelem=25: 25 57 48 12 36
Pass-2: newelem=48: 25 48 57 12 36
Pass-3: newelem=57: 25 48 57 12 36
Pass-4: newelem=12: 25 48 57 57 36
25 48 48 57 36
25 25 48 57 36
12 25 48 57 36
Pass-5: newelem=36: 12 25 48 57 57
12 25 48 48 57
12 25 36 48 57
1.2.3 Merge Sort
It is based on Divide and Conquer Strategy. First the list to be sorted is
decomposed into two sublists(Divide). Each sublist is sorted
independently(Conquer). Then these two sorted sublists are merged into
sorted sequence(Combine).
7
Algorithm Complexity
//Array x of size n is to be sorted, Initially After pass P, the array x is
lb=0, ub=n-1 partitioned into sorted
Mergesort(x, lb, ub) subarrays where subarray,
1. If (lb<ub) do steps 2 to 5 otherwise goto 6 except possibly the last, will
2. Find mid=(lb+ub)/2 contain exactly 2P elements.
3. call mergesort(lb, mid) Hence the algorithm requires
4. call mergesort(mid+1, ub) at most log2 n passes to sort
5. call merge(x, lb, mid, ub) n elements of array x.
6. stop However each pass merges a
total of n elements.
//Merge two sorted sublists x[lb..mid] and So time complexity,
x[mid+1..ub] to create a new sorted list Best Case: O(n log n)
x[lb…ub] Worst Case: O(n log n)
Merge(x. lb, mid, ub)
1. //copy x into temp list
For i=lb to ub do
temp[i]=x[i]
2. Let i=lb, j=mid+1, k=lb
3. Repeat steps 4 to 6 while (i<=mid and
j<=ub)
4. If (temp[i]<=temp[j]) //elem of first sublist
is smaller/equal
x[k]=temp[i] //copy elem of first sublist
Increment i and k
5. Otherwise //elem of second sublist is
smaller
x[k]=temp[j] //copy elem of second
sublist
Increment j and k
6. Continue step 3
7. Copy remaining elements of first sublist
into x if any
8. Copy remaining elements of second sublist
into x if any
9. stop
8
Example:
Original array: [66 33 40 22 55 88 60 11]
Pass-1: Merge each pair of elements to obtain the list of sorted pairs
[66 33 40 22 55 88 60 11]
Pass-2: Merge each pair of pairs to obtain the list of sorted quadruples
Pass-3: Merge each pair of sorted quadruples to obtain the sorted array
[11 22 33 40 55 60 88]
Algorithm Complexity
//sort array x[lb..ub]. Initially lb=0 and Best case: The reduction step
ub=n-1 produces two sublists. The
QuickSort(x, lb, ub) // x is array reduction step in the kth level
1. If (lb<ub) do steps 2 to 8 otherwise there will be 2k sublists. Each
goto 9 level uses at most n
2. Let i=lb, j=ub, a=x[i] //to find posi comparisons.
for a So the time complexity is
3. Repeat step 4 while (x[j]>a && j>i) O(n log n)
4. decrement j Worst case: If the list is
5. Interchange x[i] and x[j] already sorted then at first
6. Repeat step 7 while (x[i]<=a && i<j) level, first list is empty and
7. increment i second list contains (n-1)
8. Interchange x[i] and x[j] elements. Accordingly the
9. quicksort(x, lb, i-1) //recursive call to second element require (n-1)
sublist comparisons and so on.
10. quicksort(x, i+1, ub)//recursive call to So the total comparisons are
sublist n+(n-1)+…+2+1= n(n+1)/2
11. Stop The time complexity is
O(n2)
9
Practical Assignments
SET A
1) Write a C program to read n numbers from the user and sort them in
ascending/ descending order using Bubble sort method. Use step count, swap
count, comp count in your program to calculate time complexity and at end
display the 3 counts
2) Write a C program to read n numbers from the user and sort them in
ascending/descending order using Insertion sort method. Use step count,
swap count, comp count in your program to calculate time complexity.
SET B
1) Write a C program to read n numbers from the user and sort them in
ascending/ descending order using Merge sort. Use step count, swap count,
comp count in your program to calculate time complexity.
2) Write a C program to read n numbers from the user and sort them in
ascending/ descending order using Quick sort. Use step count, swap count,
comp count in your program to calculate time complexity.
SET C
1) Write a program that accept name of persons into array and sort them in
alphabetical order.
2) Write a program that accept employee name, age and salary into array and
sort them in descending order of salary. [ Hint: Use array of structure]
Assignment Evaluation
End of Session
10
SESSION 2: Searching Techniques Start Date ___/____/______
Objectives
To learn about:
Searching a desired element in the array
Various searching methods and their time complexity
Reading
You should read the following topics before starting the exercise.
1. Numeric / Character arrays and Array of structures.
2. Compare an element with any element of the array
3. Sorting the content of array in ascending or descending order
4. How to find the time complexity of an algorithm?
Ready References
Let LIST be a collection of data elements into memory. Searching refers to the
operation of finding the location of given ITEM in LIST. The searching said to
be successful, if ITEM is found in LIST and unsuccessful otherwise.
There are two commonly used searching methods or algorithms
(1) Linear Search (2) Binary Search
In this method ITEM is compare with each element of LIST one by one. That
is, first we test whether LIST[0] = ITEM and then we test whether
LIST[1]=ITEM and so on. This method which traverses LIST sequentially to
locate ITEM is called Linear or Sequential search.
Algorithm Complexity
//Linear Search ITEM in LIST of n elements Best Case:
1. LOC=0 ITEM found at location 1
2. Repeat steps 3 to 4 while (LOC<n) Number of comparisons=1
3. If (LIST[LOC]=ITEM)
print ITEM found at location LOC Worst Case:
stop ITEM not found in LIST
4. Otherwise Number of comparisons=n
increment LOC by 1 Complexity is O(n)
continue step 2
5. print ITEM not found in LIST An average of (n+1)/2
6. Stop comparisons are required to
search ITEM in a LIST.
Time complexity is O(n)
11
2.2. Binary Search
Algorithm Complexity
//Binary Search ITEM in LIST of n elements Best Case:
//LB-Lower Bound UB-Upper Bound of LIST ITEM found at MID position
Number of Comparisons=1
Recursive
Bsearch(LIST, ITEM, LB, UB) Worst Case:
1. If (LB>UB) ITEM not found in LIST
Print ITEM not found in LIST After 1 comparison, remaining size
Stop of LIST to be search is
2. Find MID=(LB+UB)/2 (n/2)=(n/21).
3. If (LIST[MID]=ITEM) After 2 comparisons, remaining
Print ITEM found at location MID in LIST size of LIST to be search is
Stop (n/4)=(n/22).
4. Otherwise If (LIST[MID]<ITEM) After k comparisons, remaining
Bsearch(LIST, ITEM, LB, MID-1) //call size of LIST to be search is (n/2k).
5. Otherwise
6. Bsearch(LIST, ITEM, MID+1, UB) //call If after k comparisons, remaining
file size is 1 then (n/2k)=1.
Non-Recursive That means n=2k
1. Let LB=0, UB=n-1 k=log2 n
2. Repeat steps 3 to 5 while (LB<UB) So, time complexity is O(log2 n)
3. Find MID=(LB+UB)/2
4. If (LIST[MID]=ITEM)
Print ITEM found at location MID in LIST
Stop
5. Otherwise If (LIST[MID]<ITEM)
UB=MID-1 //search in upper half
Continue step 2
6. Otherwise
LB=MID+1 //search in lower half
Continue step 2
7. Print ITEM not found in LIST
8. Stop
12
Practical Assignments
SET A
2) Write a program to accept list of cities and search a given city using Linear
Search. Use stepcnt, swapcnt, compcnt in your program to calculate time
complexity and at end display the 3 counts
SET B
SET C
Accept city name, area and population for n cities into array. Find the area
and population of given city using
1) Linear Search method
2) Binary Search method
(Hint: Use array of structures and sort the array on city name before applying
binary search)
Assignment Evaluation
End of Session
13
SESSION 3: Linked List Start Date ___/____/______
Objectives
To learn about:
Linked list implementation – dynamic and static.
Types of linked lists - singly linked list, singly circular linked list,
doubly linked list, doubly circular linked list.
Reading
Ready References
Linked list is a collection of nodes. These nodes are nothing but dynamic
variables. These dynamic variables are allocated memory from heap space.
All the nodes present in the linked list are not stored in contiguous memory
location hence every node of the linked list contains data(info) and pointer to
the next node called as link.
Head
Info link
10 20 30 40 50 NULL
14
3.1.1. How to create a singly linked list?
Following are the steps to create singly linked list. In this example, we are
crating a singly sorted linked list.
getnode() : This operation creates new node for the linked list.
DATANODE *getnode() {
DATANODE *temp = (DATANODE *) malloc(sizeof(DATANODE));
temp->next = NULL;
}
freenode() : This operation is used to free the memory allocated to the node. This
operation is essential if the linked list contains complex data. It may be needed to
release all the resources acquired by the node.
void freenode(DATANODE *ptr) {
free(ptr); /*deallocated memory of DATANODE pointed by ptr.*/
}
append(): This operation will attach new node as the last node in the sorted linked
list.
void append(DATANODE **head, int value) {
DATANODE *p=NULL, *new=NULL;
insert(): This operation is used to insert new node in the existing sorted linked list.
void insert(DATANODE **head,int value) {
DATANODE *p=NULL, *q=NULL, *new=NULL;
int i=1;
return;
}
if ( (*head)->info > value) /* New node has smallest value in the list.*/
{
new->next = *head;
*head = new;
return;
}
p = *head;
while ( p && p->info <= value)
{
q = p; /* q follows p*/
p = p->next; /* p moves to the next node.*/
}
16
Step6: Operation to delete node from the sorted linked list.
del(): This operation removes the specified node from the list and then that node
will be deallocated.
void del(DATANODE **head, int value) {
DATANODE *p=NULL, *q=NULL;
if (*head == NULL)
{
printf("Error :: Linked List Is Empty.!");
exit(1);
}
if ((*head)->info == value) /*First node contains value.*/
{
p = *head;
*head = (*head)->next; /*Second node will become first in the list.*/
freenode(p); /*Delete node pointed by p.*/
return;
}
if (!p)
{
printf("Data Not Found In The List.!");
return;
}
17
Step7: Operation to display all nodes of the linked list.
display(): This operation will display data present in all nodes of the list.
void display(DATANODE *p) {
/*Traverse till the end of the list.*/
while (p)
{
printf("%d ", p->info);
p = p->next;
}
}
destroylisr(): This operation will delete all nodes of the list. This operation is
required after the use of linked list in application is over. This will release the
memory acquired by the list.
void destroylist(DATANODE **head) {
DATANODE *p = NULL;
p = *head;
while (p)
{
*head = p->next; /*Shift head pointer to the next node.*/
freenode(p); /*Delete the node previously pointed by head.*/
p = *head;
}
}
18
Program Listing: Sorted Singly Linked List.
int main()
{
int num,n,i;
DATANODE *list = NULL; /* Initialize linked list.*/
append(&list,num);
while(i < n)
{
i++;
insert(&list,num);
}
19
printf("The linked list is as follows......\n");
display(list);
/*Delete all nodes from the linked list to free memory locations.*/
destroylist(&list);
return 0;
}
DATANODE *getnode() {
DATANODE *temp = (DATANODE *) malloc(sizeof(DATANODE)); /* create
node of type DATANODE.*/
temp->next = NULL;
}
return;
}
if ( (*head)->info > value) /* New node has smallest value in the list.*/
{
new->next = *head;
*head = new;
return;
}
p = *head;
while ( p && p->info <= value)
{
q = p; /* q follows p*/
p = p->next; /* p moves to the next node.*/
}
20
void append(DATANODE **head, int value) {
DATANODE *p=NULL, *new=NULL;
if (*head == NULL) /* List is empty. New node will be appended as the first
node in the list.*/
{
*head = new;
return;
}
if (*head == NULL)
{
printf("Error :: Linked List Is Empty.!");
exit(1);
}
if ((*head)->info == value) /*First node contains value.*/
{
p = *head;
*head = (*head)->next; /*Second node will become first in the list.*/
freenode(p); /*Delete node pointed by p.*/
return;
}
if (!p)
{
printf("Data Not Found In The List.!");
return;
}
p = *head;
while (p)
{
*head = p->next; /*Shift head pointer to the next node.*/
freenode(p); /*Delete the node previously pointed by head.*/
p = *head;
}
}
#> cc SortedSinglyLinkedList.c
#> ./a.out
22
Prev info Prev
Head
NULL 10 20 30 40 NULL
Self Activity
Following are the steps to create doubly linked list. In this example, we are
crating a doubly sorted linked list.
getnode() : This operation creates new node for the linked list.
DATANODE *getnode() {
DATANODE *temp = (DATANODE *) malloc(sizeof(DATANODE));
temp->prev = NULL;
temp->next = NULL;
}
freenode() : This operation is used to free the memory allocated to the node. This
operation is essential if the linked list contains complex data. It may be needed to
release all the resources acquired by the node.
23
Stepr4: Implement function to append new node in the sorted doubly linked
list.
append(): This operation will attach new node as the last node in the sorted linked
list.
void append(DATANODE **head, int value) {
DATANODE *p=NULL, *new=NULL;
Step5: Implement function to insert new node in the sorted doubly list.
insert(): This operation is used to insert new node in the existing sorted list.
void insert(DATANODE **head,int value) {
DATANODE *p=NULL, *q=NULL, *new=NULL;
int i=1;
if ( (*head)->info > value) /* New node has smallest value in the list.*/
{
p = *head;
while ( p && p->info <= value)
{
}
/* Insertion between q and p.*/
24
Step6: Implement function to delete node from the sorted doubly linked list.
del(): This operation removes specified node from the list and then that node will
be deallocated.
void del(DATANODE **head, int value) {
DATANODE *p=NULL, *q=NULL;
if (*head == NULL)
{
}
if ((*head)->info == value) /*First node contains value.*/
{
if (!p)
{
Step7: Implement function to display all nodes of the doubly linked list in
forward as well as reverse order.
display(): This operation will display data present in all nodes of the list.
void display(DATANODE *p) {
/*Traverse till the end of the list.*/
while (p)
{
printf("%d ", p->info);
p = p->next;
}
/*Traverse the list in reverse till we reach to the first node in the list.*/
25
Step8: Operation to delete all nodes of the list.
destroylisr(): This operation will delete all nodes of the list. This operation is
required after the use of linked list in application is over. This will release the
memory acquired by the list.
p = *head;
while (p)
{
*head = p->next; /*Shift head pointer to the next node.*/
freenode(p); /*Delete the node previously pointed by head.*/
p = *head;
}
}
NOTE:
1. Please note that the above programs and program skeletons are guidelines
for students. You are free to implement linked list by your own method under
the guidance of teacher.
2. Linked list with header node will simplify insertion and deletion
operations. Please concern your teacher to know more about it.
Practical Assignments
SET A
2. Write a C program to implement circular singly linked list. What are the
advantages of circular singly list over linear singly list?
3. Write a C program to implement doubly circular linked list. What are the
advantages of circular double linked list over linear doubly linked list?
SET B
26
SET C
Assignment Evaluation
End of Session
27
SESSION 4: Stack Start Date ___/____/______
Objectives
To learn about:
Concept of Stack
Operations on stack
Implementation of stack using array
Implementation of stack using linked list
Applications of Stack
Reading
Ready References
4.1. Stack
In stack, insertion and deletion is possible only from one end called as top
of the stack. It is a LIFO(Last In First Out) data structure.
push(stk,x)
Data item x can pushed into stack stk. The size of stack stk is increased
by 1. Top of the stack stk will be pointing to the last inserted element x.
This operation is always valid because stack doesn’t have any upper
limit. But, if stack is implemented using array then it can grow up to
the size of array.
If array is full, push() operation is not possible. This condition is called
as “Stack Overflow Condition”.
x = pop(stk)
Topmost element of stack is removed from stack stk. The size of stack
is reduced by 1 after this operation.
This operation is invalid if stack is empty. The pop() operation on
empty stack results into “Stack Underflow” condition.
x = stacktop(stk)
This operation returns the copy of topmost element present in stack
stk. It does not remove it. The size of stack is unchanged after this
operation.
This operation is invalid if stack is empty. The stacktop() operation
on empty stack results into “Stack Underflow” condition.
empty(stk)
The empty() operation returns true if the stack is empty, otherwise it
returns false.
28
Self Activity
29
Step6: Implement empty() operation.
typedef struct
{
int info;
struct node *next;
} Stack;
top 10 20 30
push(&top, 5);
top 5 10 20 30
push(&top, 2);
top 2 5 10 20 30
4. Implement pop() function.
top 2 5 10 20 30
X = pop(&top);
top 5 10 20 30 2
Deleted Node
X = pop(&top);
top 10 20 30 5
Deleted Node
5. Implement stacktop() function.
Practical Assignments
SET A
31
Does all these functions are implemented using stack? If yes, How they are
using stack?
SET B
2. Write a C program to convert infix expression into prefix form and evaluate
it.
SET C
Assignment Evaluation
End of Session
32
SESSION 5: QUEUE Start Date ___/____/______
Objectives
To learn about:
The data structure QUEUE
QUEUE as an Abstract Data Type
Types of QUEUE
Operations on QUEUE
Static QUEUE
Dynamic QUEUE
Applications of QUEUE
Reading
Ready References
5.1. Queue
The QUEUE is a FIFO (First In First Out) structure. We use this term many a
times in our day to day activities. E.g. Cinema QUEUE, bus QUEUE etc.
There are 2 active pointers to QUEUE, front and rear. We follow certain
rules:
1) All additions at the rear end and all deletions from the front end
It means that we always add new elements towards the rear end and we
always delete the elements from the front end.
Depending upon the strategy you choose, you can initialize the front and rear.
For strategy a) we initialize front = -1, rear = -1;
For strategy b) we initialize front = 0, rear = 0;
33
In the static implementation of queue front and rear are integers as they are
giving the location of the array where delete / insert should take place. In the
dynamic implementation of queue front and rear are pointers.
Types of Queue:
1) Linear queue
2) Circular queue
3) Priority queue
4) Double Ended Queue (DEQUE)
Front Rear
10 20 30 40 50 60 70 80 90
0 1 2 3 4 5 6 7 8
Operations on a QUEUE :
2) Initialize : Initialize the rear and front pointers for an empty queue.
If we use increment rear and add at that position strategy, we initialize
front and rear to -1, if we adopt the other strategy, we initialize both
front and rear to zero.
void initq( Q * P)
{ P -> rear = -1;
P -> front = -1;
}
34
3) Add or insert : Adds a new element to the queue at the rear end. The
operation can only be performed if the queue is not full. If the queue
is full, and we try to add an element, an overflow results.
4) Delete : Removes an element from the front end of the queue. The
operation can only be performed if the queue is not empty.
int delQ(Q * P)
{ if( !isempty(P) )
return ( P -> data[++ ( P->front)]);
else
return 0;
}
Method 1: Let the positions be empty only. This will cause wastage of
memory locations.
int isfull(Q *P)
{
if(p->rear == MAX -1)
{ printf(“Q is full “ ) ;
return 1 ;
}
else
return 0 ;
}
35
Method 2: If empty positions at beginning of queue, and rear reaches
MAX – 1 then perform shift queue to reuse empty locations in the array.
int isfull(Q *P)
{
if(p->rear == MAX -1)
{ if (p->front == -1)
return 1 ;
else
shiftq(p) ;
return 0 ;
}
7) ShiftQ : As there are 2 active ends, (all additions at the rear end and all
deletions from the front end,) even if you add at the rear end some
locations towards begining of the queue might be empty. You have to
reset the front pointer when rear reaches the MAX -1 position. i.e. You
have to shift the queue elements to the beginning of the queue
periodically( or when rear reaches MAX – 1) to get the free spaces at
the rear end. ) sothat the empty locations can be utilized.
The word dynamic refers to run time allocation of memory. So for this
purpose we use malloc(), calloc() kind of functions for run time memory
allocation. Here, we get the memory allocated as per requirement. Therefore,
the maximum number of items in the Queue we need not mention. Items can
be linked together , so the item is stored in one node of the linked list. As and
how we want to store an item , we get one node allocated.
The declaration will look like this:
36
For a dynamic queue except shiftQ() ,we write all the above functions.
shiftQ() is not written because we are not required to shift the queue
elements.
front rear
10 20 30 40 50
This queue also will not require shiftQ() function. Works like a clock. The first
and the last positions are coming side by side. Also if MAXSIZE is 6( positions
available are 0 to 5), then the 7th item should be placed in the zeroth position.
i.e. We have to increment rear to rear + 1 % MAX when rear reaches to MAX-
1 and front to front +1 % MAX when front reaches to MAX -1.Here one
position from the queue will be underutilized.
37
Types of priority Queue :
1. Ascending Priority Queue : Elements can be inserted arbitrarily but
only the smallest element gets deleted first
2. Descending Priority Queue: Only the largest element gets deleted first.
5.6 Dequeue
This is Double Ended Queue. A DEQUE is a linear list in which elements can
be added or removed at either end. Elements can be added or removed from
front or the rear end.
A DEQUE is generalization of a stack and a queue.
Types of DEQUE:
1. Input restricted DEQUE : allows insertin at only one end of the list but
allows deletion from both the ends.
2. Output restricted DEQUE : allows deletion at only one end of the list,
but allows insertion at both ends of the list.
Operations possible are:
Enquefront() : To add at front end of the queue.
Enquerear() : To add at rear end of the queue.
Dequeuefront() : To delete item at the fron end of the queue.
Dequeuerear() : To delete an item at rear end of queue.
Practical Assignments
SET A
38
3. Write a C program to implement a queue of integers using linked list. The
program should be menu driven with the following options: ADD, DELETE,
EXIT.
typedef struct node
{
// members
}NODE;
SET B
SET C
Assignment Evaluation
End of Session
39
SESSION 6: Tree Start Date ___/____/______
Objectives
To learn about:
The data structure Tree
Tree as an Abstract Data Type
Types of Tree
Operations on Tree
Applications of Tree
Reading
Ready References
A binary tree is a special form of a tree. A binary tree is finite set of nodes,
which is empty or partitioned into 3 sets, one which is the root and the other 2
are binary trees called its left and right subtrees. It is a tree where every node
can have at the most two branches or children. Some frequently used types of
binary trees are as follows:
1. Binary Search Tree (BST)
2. Expression Tree
3. Heap Tree
4. Threaded Binary Tree
5. Huffman Tree
6. Height Balanced Tree (AVL tree)
Definition:
A binary search tree is a binary tree, which is either empty or in which each
node contains a key that satisfies following conditions:
1) For every node X, in the tree the values of all the keys in its left subtree are
smaller than the key value in X.
2) For every node X, in the tree the values of all the keys in its right subtree
are larger than the key value in X.
40
Structure of a node of a BST:
typedef struct BST
{ int data;
struct BST * left, * right;
}BSTnode;
BSTnode * create()
{ int i, totnodes, val;
BSTnode * root =NULL;
printf(“ How many nodes to create?”);
scanf(“%d”, &totnodes);
printf(“Enter node values : “);
for ( i=0;i<totnodes;i++)
{ scanf(“%d”,&val);
root = insert(root, val);
}
return ( root);
}
4. Traversal: To visit all nodes and print the data of the BST. There are 3 types
of traversals: inorder, preorder, postorder.
41
5. Findmin: Finds the minimum value in the BST. This value is situated in
the leftmost node of the BST.
BSTnode * findmin(BSTnode *T)
{ while (T->left != NULL)
T = T->left;
return(T);
}
6. Findmax : Finds the maximum value of the BST. This value is situated at
the rightmost position of BST.
Types of heaps:
a) MaxHeap : A max heap is a complete binary tree with the property
that the value of each node is at least as large as the values at its
children. In the max heap the largest element is at the root.
b) MinHeap : A min heap is a complete binary tree with the property
that the value at each node is at least as small as the values at its
children. Here, the smallest element is at the root.
Algorithm :
Step 1: Construct a max-heap. heap[0] has total values n and heap[1] is largest
element.
Step 2: Swap heap[1] and heap[n]. This will put largest at heap[n].
Step 3: Reduce the heap size by 1. i.e. heap[0] = heap[0] – 1; Largest element
is in the array but it is not a part of the heap.
Step 4: The new tree represented by heap[1..n-1] may no longer be a heap, as
heap[1] is changed. The new tree can be converted to a heap by using a
function downadjust().
Step 5 : Repeat steps 2 to 4, while number of elements in the heap > 1 ( i.e.
heap[0] > 1)
42
Function to create the max-heap:
43
heap[j] = temp;
i = j;
}/* end if */
}/* end while */
}/* end down adjust */
Practical Assignments
SET A
1. a) Write a menu driven program for Binary Search Tree creation and
inorder, preorder, postorder recursive traversal of all nodes.
b) Modify the above program for performing following operations :
a. Search a value.
b. Insertion of a value
SET B
1. Write a program to create Binary Search tree with the following functions:
a) tcopy - function to make an identical copy of a tree T, returns root
of newly created tree
b) tmirror – checks whether a tree t1 is a mirror image of tree t2,
returns 1 if true else returns 0
c) tleafcnt - counting leaf nodes of a tree T
44
SET C
Assignment Evaluation
End of Session
45
SESSION 7: Graph Start Date ___/____/______
Objectives
To learn about:
Implementation of adjacency matrix and adjacency list
Implementation of adjacency mult-ilist
Graph traversal – BFS and DFS
Shortest path algorithm – Dijkstra’s Algorithm
Reading
You should read the following topics before starting the exercise.
1. Graph Terminologies - vertex, edge, graph, path, complete graph,
2. Graph representation techniques – Adjacency matrix, Adjacency
list
3. Examples on Adjacency matrix, Adjacency list
Ready References
Adjacency Matrix
A adjacency matrix A has a natural interpretation as
A[v,w] = 1 iff vertex v is adjacent to vertex w, otherwise A[v,w] = 0(if not
adjacent)
Example:
0 1 0 0
V1 V2
0 0 1 1 Adjacency Matrix
Graph G
0 0 0 0
V4 V3 1 1 1 0
V1 V2 NULL
V3 V4 NULL
V2
V3 NULL
V1 V2 V3 NULL
V4
Algorithm
1. Initialize visited array to 0
2. v is the starting vertex
3. visited [v] = 1
4. display v
5. Search for w which is an unvisited vertex adjacent to v
6. if w is found
Visited [w] =1
Display w
Push w into stack
Go to 5
7. v=pop
8. Continue from 5 till stack becomes empty
9. Stop.
Topological Sort
Graphs are commonly used for project planning which consists of many
interdependent activities. These activities are represented as vertices and
the directed edges represent the order of activities. Such graph is called an
Activity On Vertex (AOV). The process of converting a set of precedence
represented by an AOV network into a linear list in which no later activity
precedes an earlier one is called topological sorting.
Algorithm
1. Accept AOV network in adjacency list form
2. S is an empty stack
3. Search for vertex v whose in-degree is 0
4. if v is not found
if stack is empty
go to 9
else
go to 5
if not found
if stack is empty
go to 8
else
go to 5
5. if found
make in-degree of v = -1
push v into stack
6. pop v from the stack and display
7. Reduce the in-degree of all vertices adjacent to v by 1
8. Repeat from step 3 till all vertices have been visited
9. Stop.
Algorithm
1. V is the starting vertex
2. Initialize visited array to 0
3. Initialize all the elements of distance array as
Dist [i] = cost [v] [i]
4. visited [v] =1
5. num=1
6. while (num <n)
{
u=choose (dist, n); num=num+1
/* choose is the function which returns u such that
Dist [u] = min{ dist[w]} where visited [w] is false */
For w= 1 to n-1
{
If (!visited[w] )
If (dist[u]+cost[u][w]<dist[w])
Dist[w]=dist[u]+cost[u][w]
}
}
7. dist array contains the shortest paths from V to all other destinations
8. Stop
Practical Assignments
SET A
49
SET B
D
A
D
A
SET C
50
Period Method 1 Method 2 Method 3
1 A, F F A, F
2 B, H A, H H
3 I B, I B, J
4 C C C
5 D D D
6 E E E
A D F
B E
Assignment Evaluation
End of Session
51