Download Data Structures Using C(cs221) - Prof. Ramkrishna More Arts

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts

Array data structure wikipedia , lookup

Quadtree wikipedia , lookup

Red–black tree wikipedia , lookup

Lattice model (finance) wikipedia , lookup

B-tree wikipedia , lookup

Interval tree wikipedia , lookup

Binary tree wikipedia , lookup

Linked list wikipedia , lookup

Binary search tree wikipedia , lookup

Transcript
University of Pune
Data Structures Using C
(CS-211)
S.Y.B.Sc.(Computer Science)
Semester I
1
Advisors:
Prof. A. G. Gangarde (Chairman, BOS-Comp. Sc.)
Chairman:
Prof. S. S. Deshmukh (Head & Vice-Principal, Modern College, Pune 5)
Co-ordinator:
Mr. A. V. Sathe
Authors:
Mrs. Madhuri Ghanekar
Mrs. A. S. Bachav
Mrs. Smita Ghorpade
Mrs. G. S. Marane
Mrs. Sonali Ghule
Board of Study (Computer Science) members:
1. Mr. M. N. Shelar
2. Mr. S. N. Shinde
3. Mr. U. S. Surve
4. Mr. V. R. Wani
5. Mr. Prashant Mule
6. Dr.Vilas Kharat
7. Mrs. Chitra Nagarkar
2
Table of Contents
About the work book……………………………………………………………4
1. Sorting Techniques……………………………………………………………6
2. Searching Techniques………………………………………………………...12
3. Linked List……………………………………………………………………...15
4. Stack……..………………………………………………………………………29
5. Queue..………..…………………………………………………………………34
6. Trees....…………………………………………………………………………...41
7.Graph...…………………………………………………………………………...47
3
About the Work Book
Objectives of this book
This workbook is intended to be used by S.Y.B.Sc(Computer Science) students
for the two computer science laboratory courses.
The objectives of this book are
1. The scope of the course.
2. Bringing uniformity in the way course is conducted across different
colleges.
3. Continuous assessment of the students.
4. Providing ready references for students while working in the lab.
How to use this book?
This book is mandatory for the completion of the laboratory course. It is a
measure of the performance of the student in the laboratory for the entire
duration of the course.
Instructions to the students
1)
2)
3)
4)
Students should carry this book during practical sessions of computer
science.
Students should maintain separate journal for the source code, SQL
queries/commands along with outputs.
Student should read the topics mentioned in Reading section of this
book before coming for practical.
Students should solve only those exercises which are selected by
practical in-charge as a part of journal activity. However, students are
free to solve additional exercises to do more practice for their practical
examination.
Exercise Set
Self Activity
Difficulty Level
NA
SET A
Easy
SET B
Medium
SET C
Difficult
5)
Rule
Student should solve
these exercises for
practice only.
All exercises are
compulsory.
At least one exercise is
mandatory.
Not Compulsory.
Students will be assessed for each exercise on a scale of 5
1. Note Done
2. Incomplete
3.Late Complete
4.Needs Improvement
5.Complete
6.Well Done
0
1
2
3
4
5
4
Instructions to the Practical In-charge
1)
2)
3)
4)
5)
6)
Explain the assignment and related concepts in around ten minutes
using white board if required or by demonstrating the software.
Choose appropriate problems to be solved by student.
After a student completes a specific set, the instructor has to verify the
outputs and sign in the provided space after the activity.
Ensure that the students use good programming practices.
You should evaluate each assignment carried out by a student on a
scale of 5 as specified above ticking appropriate box.
The value should also be entered on assignment completion page of
respected lab course.
5
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
1.1 Time complexity
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.
Algorithm Sum(a,n)
1 {
2
S= 0.0;
3
Stepcnt = stepcnt +1;
4
For i = 1 to n do
5
{
6
Stepcnt=stepcnt+1;
7
S = S + a[i];
8
Stepcnt = stepcnt +1;
9
}
10
Stepcnt = stepcnt +1;
11
Stepcnt = stepcnt +1;
12
Return S;
13 }
Comments
Stepcnt is initially zero.
For the execution of for
statement increment it once.
Increment for the assignment
statement
For the last invocation of for
For the return
Important operations for sorting and searching algorithms are as follows:
1. Number of interchanges/swaps
2. Number of comparisons
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.
6
Program Segment
for (i=O; i< n; i++)
{ stepcnt ++; compcnt++;
if ( x[i] > x[j] )
{
swapcnt++;
temp = x[i];
x[i] = x[j];
x[j] = x[i];
stepcnt +=4;
}
Comments
Comparing 2 elements
So compcnt++
Swapping of 2 elements
So swapcnt ++
Total 4 steps . so stepcnt += 4
1.2 Sorting Techniques
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
1.2.1 Bubble Sort
In this method successive elements are compared and exchange according to
the order required. The list to be sorted is traversed several times. Each pass
puts one element in its correct position. In successive parses, the largest
element sinks to the bottom.
1.
2.
3.
4.
5.
6.
7.
8.
Algorithm
Accept n numbers into the array x
Initialize i=O
Repeat step 4 to 7 as long as (i<n)
if (x[j]>x[j+1])
interchange x[j] and x[j+1]
Increment j
if j<n-1-j got step 3
Increment i
stop
Example:
Original array x
After Pass 1
After Pass 2
After Pass 3
After Pass 4
After Pass 5
57
25
25
25
12
12
25
48
48
12
25
25
48
57
12
37
37
37
Complexity
 The number of passes: n-1
 In first pass n-1 comparisons
 In second pass n-2 comparisons
and so on
 Total=(n-1)+(n-2)+……+1= n(n1)/2
 Time Complexity=O(n2)
 Best case= O(n2)
 Worst case= O(n2)
92
12
37
48
48
48
12
37
57
57
57
57
37
92
92
92
92
92
7
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
Accept n numbers into the array x
Let x[O] is sorted list of one element.
Let j=1
Let newelem=x[j] and i=j-1
Repeat step 6 to 7 as long as
(i>=O) and (newelem<x[i])
6. Move x[i] at (i+1) position
7. i=i-1
8. Insert newelem at position (i+1)
i.e. x[i+1]=newelem
9. j=j+1
1O. If j<n go to step 4
11. stop
Complexity
Best case: If the initial data is
sorted, only one comparison is
made in each pass. So the
complexity is 0(n).
1.
2.
3.
4.
5.
Example:
Let x[O] is sorted list:
Pass-1: newelem=25:
Pass-2: newelem=48:
Pass-3: newelem=57:
Pass-4: newelem=12:
Pass-5: newelem=36:
57
25
25
25
25
25
25
12
12
12
12
25
57
48
48
48
48
25
25
25
25
25
Worst case: If the initial data is in
reverse order, total number of
comparisons for (n-1) passes will
be
1+2+3+……+(n-1)=n(n-1)/2
So the complexity is 0(n2)
48
48
57
57
57
48
48
48
48
48
36
12
12
12
12
57
57
57
57
57
48
48
36
36
36
36
36
36
36
36
57
57
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).
8
Algorithm
//Array x of size n is to be sorted, Initially
lb=O, ub=n-1
Mergesort(x, lb, ub)
1. If (lb<ub) do steps 2 to 5 otherwise goto 6
2. Find mid=(lb+ub)/2
3. call mergesort(lb, mid)
4. call mergesort(mid+1, ub)
5. call merge(x, lb, mid, ub)
6. stop
//Merge two sorted sublists x[lb..mid]
and x[mid+1..ub] to create a new sorted list
x[lb…ub]
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
Complexity
After pass P, the array x is
partitioned into sorted
subarrays where subarray,
except possibly the last, will
contain exactly 2P elements.
Hence the algorithm requires
at most log2 n passes to sort
n elements of array x.
However each pass merges a
total of n elements.
So time complexity,
Best Case: O(n log n)
Worst Case: O(n log n)
9
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
11] [33 66]
55
88
[22 40]
60
[55 88]
[11 60]
Pass-2: Merge each pair of pairs to obtain the list of sorted quadruples
[33 66]
[22 40]
60] [22 33 40 60]
[55 88]
[11
[11 55 60 88]
Pass-3: Merge each pair of sorted quadruples to obtain the sorted array
[11
22
33
40
55
60
88]
1.2.4 Quick Sort
It is also based on Divide and Conquer Strategy. Let x be an array and n be
number of elements in the array to be sorted. To find proper position j for any
element a of array x, it is partitioned at position j such that
(I) All elements from 0 to j-1 are smaller than or equal to a
(II) All elements from j+1 to n-1 are greater than a.
Algorithm
//sort array x[lb..ub]. Initially lb=0 and
ub=n-1
QuickSort(x, lb, ub) // x is array
1. If (lb<ub) do steps 2 to 8 otherwise
goto 9
2. Let i=lb, j=ub, a=x[i] //to find
posi
for a
3. Repeat step 4 while (x[j]>a && j>i)
4.
decrement j
5. Interchange x[i] and x[j]
6. Repeat step 7 while (x[i]<=a && i<j)
7.
increment i
8. Interchange x[i] and x[j]
9. quicksort(x, lb, i-1) //recursive call
to
sublist
10. quicksort(x, i+1, ub)//recursive call
to
sublist
11. Stop
Complexity
Best case: The reduction step
produces two sublists. The
reduction step in the kth level
there will be 2k sublists. Each
level uses at most n
comparisons.
So the time complexity is
O(n log n)
Worst case: If the list is
already sorted then at first
level, first list is empty and
second list contains (n-1)
elements. Accordingly the
second element require (n-1)
comparisons and so on.
So the total comparisons are
n+(n-1)+…+2+1= n(n+1)/2
The time complexity is
O(n2)
10
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
0: Not Done [ ]
1:Incomplete [ ]
2.Late Complete [ ]
3:Needs Improvement [ ]
4:Complete [ ]
5:Well Done [ ]
Signature of the Instructor
Date of Completion
!
!
End of Session
11
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
2.1. Linear 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
!!Linear Search ITEM in LIST of n elements
1. LOC=0
2. Repeat steps 3 to 4 while (LOC<n)
3. If (LIST[LOC]=ITEM)
print ITEM found at location LOC
stop
4. Otherwise
increment LOC by 1
continue step 2
5. print ITEM not found in LIST
6. Stop
Complexity
Best Case:
ITEM found at location 1
Number of comparisons=1
Worst Case:
ITEM not found in LIST
Number of comparisons=n
Complexity is O(n)
An average of (n+1)!2
comparisons are required to
search ITEM in a LIST.
Time complexity is O(n)
12
2.2. Binary Search
If the collection elements in a LIST is stored in sorted order (ascending or
descending) then there is extremely efficient searching algorithm called
Binary Search is available. In this method LIST is divided into two halves. The
ITEM to be search is compare with middle element of the LIST. If matches
then search terminates otherwise continues further. If the ITEM is less than
middle element then the search proceeds in upper half of the LIST. If the
ITEM is greater than middle element then the search proceed in lower half of
the LIST.
Algorithm
!!Binary Search ITEM in LIST of n elements
!!LB-Lower Bound UB-Upper Bound of LIST
Recursive
Bsearch(LIST, ITEM, LB, UB)
1. If (LB>UB)
Print ITEM not found in LIST
Stop
2. Find MID=(LB+UB)!2
3. If (LIST[MID]=ITEM)
Print ITEM found at location MID in LIST
Stop
4. Otherwise If (LIST[MID]<ITEM)
Bsearch(LIST, ITEM, LB, MID-1) !!call
5. Otherwise
6. Bsearch(LIST, ITEM, MID+1, UB) !!call
Non-Recursive
1. Let LB=O, UB=n-1
2. Repeat steps 3 to 5 while (LB<UB)
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
Complexity
Best Case:
ITEM found at MID position
Number of Comparisons=1
Worst Case:
ITEM not found in LIST
After 1 comparison, remaining size
of LIST to be search is
(n!2)=(n!21).
After 2 comparisons, remaining
size of LIST to be search is
(n!4)=(n!22).
After k comparisons, remaining
size of LIST to be search is (n!2k).
If after k comparisons, remaining
file size is 1 then (n!2k)=1.
That means n=2k
k=log2 n
So, time complexity is O(log2 n)
13
Practical Assignments
SET A
1) Write a program to accept list of n numbers and search a given number
using Linear Search. Use stepcnt, swapcnt, compcnt in your program to
calculate time complexity and at end display the 3 counts
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
1) Write a program to accept list of sorted n numbers and search a given
number using Binary Search.
2) Write a program to accept list of student names in alphabetical order and
search a given name using Binary Search.
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
0: Not Done [ ]
1:Incomplete [ ]
2.Late Complete [ ]
3:Needs Improvement [ ]
4:Complete [ ]
5:Well Done [ ]
Signature of the Instructor
Date of Completion
!
!
End of Session
14
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
You should read following topics before starting the exercise.
 static and dynamic variables
 limitations of Array
 pointers in C
 malloc() and free() functions in C
 Concept of linked list
