Sei sulla pagina 1di 51

Data Structures Using C

(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

About the work book……………………………………………………………3

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

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) Students should carry this book during practical sessions of computer


science.
2) Students should maintain separate journal for the source code, SQL
queries/commands along with outputs.
3) Student should read the topics mentioned in Reading section of this
book before coming for practical.
4) 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 Difficulty Level Rule


Self Activity NA Student should solve
these exercises for
practice only.
SET A Easy All exercises are
compulsory.
SET B Medium At least one exercise is
mandatory.
SET C Difficult Not Compulsory.

5) Students will be assessed for each exercise on a scale of 5

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

1) Explain the assignment and related concepts in around ten minutes


using white board if required or by demonstrating the software.
2) Choose appropriate problems to be solved by student.
3) After a student completes a specific set, the instructor has to verify the
outputs and sign in the provided space after the activity.
4) Ensure that the students use good programming practices.
5) You should evaluate each assignment carried out by a student on a
scale of 5 as specified above ticking appropriate box.
6) The value should also be entered on assignment completion page of
respected lab course.

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

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) Comments


1 {
2 S= 0.0;
3 Stepcnt = stepcnt +1; Stepcnt is initially zero.
4 For i = 1 to n do
5 {
6 Stepcnt=stepcnt+1; For the execution of for
7 S = S + a[i]; statement increment it once.
8 Stepcnt = stepcnt +1; Increment for the assignment
9 } statement
10 Stepcnt = stepcnt +1;
11 Stepcnt = stepcnt +1; For the last invocation of for
12 Return S; For the return
13 }

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.

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;
}

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.

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]

[33 66] [22 40] [55 88] [11 60]

Pass-2: Merge each pair of pairs to obtain the list of sorted quadruples

[33 66] [22 40] [55 88] [11 60]

[22 33 40 60] [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 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

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

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

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 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

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 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

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

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

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.

Head
Info link

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.

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.

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;
15
/*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;
}

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;
}

/*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.*/


}

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;
}
}

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;
}
}

18
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);
}

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;
}

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;
}

20
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;
21
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
o traversing is possible only in forward direction.
o 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.

22
Prev 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.*/
}

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;

/* Create new node.*/

if (*head == NULL) /* List is empty. New node will be appended as the


first node in the list.*/
{
}

/*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.*/

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.*/
{

/*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.*/

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.

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.

26
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

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

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.

28
Self Activity

Let’s implement Stack using Array (Static Representation)

Step1. 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.*/
}

29
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

push(&top, 5);

top 5 10 20 30

push(&top, 2);

top 2 5 10 20 30
4. Implement pop() function.

int pop(Stack **top)


{
30
/* Write a code to delete first node from the list.*/
/*Return data from deleted node.*/
}

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.

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.

31
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

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

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;

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)

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 40 50 60 70 80 90
0 1 2 3 4 5 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;
}

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.

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 ;
}

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.

void shiftQ( Q *P)


{ int topos =0, frompos;
for( frompos = P->rear; 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;

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

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.

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

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)

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;

NODE *front, *rear; //global variable


void initqueue() { }
void addq(int n) { }
int delq() { }
int isempty() { }
void main()
{
//menu driven program
}

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

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

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.

40
Structure of a node of a BST:
typedef struct BST
{ int data;
struct BST * left, * right;
}BSTnode;

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=0;i<totnodes;i++)
{ scanf(“%d”,&val);
root = insert(root, val);
}
return ( root);
}

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);
}
if(x > T->data)
{ T-> right = insert(T->right, x);
return (T);
}
T->left = insert(T->left, x);
return (T);
}

3. Delete: Deleting one node of the BST. There are 3 cases:


a) deleting a leaf node
b) deleting a node with one child
c) 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.

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.

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[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:

void create(int heap[])


{
int i,n;
n = heap[0];
for ( i=n/2; i>=1; i--)
down_adjust(heap,i);
}

Function to readjust the heap

void down_adjust(int heap[], int i)


{
int j, temp, n,flag = 1;
n= heap[0];
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 = 0;
else
{
temp = heap[i];
heap[i] = heap[j];

43
heap[j] = temp;
i = j;
}/* end if */
}/* end while */
}/* 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);
}
}

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

44
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

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

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] = 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

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
46
Example:
For above graph G adjacency list:

V1 V2 NULL

V3 V4 NULL
V2

V3 NULL

V1 V2 V3 NULL
V4

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.

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.

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.
47
Algorithm
1. Initialize visited array to 0
2. v is the starting vertex
3. Queue is initialized
4. visited [r] =1
5. add v to queue
6. Remove v from queue and display to v
7. for all vertices w adjacent to v
if visited [w]=1
add w to queue
visited [w] =1
8. 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.

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.

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
48
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]} 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

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.

49
SET B

1. Write a program to represent following graph as an adjacency multi-


list form.

D
A

2. Write a program to represent following graph as an Orthogonal list.


B

D
A

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


/ 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:

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

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

51

Potrebbero piacerti anche