Ready References
3.1 Linked list
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.
Info Iink
Head
10
20
30
40
50 NULL
Following are the operations of linked lists:
 getnode() — creates a node for the linked list.
 freenode() — releases the memory acquired by the node .
 insertAt(int item, int pos) — insert the new element in the linked list by
inserting a new node.
 deleteAt(int pos) — delete a node from the linked list.
 append(int item) — append new node at the end of the list.
15
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.
Step1: Declare Self-referential structure
typedef struct node {
int info;
!*data part of node*!
struct node *next; !*pointer to the next node*!
} DATANODE;
Step2: getnode() operation for the linked list.
getnode() : This operation creates new node for the linked list.
DATANODE *getnode() {
DATANODE *temp = (DATANODE *) malloc(sizeof(DATANODE));
temp->next = NULL;
}
Step3:freenode() operation for the linked list..
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.*!
}
Stepr4: Operation to append new node in the sorted 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;
!* Create new node.*!
new = getnode();
new->info = value;
if (*head == NULL) !* List is empty. New node will be appended as the
first node in the list.*!
{
*head = new;
return;
}
!*Traverse the list till the end.*!
p = *head;
while(p->next)
p = p->next;
16
}
!*Append new node.*!
p->next = new;
Step5: Operation to insert new node in the sorted list.
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;
!*Create new node. *!
new = getnode();
new->info = value;
if ( *head == NULL) !* Linked List Is Empty.*!
{
*head = new; !* New node becomes the first node in the linked list.*!
}
return;
if ( (*head)->info > value) !* New node has smallest value in the list.*!
{
new->next = *head;
*head = new;
return;
}
!*Traverse list to reach specific position.*!
p = *head;
while ( p && p->info <= value)
{
q = p;
!* q follows p*!
p = p->next; !* p moves to the next node.*!
}
}
!* Insertion between q and p.*!
q->next = new;
new->next = p;
17
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;
}
!*Traverse the list to search for specific node.*!
p = *head;
while(p)
{
q=p; !*q follows p.*!
p=p->next;
}
if (!p)
{
}
printf(”Data Not Found In The List.!”);
return;
!*Remove node pointed by p from the list.*!
q->next = p->next;
}
freenode(p); !*Delete node pointed by p.*!
18
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;
}
}
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.
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;
}
}
19
Program Listing: Sorted Singly Linked List.
/* Program to implement sorted singly linked list.*/
#include <stdio.h> !*for input!output operations*!
#include <malloc.h> !*for accessing library functions: malloc(), free()*!
#include <stdlib.h> !*for accessing library functions such as exit()*!
!* Declare Self Referential Structure for creating nodes of linked list.*!
typedef struct node {
int info;
!*data part of node*!
struct node *next; !*pointer to the next node*!
} DATANODE;
DATANODE *getnode(); !* Creates New Data Node.*!
void freenode(DATANODE *ptr); !*Deallocates the memory assigned to datanode.*!
void insert(DATANODE **head,int value);!*Inserts new node at the specified
position.*!
void del(DATANODE **head, int value);!*Delete the node from specified position.*!
void append(DATANODE **head, int value);!*Add new element as the last node in
the linked list.*!
void display(DATANODE *head);!*Display all elements of the linked list.*!
void destroylist(DATANODE **head); !*Delete all nodes from the list.*!
int main()
{
int num,n,i;
DATANODE *list = NULL; !* Initialize linked list.*!
printf(”Program to store integers in sorted order.\n”);
printf(”How many Numbers?:”);
scanf(”%d”,&n);
!* Append first number in the list.*!
i = 1;
printf(”Enter Number %d:”,i);
scanf(”%d”,&num);
append(&list,num);
!*Insert remaining numbers in the list.*!
while(i < n)
{
i++;
printf(”Enter Number %d:”, i);
scanf(”%d”,&num);
}
insert(&list,num);
20
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;
}
void freenode(DATANODE *ptr) {
free(ptr); !*deallocated memory of DATANODE pointed by ptr.*!
}
void insert(DATANODE **head,int value) {
DATANODE *p=NULL, *q=NULL, *new=NULL;
int i=1;
!*Create new node. *!
new = getnode();
new->info = value;
if ( *head == NULL) !* Linked List Is Empty.*!
{
*head = new; !* New node becomes the first node in the linked list.*!
return;
}
if ( (*head)->info > value) !* New node has smallest value in the list.*!
{
new->next = *head;
*head = new;
return;
}
!*Traverse list to reach specific position.*!
p = *head;
while ( p && p->info <= value)
{
q = p;
!* q follows p*!
p = p->next; !* p moves to the next node.*!
}
}
!* Insertion between q and p.*!
q->next = new;
new->next = p;
21
void append(DATANODE **head, int value) {
DATANODE *p=NULL, *new=NULL;
!* Create new node.*!
new = getnode();
new->info = value;
if (*head == NULL) !* List is empty. New node will be appended as the first
node in the list.*!
{
*head = new;
return;
}
!*Traverse the list till the end.*!
p = *head;
while(p->next)
p = p->next;
}
!*Append new node.*!
p->next = new;
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;
}
!*Traverse the list to search for specific node.*!
p = *head;
while(p)
{
q=p; !*q follows p.*!
p=p->next;
}
if (!p)
{
}
printf(“Data Not Found In The List.!“);
return;
!*Remove node pointed by p from the list.*!
q->next = p->next;
22
freenode(p); !*Delete node pointed by p.*!
}
void display(DATANODE *p) {
!*Traverse till the end of the list.*!
while (p)
{
printf(”%d ”, p->info);
p = p->next;
}
}
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;
}
}
Compile and run this program as follows to see the output:
#> cc SortedSinglyLinkedList.c
#> ./a.out
1. Modify this program to delete repetitive elements from the list.
2. Modify this program to add header node in the linked list. Header node should
contain a count of total nodes present in the linked list.
3.2. Doubly Linked List
Need for doubly linked list:
 In singly linked list
0 traversing is possible only in forward direction.
0 If the value to be searched in a linked list is toward the end of
the list, the search time would be higher.

In doubly linked list, traversing is possible in both directions and
search can be continued from any node in between either in forward of
backward direction.
Characteristics of doubly linked list
 In a doubly linked list, each node has two pointers, one pointing to the
next node in the list, and the other pointing to previous node in the list.
 Previous pointer of first node is always NULL in doubly linked list.
 Last node’s next pointer is always NULL in doubly linked list.
23
Prey
info
Prev
Head
NULL
10
20
30
40
NULL
Operations of doubly linked list
Doubly linked contains same operations as in singly linked list. If
required, traversing for doubly linked could be implemented in reverse
order.
Self Activity
Let’s create doubly linked list.
Following are the steps to create doubly linked list. In this example, we are
crating a doubly sorted linked list.
Step1: Declare Self-referential structure
typedef struct node
{
struct node *prev; !*pointer to the previous node.*!
int info;
!*data part of node*!
struct node *next; !*pointer to the next node*!
} DATANODE;
Step2: getnode() operation for the 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;
}
Step3: freenode() operation for the linked lisr.
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.*!
}
24
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;
!* Create new node.*!
if (*head == NULL)
first node in the list.*!
{
}
!* List is empty. New node will be appended as the
!*Traverse the list till the end.*!
}
!*Append new node.*!
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;
!*Create new node. *!
if ( *head == NULL) !* Linked List Is Empty.*!
{
}
if ( (*head)_>info > value) !* New node has smallest value in the list.*!
{
}
!*Traverse list to reach specific position.*!
p = *head;
while ( p && p_>info <= value)
{
}
!* Insertion between q and p.*!
}
25
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.*!
{
}
!*Traverse the list to search for specific node.*!
p = *head;
while(p)
{
}
if (!p)
{
}
!*Remove node pointed by p from the list.*!
}
freenode(p); !*Delete node pointed by 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.*!
}
26
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.
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;
}
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
1. Write a C program to implement singly linked list of integers using array.
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
1. Write a C program to perform union, intersection operations on two sorted
linked lists.
2. Write a C program to add two polynomials using linked list.
3. Write a C program to multiply two polynomials.
27
SET C
1. Write a C program to sort the singly linked list of integers. (Create an
unsorted list and then sort it.
2. Write a C program to merge two sorted linked list.
3. Write a C program to create linked list of strings. Display all strings
containing same substring. (Accept substring from user.)
Assignment Evaluation
0: Not Done [ ]
1:Incomplete [ ]
2.Late Complete [ ]
3:Needs Improvement [ ]
4:Complete [ ]
5:Well Done [ ]
Signature of the Instructor
Date of Completion
!
!
End of Session
28
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
You should read following topics before starting the exercise.
 Linked list implementation
 Stack as a data structure and all its applications
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.
Following operations are possible on stack:
 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.
29
Self Activity
Let’s implement Stack using Array (Static Representation)
Stepi. Define structure to hold Stack as a single entity.
typedef struct Stack
{
int data[MAXSIZE_1];
int top;
} STACK;
Step2: Implement initlist() operation for the Stack.
void initlist(STACK *stk)
{
!* Write a code to initialize top pointer to _1 *!
}
Step3: Implement push() operation.
void push(STACK *stk, int item)
{
!* Write a code to check for “Overflow Condition.” *!
}
!* Write a code to add new item at the top of stack.*!
Step4: Implement pop() operation.
int pop( STACK *stk)
{
!* Write a code to check for “Overflow Condition”. *!
!* Write a code to delete and return topmost element from the
stack.*!
}
Step5: Implement stacktop() operation.
int stacktop( STACK *stk)
{
!* Write a code to check for “Overflow Condition”. *!
!* Write a code to return a copy of topmost element from the
stack.*!
}
30
Step6: Implement empty() operation.
int empty(STACK *stk)
{
!* if top is _1, the list is empty. *!
}
Let’s Implement Stack using Linked list (Dynamic Representation)
Following are some guidelines to implement stack using linked list:
1. Define a structure for stack.
typedef struct
{
int info;
struct node *next;
} Stack;
2. Declare stack pointer which will be treated as top pointer.
Stack *top = NULL;
3. Implement push() function
void push(Stack **top, int item)
{
!* Write a code to insert new node (new element of stack) at first
position of the linked list. In other words, top pointer will be always
pointing to newly inserted node in the linked list.*!
}
top
10
20
30
10
20
30
10
20
push(&top, 5);
top
5
push(&top, 2);
2
5
top
4. Implement pop() function.
30
int pop(Stack **top)
{
31
!* Write a code to delete first node from the list.*!
!*Return data from deleted node.*!
}
top
2
5
l0
20
30
l0
20
30
2
X = pop(&top);
top
5
Deleted Node
X = pop(&top);
top
l0
20
30
5
Deleted Node
5. Implement stacktop() function.
int stacktop(Stack **top)
{
!*Write a code to return the value of the first node without
deleting it.*!
}
6. Implement empty() function.
int empty(Stack **top)
{
}
Practical Assignments
SET A
1. Write a C program to reverse a string using static stack. (Create Stack.h
file.)
2. Write a C program to check whether the string is palindrome or not using
dynamic stack. (Use Stack.h file.)
3. Write a recursive functions to solve following problems:
a. Towers of Hanoi problem with n disks. (n must be accepted from user.)
b. Calculate power of x to the n.
c. Fibbonacci series.
32
Does all these functions are implemented using stack? If yes, How they are
using stack?
SET B
1. Write a C program to convert infix expression into postfix form and
evaluate it.
2. Write a C program to convert infix expression into prefix form and evaluate
it.
SET C
1. Write a C program to simulate recursion of following functions:
a. Factorial of n numbers
b. Power function
2. Write a C program to simulate recursion of Towers of Hanoi function.
Assignment Evaluation
0: Not Done [ ]
1:Incomplete [ ]
2.Late Complete [ ]
3:Needs Improvement [ ]
4:Complete [ ]
5:Well Done [ ]
Signature of the Instructor
Date of Completion
!
!
End of Session
33
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
You should read following topics before starting the exercise:
 concept of queue
 Representation of queue using array and linked list
 Concept of circular queue, dequeue, priority queue.
 multiple queues
Ready References
5.1. Queue
Definition: A queue is an ordered collection of items, from which items may
be deleted from one end called the front, and into which items may be
inserted at the other end called the rear end of the queue.
QUEUE as an Abstract Data Type :
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.
2) We normally use one of the following strategies:
a) Increment rear and then add at that position
OR
b) Add at the rear position and then increment rear.
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;
34
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)
2)
3)
4)
Linear queue
Circular queue
Priority queue
Double Ended Queue (DEQUE)
All those types can be implemented either statically or dynamically.
5.2. Implementation of linear queue using array (static representation)
Static implementation is array based implantation. This requires a structure
(using struct keyword) as it allows us, user defined datatype declaration (Q
becomes user defined datatype). Inside the structure we declare an array to
store int data, and two pointers front and rear.
Front
Rear
10 20 30
0
1
2
40 50
3
4
60
5
70 80 90
6
7
8
Operations on a QUEUE :
Different operations possible on a queue are as follows:
1) Create: This creates a new empty queue.
#define MAX 10
typedef struct QUEUE
{ int data[MAX];
int rear, front;
} Q;
Q q1, q2; !* create 2 queues. */
Q *P;
P = &q1;
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;
}
35
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.
int addQ(Q*p, int x)
{ if (! isfull(p))
{ p_>data[++(p_>rear)] = x;
return 1;
}
return 0;
}
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;
}
5) Isempty : Checks whether a queue is empty, returns TRUE if queue is
empty and FALSE otherwise.
int isempty(Q *P)
{ if (P_>front = = P_>rear)
return 1;
else
return 0;
}
6) Isfull : Checks whether a queue is full, returns TRUE if queue is full
and returns FALSE otherwise.
If rear reaches MAX _1, but front is not _1, so some empty positions
exist at the beginning of the queue. Now this situation is tackled in 2
ways.
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 ;
}
36
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.
void shiftQ( Q *P)
{ int topos =0, frompos;
for( frompos = P->front+1; frompos < MAX; frompos++)
P_>data[topos++]=P_>data[frompos];
P_>front = _1;
P_>rear = topos_1;
}
8) Display: Print elements of the queue.
5.3 Implementation of queue using linked list (Dynamic Queue)
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:
typedef struct QUEUE
{ int data;
struct QUEUE *next;
}QNODE;
QNODE *front, *rear;
In the initialize function we can initialize front and rear to NULL;
37
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
10
rear
20
30
40
50
5.4 Circular Queue
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.
typedef struct CirQ
{ int items[MAX];
int front, rear;
}Q;
Functions for Circular Queue:
1. Initialize Queue
void initQ (Q* cq)
{ cq_> front = cq_>rear = MAX _1;
}
2. IsemptyQ
Prototype: int isemptyQ(Q *cq)
Queue will be empty if rear = front
3. IsfullQ
int isfullQ(Q* cq)
{ return ((cq_>rear+1)% MAX == cq_>front)
4. AddQ
Prototype: int addQ(Q *cq, int item)
If Q is not full, then increment rear to (rear +1) % MAX and then add
at that position.
5. DelQ
Prototype: int delQ(Q *cq)
While deleting increment front to (front + 1) % MAX and then delete.
Return the deleted element
5.5 Priority Queue
Definition: A priority Queue is a data structure in which the intrinsic
ordering among the elements decides the result of its basic operations.
38
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
1. Write a C program to implement linear queue of strings using array. Store
the structure and queue functions in “queue.h” and write the main function in
a .C file. The program should be menu driven with the options : ADD,
DELETE, EXIT.
typedef struct
{
!! members
}queue;
void initq(queue *pq) {
}
int isempty(queue *pq) {
}
int isfull(queue *pq)
{
}
void addq(queue *pq, char *str) {
}
char *delq(queue *pq) {
}
void main()
{
queue q;
//menu driven program
}
2. Write a C program to implement a circular queue using array. (Refer to the
code above)
39
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
INODE;
NODE *front, *rear; !!global variable
void initqueue() {
I
void addq(int n) {
I
int delq() {
I
int isempty() {
I
void main()
{
!!menu driven program
I
SET B
1. Write a C program to implement static ascending priority queue.
2. Write a C program to sort n integers using bucket sort method.
SET C
1. Write a C program to implement static DEQUE.
2. Write a C program to implement Multiple Queues using single array.
3. Write a C program to implement Josephus problem.
Assignment Evaluation
0: Not Done [ ]
1:Incomplete [ ]
2.Late Complete [ ]
3:Needs Improvement [ ]
4:Complete [ ]
5:Well Done [ ]
Signature of the Instructor
Date of Completion
!
!
End of Session
40
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
You should read following topics before starting the exercise.
 Concept & Terminologies of Binary tree and binary search tree
 Operations on BST — create. Insert, delete, traversals (preorder, inorder,
postorder), counting leaf, non_leaf & total nodes
 Application _ Heap sort, Height balance tree_ AVL trees_ Rotations
Ready References
Tree can be treated as a special case of generalized link list.
6.1 Binary Tree
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)
6.2 Binary Search Tree (BST)
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.
41
Structure of a node of a BST:
typedef struct BST
{ int data;
struct BST * left, * right;
IBSTnode;
Operations on a binary Search Tree:
1. Create: creating a binary search tree(BST).A BST can be created by
making repeated calls to insert operation.
BSTnode * create()
{ int i, totnodes, val;
BSTnode * root =NULL;
printf(” How many nodes to create?”);
scanf(”%d”, &totnodes);
printf(”Enter node values : ”);
for ( i=O;i<totnodes;i++)
{ scanf(”%d”,&val);
root = insert(root, val);
I
return ( root);
I
2. Insert: Inserting one node in the BST.
BSTnode * insert(BSTnode * T, int x)
{
if ( T = = NULL)
{ T = (BSTnode*) malloc (sizeof(BSTnode));
T_> data = x;
T_>left = NULL;
T_>right = NULL;
return (T);
I
if(x > T_>data)
{ T_> right = insert(T_>right, x);
return (T);
I
T_>left = insert(T_>left, x);
return (T);
I
3. Delete:
a)
b)
c)
Deleting one node of the BST. There are 3 cases:
deleting a leaf node
deleting a node with one child
deleting a node with 2 children
4. Traversal: To visit all nodes and print the data of the BST. There are 3 types
of traversals: inorder, preorder, postorder.
42
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);
I
6. Findmax : Finds the maximum value of the BST. This value is situated at
the rightmost position of BST.
Prototype : BSTnode * findmax(BSTnode *T)
7. Find: finds the value X in the BST
Prototype : BSTnode * find(BSTnode, int x)
6.3. Heap Tree
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.
Sorting in ascending order:
The best known application of heap is in sorting. It uses a very simple
strategy for sorting. A heap can be sorted through repeated application of
delete max( ) in the Maxheap. An array can be used for heap sort.
Accept all values in an array where at zeroth position total number of
values are stored.
Algorithm :
Step 1: Construct a max_heap. heap[O] 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[O] = heap[O] — 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[O] > 1)
43
Function to create the max_heap:
void create(int heap[])
{
int i,n;
n = heap[O];
for ( i=n!2; i>=1; i )
down_adjust(heap,i);
I
Function to readjust the heap
void down_adjust(int heap[], int i)
{
int j, temp, n,flag = 1;
n= heap[O];
while (2*i <= n && flag = = 1)
{
j = 2 *i; !* j points to left child *!
if ( j + 1 <=n && heap[j+1] > heap[j])
j=j+1;
if (heap[i] > heap[j])
flag = O;
else
{
temp = heap[i];
heap[i] = heap[j];
44
heap[j] = temp;
i = j;
I!* end if *!
I!* end while *!
I!* end down adjust *!
Function to sort the array elements:
Sort(int heap[])
{
int last, temp;
while (heap[0] > 1)
{
!* swap heap[1] with heap[last] *!
last = heap[0];
temp = heap[1];
heap[1] = heap[last];
heap[last] = temp;
heap[o] ;
down_adjust(heap,1);
I
I
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
2. Write a program to perform Heap_sort using arrays.
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
2. Write a program to create and evaluate expression tree.
3. Modify program in set A (Exercise 1) to perform deletion of a node in the
BST
45
SET C
1. Write a program to perform Non_recursive traversal using stack(inorder,
preorder, postorder) on the BST
2. Write a program to create height balanced tree. Write appropriate
functions for different cases_ LL, RR, LR, RL to rotate the tree and maintain
the balance.
3. Write a program to create Huffman tree for compression.
Assignment Evaluation
0: Not Done [ ]
1:Incomplete [ ]
2.Late Complete [ ]
3:Needs Improvement [ ]
4:Complete [ ]
5:Well Done [ ]
Signature of the Instructor
Date of Completion
!
!
End of Session
46
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
7.1 Representation of Graph
If we want to represent cities and highways connecting them, we can
represent this information in the form a graph. Or components on circuit
board with the connections among them. An organic chemical compound can
be considered as a graph with atoms as the vertices and the bonds between
them as edges. For such need most suitable data structure is ‘graph’. In
computer systems graph can be stored using adjacency matrix, adjacency list
or adjacency multilist.
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] = O(if not
adjacent)
Example:
V1
0
1
0
0
0
1
1
0
0
0
0
1
1
1
0
Graph G
V4
0
V2
Adjacency Matrix
V3
Adjacency List: Another way to represent a graph is adjacency list. This is
linked list representation of graph; there is one list for each vertex in the
graph. Thus for ‘n’ vertices, n list will be prepared. Each node of the list I
consists of
1. Vertex numbers to which vertex I is adjacent
2. Pointer to the next node in the list
47
Example:
For above graph G adjacency list:
Vi
V2
V2
V3
NULL
V4
NULL
NULL
V3
Vi
V4
V2
V3
NULL
7.2 Graph Traversal Methods
In many problems we wish to investigate all the vertices in a graph in some
systematic order, just as with binary trees we developed several systematic
traversals methods. In tree traversal, we had w root as a starting vertex; in
graph we often do not have any one vertex as a special, and therefore the
traversal may start at an arbitrary vertex. This lecture focus on graph traversal
techniques _ DFS, BFS.
1. Depth First Traversal/Search: Depth first traversal of a graph is
roughly analogous to preorder traversal of an ordered tree. Suppose
that the traversal has just visited a vertex v, and let w1,w2…….wk be
the vertices adjacent to v. Then we shall visit w1 and keep w2……wk
waiting. After visiting w1 we traverse all the vertices to which it is
adjacent before returning to traverse w2…..…wk.
1.
2.
3.
4.
5.
6.
7.
8.
9.
Algorithm
Initialize visited array to 0
v is the starting vertex
visited [v] = 1
display v
Search for w which is an unvisited vertex adjacent to v
if w is found
Visited [w] =1
Display w
Push w into stack
Go to 5
v=pop
Continue from 5 till stack becomes empty
Stop.
2. Breadth First Traversal/Search: Breadth first traversal of a graph is
roughly analogous to level_by_level traversal of an ordered tree. If the
traversal has just visited a vertex v, then it next visits all the vertices
adjacent to v, putting the vertices adjacent to these in a waiting list to
be traversed after all the vertices adjacent to v have been visited.
48
1.
2.
3.
4.
5.
6.
7.
8.
Algorithm
Initialize visited array to 0
v is the starting vertex
Queue is initialized
visited [r] =1
add v to queue
Remove v from queue and display to v
for all vertices w adjacent to v
if visited [w]=1
add w to queue
visited [w] =1
Continue from 6 till queue becomes empty
7.3 Applications of Graph
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.
1.
2.
3.
4.
5.
6.
7.
8.
9.
Algorithm
Accept AOV network in adjacency list form
S is an empty stack
Search for vertex v whose in_degree is 0
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
if found
make in_degree of v = _1
push v into stack
pop v from the stack and display
Reduce the in_degree of all vertices adjacent to v by 1
Repeat from step 3 till all vertices have been visited
Stop.
Shortest Path Algorithm
Graphs are often used to represent the road network of a state or country
with the vertices representing cities and the edges representing the
connecting roads. Each edge may be assigned a weight which may be the
49
distance between the two vertices or the time taken to go from one vertex
to another. An algorithm devised by Dijkstra is a ‘single source all
destinations’ algorithm which gives the shortest path from a given vertex
to all other vertices in the network.
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]I 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]
I
I
7. dist array contains the shortest paths from V to all other destinations
8. Stop
Practical Assignments
SET A
1. Write a program to read a graph as adjacency matrix. Calculate
indegree,outdegree and total degree of each vertex. Also write
functions to implement BFS and DFS. (Use recursive DFS function.)
2. Write a program to read a graph as adjacency matrix and convert it
into adjacency list. Write BFS and non_recursive DFS functions.
50
SET B
1. Write a program to represent following graph as an adjacency multi_
list form.
B
D
A
C
2. Write a program to represent following graph as an Orthogonal list.
B
D
A
C
3. Implement a graph using an array of adjacency lists. Under this
representation, a graph of n nodes consists of n header nodes, each
containing an integer from 0 to n_1 and a pointer. The pointer is to a list of
list nodes each of which contains the node number of a node adjacent to
the node represented by the header node. Implement Dijkstra’s algorithm
using this graph representation.
SET C
1. Write a program to implement Prim’s algorithm using an adjacency
matrix.
2. Write a program to implement Kruskal’s algorithm using an adjacency matrix
I adjacency list.
3. There may be more than one way to organize set of subtasks in a
minimum number of time periods. For example, the subtask in
following figure may be completed in six time periods in one of three
different methods:
51
Period
1
2
3
4
5
6
Method 1
A, F
B, H
I
C
D
E
A
Method 2
F
A, H
B, I
C
D
E
D
Method 3
A, F
H
B, J
C
D
E
F
G
B
E
C
Write a program to generate all possible methods of organizing the
subtasks in the minimum number of time periods.
Assignment Evaluation
0: Not Done [ ]
1:Incomplete [ ]
2.Late Complete [ ]
3:Needs Improvement [ ]
4:Complete [ ]
5:Well Done [ ]
Signature of the Instructor
Date of Completion
!
!
End of Session
5i