Lab-Manual Batch 2018
Lab-Manual Batch 2018
Lab-Manual Batch 2018
Islamabad, Pakistan
Lab Manual
Name: _____________________________________________
EXPERIMENT NO.1:
OBJECTIVE:
Remarks: _____________
Instructor’s Signature:
______________________
1. C Programming Language
The C programming language is a general purpose, high level language (generally denoted
as structured language). C programming language was at first developed by Dennis M.
Ritchie at AT&T Bell Labs. C is one of the most commonly used programming languages. It
is simple and efficient therefore it becomes best among all. Many software’s &
applications as well as the compilers for other programming languages are written in C also
operating systems like UNIX, DOS, and Windows 95 were written in C.
C has now become a widely used professional language for various reasons −
Easy to learn
Structured language
It produces efficient programs
It can handle low-level activities
It can be compiled on a variety of computer platforms
5. Now write the Project name and set the path of Project folder and proceed
6. Now choose the GCC C compiler from dropdown menu and click finish
9. After Successful Build and Run the output “Hello World” will be displayed on the screen
3. Variables
During programming we need to store data. This data is stored in variables. Variables are
locations in memory for storing data. The memory is divided into blocks and there is a
numerical address for each location of a memory block. It is difficult for us to handle these
numerical addresses in our programs. So we give a name to these locations and these
names are variables. We call them variables because they can contain different values at
different times. In C every variable has the following attributes.
Name
Type
Size
Value
4. Data Types
A variable must have a data type associated with it, for example it can have data types like
integers, decimal numbers and characters. The variable of type integer stores the integer
values and a character type variable store character value. The primary difference in these
data types is their size in memory.
5. Arithmetic operators
An operator is the symbol that tells the compiler to perform the specific mathematical or
logic functions. C language is rich in built-in operators and provides the following types of
operators.
Arithmetic operators
Relational operators
Logical operators
Bitwise operators
Assignment operators
6. Conditional Statements
Conditional statements allow user to make decision, based upon the result of a condition.
These statements are called decision making statements or conditional statements. C
support following conditional statements
IF statement
IF-ELSE statement
ELSE-IF statement
SWITCH
(1). IF statement:
IF statement is used to execute the some lines of code, if a test condition is true
otherwise if condition is false, execute nothing.
(4). SWITCH:
A switch statement allows a variable to be tested for equally against a list of values. Each
value is called a case, and the variable being switched on is checked for each switch case.
LAB TASK
National University of Technology
Islamabad, Pakistan
EXPERIMENT NO.2:
OBJECTIVE:
CMS: ________________
Obtained Marks:
Remarks:
Instructor’s Signature:
LOOPS:
There are situations, when a block of code needs to be executed several number of times. In
general, statements are executed sequentially. The first statement is executed first,
followed by second and so on. A loop statement allows us to execute a statement or group
of statements multiple times. Given below is the general form of a loop statement in most
of the programming languages.
FOR Loop
WHILE Loop
DO-WHILE Loop
1. FOR Loop:
Whenever we need to execute certain action multiple times, we need to wrap statements
inside the loop.
Initial Expression
In the above program we have printed the string “Hello World!!!!!” 5 times.
2. WHILE Loop:
while (condition)
{
Statements;
}
Example Code:
/////////////////////////////////////////////////////////////////////
#include<stdio.h>
int main()
{
int a = 10;
/////////////////////////////////////////////////////////////////////
You can also make an infinite loop using while(1) statement. The syntax of infinite
loop is
while(1)
{
Statements;
}
3. DO-WHILE Loop:
Unlike for and while loops, which test the loop condition at the top of the loop, the do-
while loop in C programming checks its condition at the bottom of the loop. A do-while loop
is similar to while loop, except the fact that it is guaranteed to execute at least one time.
do {
statements;
} while(condition);
Example code
/////////////////////////////////////////////////////////////////////
#include <stdio.h>
int main ()
{
int a = 20;
do {
printf(“Value of a = %d \n”,a);
a = a + 1;
return 0;
/////////////////////////////////////////////////////////////////////
Functions:
A function is a group of statements that together perform a task. Every C program has at
least one function, which is main (). You can divide up your code in to separate functions.
How you divide up your code among different functions is up to you, but logically the
division is such that each function performs a specific task. A function declaration tells the
compiler about a function’s name, return type and parameters
Example Code
/////////////////////////////////////////////////////////////////////
#include <stdio.h>
int main () {
int a = 10;
int b = 20;
int c;
c = max(a,b);
printf(“Max Value = %d”,c);
return 0;
Int result;
result = num1;
else
result = num2;
return result;
/////////////////////////////////////////////////////////////////////
ARRAYS:
Array is a container which can hold fix number of items and these items should be of same
type. Most of the data structure makes use of array to implement their algorithms.
Following are important terms to understand the concepts of array.
An array can be declared in various ways. Let take an example of array declaration in C.
As per above shown illustration, following are the important points to be considered.
Operations:
Algorithm
1. Start
2. Set J=N
3. Set N=N+1
4. Repeat Steps 5 and 6 while J >= K
5. Set Array[J+1] = Array[J]
6. Set J=J-1
7. Set Array[K]= Item
8. Stop
Example Code
/////////////////////////////////////////////////////////////////////
#include <stdio.h>
int main () {
Let an Array is a linear unordered array of N elements and K is a positive integer such that
K <= N. Algorithm to remove an item at Kth index of an Array is shown below.
Algorithm
1. Start
2. Set J=K
3. Repeat Steps 4 and 5 while J < N
4. Set Array[J-1] = Array[J]
5. Set J=J+1
6. Set N=N-1
7. Stop
Example Code
/////////////////////////////////////////////////////////////////////
#include <stdio.h>
int main () {
Let an Array is a linear unordered array of N elements and K is a positive integer such that
K <= N. Algorithm to find an item in an Array is shown below.
Algorithm
1. Start
2. Set J=0
3. Repeat Steps 4 and 5 while J < N
4. If Array[J] = Item then goto step 6
5. Set J=J+1
6. Print J, Item
7. Stop
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
Let an Array is a linear unordered array of N elements and K is a positive integer such that
K <= N. Write down the algorithm to update an element in an array.
Algorithm
1.
2.
3.
4.
5.
Lab Task-2 (Write down the C code for update operation in an array)
/////////////////////////////////////////////////////////////////////
Types of Arrays
Array a kind of data structure that can store a fixed size sequential collection of elements of
the same type. An array is used store a collection of data, but it is often more useful to think
of an array as a collection of variables of the same data type. For example: if the user wants
to store marks of 100 students. This can be done by creating 100 variables individually but,
this process is rather tedious. This type of problem can be handled in C programming using
arrays. All arrays consist of contiguous memory locations. The lowest address corresponds
to the first element and the highest address to the last element. Arrays are of two types:
1. One-Dimensional Arrays.
2. Multi-Dimensional Arrays.
1-D Arrays:
To declare an array in C, programmer specifies the type of the elements and the number of
elements required by an array as follows
The data type of an array can be valid C data type like int, float, single, double etc. The size
of an array must be integer constant greater than zero. The Example code below takes 5
integers as an input from user to store in an array and then print the array contents on
screen.
Example Code
/////////////////////////////////////////////////////////////////////
#include <stdio.h>
int main () {
return 0;
/////////////////////////////////////////////////////////////////////
Multi-Dimensional Arrays:
C programming language allows programmers to create arrays of arrays known as multi
dimensional arrays. The simplest form of multi dimensional array is the two-dimensional
array. A two dimensional array is, in essence, a list of one dimensional arrays. The two
dimensional array can be declared as follows
Where type can be any valid C data type and ArrayName will be a valid C identifier. A two
dimensional array can be considered as a table which will have x number of rows and y
number of columns. A two dimensional array, which contains three rows and four columns
can be shown as follows.
Thus, every element in the array a is identified by an element name of the form a[ i ][ j ],
where 'a' is the name of the array, and 'i' and 'j' are the subscripts that uniquely identify
each element in 'a'.
Example Code
/////////////////////////////////////////////////////////////////////
#include <stdio.h>
int main () {
/////////////////////////////////////////////////////////////////////
Note: In 1-D Array single for loop will be used for storing or reading array elements and in
2-D Array two for loops will be used in nested form.
LAB TASK
National University of Technology
Islamabad, Pakistan
EXPERIMENT NO.3:
OBJECTIVE:
CMS: ________________
Obtained Marks:
Remarks:
The program below allows user to read the string from user as an input and display on the
screen. String variable Name can only take a word. It is because when white space is
encountered, the scanf() function terminates. Here program will ignore second word
because, scanf() function takes only string before the white space.
Example Code
/////////////////////////////////////////////////////////////////////
#include <stdio.h>
int main () {
char Name[30];
printf(“Enter the string : ”);
scanf(“%s”,&Name);
printf(“Your entered string is %s”,Name);
return 0;
}
/////////////////////////////////////////////////////////////////////
Output:
Enter your string: FEAS RIPHAH
Your entered string is FEAS
/////////////////////////////////////////////////////////////////////
C language provides two basic functions gets() and puts() to read and write the strings. Now
re-write the above code by using gets() and puts() functions instead of scanf() and printf()
functions. Now the output of the program will shows both the words in the string. By using
gets() function user can enter white spaces in the string while entering the string as an input
to the program.
You can perform different type of string operations manually like: finding the length of the
string, concatenating two strings, copy one string to other string etc. For programmers ease,
many built in functions are available under header file <string.h>. Few commonly used string
handling functions are
POINTERS:
As we know, every variable is a memory location and every memory location has its address
defined which can be accessed using ampersand (&) sign, which denotes an address in
memory. A pointer is a variable whose value is the address of another variable, i.e direct
address of the memory location. Like any variable and constant, you must declare a pointer
before using it to store any variable address. The general type of pointer variable
declaration is
type *variable_name;
Here, type is the pointer’s base type; it must be a valid C data type and variable_name is the
name of the pointer variable. The asterisk (*) used to declare a pointer is the same asterisk
used for multiplication. However, in this statement the asterisk is being used to designate a
variable pointer as a pointer.
Example Code
/////////////////////////////////////////////////////////////////////
#include <stdio.h>
int main () {
int a = 10;
int *b; // pointer variable declaration
}
/////////////////////////////////////////////////////////////////////
Null Pointer:
It is always a good practice to assign a NULL value to a pointer variable in case you do not
have an exact address to be assigned. This is done at the time of variable declaration. A
pointer that is assigned NULL is called a null pointer. The NULL pointer is a constant with a
value of zero defined in several standard libraries.
Pointer to Pointer:
A variable that is a pointer to a pointer must be declared by placing double asterisk sign (**)
with variable name.
Example Code
/////////////////////////////////////////////////////////////////////
#include <stdio.h>
int main () {
int a = 10;
int *b; // pointer variable declaration
int **c; // pointer to pointer variable declaration
b = &a;
c = &b;
}
/////////////////////////////////////////////////////////////////////
STRUCTURE:
Arrays allow defining type of variables that can hold several data items of the same kind.
Similarly structure is another user defined data type available in C that allows combining
data items of different kinds. Structures are used to represent a record. Suppose you want
to keep track of your books in a library. You might want to track the following attributes
about each book
Title
Author
Book ID
Book Price
To define a structure, you must use a struct statement. The struct statement defines a new
data type, with more than one member
Struct Book {
Char title[50];
Char author[50];
Int book_id;
float price;
};
To access any member of a structure, we use the member access operator (.).
Example Code
/////////////////////////////////////////////////////////////////////
#include <stdio.h>
struct Book
{
Char Title[50];
Char Author[50];
Int Book_Id;
float Price;
};
int main () {
EXPERIMENT NO.04:
OBJECTIVE:
CMS: ________________
Obtained Marks:
Remarks:
Instructor’s Signature:
______________________________
LINKED LIST:
A linked list is a sequence of data structures which are connected together via links. Linked
list is a sequence of links which contains items. Each link contains a connection to another
link. Linked list the second most used data structure after array. Linked list is a dynamic data
structure whose length can be increased or decreased at run time. Linked list basically
consists of memory blocks that are located at random memory locations. Now, one would
ask how are they connected or how then can be traversed, Well they connected through
pointers. Usually a block in a linked list is represented through a structure. How linked lists
are different from arrays, consider the following points:
An array is a static data structure. This means the length of an array cannot be
altered at run time. While, a linked list is a dynamic data structure.
In an array, all the elements are kept at consecutive memory locations while in a
linked list the elements (nodes) may be kept at any location but still connected to
each other.
Linked lists are preferred in those applications where volume of the data is not known. For
example, In an employee management system, one cannot use arrays as they are of fixed
length while any number of new employees can join.
TYPES:
There are three types of linked lists
Struct node
{
Int value;
Struct node *next;
};
The structure shown above contains two items in it. One is value which contains the data
and the second item is a pointer to a structure which contains the address of the next node
(memory block) of the linked list.
Basic Operations:
Following are the basic operations supported by a list.
Insertion:
Adding a new node in linked list is a more than one step activity. First create a new node
using the same structure and find the location where it has to be inserted.
Let we are inserting a node B(new node) between node A(left node) and node C(right node).
Then point B.next to C node.
Now next of the left node (A node) should point to the new node (B node).
This will put a new node (B node) in the middle of the two nodes. The now list should be
look like.
Using the same way a new node can be inserted at any place (beginning, middle and end) of
a linked list.
Deletion:
Deletion is also a more than one step process. First locate the target node to be removed by
searching.
The left (previous node) of the target node now should point to the next node of the target
node.
This will remove the link that was pointing to target node. Now we shall remove to what
target node is pointing. Put a NULL to a Target node next field like targetnode.next = NULL;
We need to use the deleted node we can keep that in memory otherwise we can simply
deallocate memory and wipe off the target node completely.
Example Code (Singly Linked List)
/////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h> printf(“\n Restored List :”);
display_list();
struct node printf(“\n”);
{ struct node *found_link = find(4);
int data;
int key; if(found_link!=Null)
struct node *next; {
}; printf(“Element Found”);
printf(“(%d,%d)”,found_link-
struct node *head = NULL; >key,found_link->data);
struct node *current = NULL; printf(“\n”);
}
int main() else
{ {
printf(“Element not found”);
insert_first(1,5); }
insert_first(2,10); printf(“\n”);
insert_first(3,15); sort();
insert_first(4,4); printf(“Linked List after sorting :”);
insert_first(5,20); display_list();
insert_first(6,50); reverse(&head);
printf(“Linked List after reversing :”);
printf(“Original Linked List is :”); display_list();
display_list(); }
OUTPUT
National University of Technology
Islamabad, Pakistan
EXPERIMENT NO.05:
OBJECTIVE:
CMS: ________________
Obtained Marks:
Remarks:
Instructor’s Signature:
______________________________
Double Linked List is a variation of linked list in which navigation is possible in both ways
either forward or backward easily as compared to single linked list. Following are the
important terms to understand the concept of double linked list
Node ---- Each node of a linked list can store a data called an element.
Next ---- Each node of a linked list contains a link to a next node called Next.
Prev ---- Each node of a linked list contains a link to a previous node called Prev.
Example Code
/////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
struct node
{
int data;
int key;
struct node *next;
struct node *prev;
};
struct node *head = NULL; {
struct node *last = NULL; struct node *link = (struct node*)
struct node *current = NULL; malloc(sizeof(struct node));
link->key = key;
bool isEmpty() link->data = data;
{
return head == NULL; if(isEmpty())
} {
last = link;
int length () }
{ else
int count = 0; {
struct node *current; head->prev = link;
for(current = head ; current != NULL ; }
current = current->next) link->next = head;
{ head = link;
count++; }
}
return count; void insertLast(int key, int data)
} {
struct node *link = (struct node*)
void displayForward() malloc(sizeof(struct node));
{ link->key = key;
struct node *ptr = head; link->data = data;
printf(“\n [ ”);
while(ptr != NULL) if(isEmpty())
{ {
printf(“(%d,%d)”,ptr->key,ptr->data); last = link;
ptr = ptr->next; }
} else
printf(“ ] ”); {
} last->next = link;
link->prev = last;
void displayBackward() }
{ last = link;
struct node *ptr = last; }
printf(“\n [ ”);
while(ptr != NULL) struct node* deleteFirst()
{ {
printf(“(%d,%d)”,ptr->key,ptr->data); struct node *temp = head;
ptr = ptr->prev;
printf(“ ”); if(head->next == NULL)
} {
printf(“ ] ”); last = NULL;
} }
else
void insertFirst(int key, int data) {
head->next->prev = NULL; else
} {
head = head->next; current->prev->next = current->next;
return temp; }
} if(current==last)
{
struct node* deleteLast() last=current->prev;
{ }
struct node *temp = last; else
{
if(head->next == NULL) current->next->prev = current->prev;
{ }
head = NULL; return current;
} }
else
{ bool insertAfter(int key, int newKey, int
last->prev->next = NULL; data)
} {
last = last->prev; struct node *current = head;
return temp; if(head==NULL)
} {
return false;
struct node* delete(int key) }
{
struct node *current = head; while(current->key != key)
struct node *previous= NULL; {
if(current->next == NULL)
if(head==NULL) {
{ return false;
return NULL; }
} else
while(current->key != key) {
{ current = current->next;
if(current->next == NULL) }
{ }
return NULL;
} struct node *new = (struct node*)
else malloc(sizeof(struct node));
{ new->key = key;
previous = current; new->data= data;
current = current->next;
} if(current == last)
} {
if(current==head) new->next = NULL;
{ last = new;
head=head->next; }
} else
{
new->next = current->next;
current->next->prev = new;
}
new->prev = current;
current->next = new;
return true;
}
int main()
{
insertFirst(1,10);
insertFirst(2,20);
insertFirst(3,30);
insertFirst(4,100);
insertFirst(5,40);
insertFirst(6,50);
printf(“\n”);
printf(“\n List (Last to First)”);
displayBackward();
OBJECTIVE:
CMS: ________________
Obtained Marks:
Remarks:
Basic Operations:
Following are the important operations supported by a circular linked list.
Insert
Delete
Display
Example Code (Circular Linked List using Singly Linked List)
/////////////////////////////////////////////////////////////////////
#include <stdio.h> {
#include <stdlib.h> head=link;
#include <string.h> head->next=head;
#include <stdbool.h> }
else
struct node { {
int data; link->next=head;
int key; head=link;
struct node *next; }
}; }
struct node * deleteFirst()
struct node *head = NULL; {
struct node *current = NULL; struct node *temp = head;
if(head->next==head)
bool isEmpty() {
{ head=NULL;
return head == NULL; return temp;
} }
head=head->next;
int length() return temp;
{ }
int Count = 0; void printList()
if(head==NULL) {
{ struct node *ptr = head;
return 0; printf(“\n [ ”);
} if(head != NULL)
current = head->next; {
while(ptr->next != NULL)
while(current != head) {
{ printf(“(%d,%d)”,ptr->key,ptr->data);
Count++; ptr=ptr->next;
current = current->next; }
} }
return Count; Printf(“ ] ”);
} }
void insertFirst(int key, int data) int main()
{ {
struct node *link = (struct node*) insertFirst(1,100);
malloc(sizeof(struct node)); insertFirst(2,200);
link->key=key; insertFirst(3,300);
link->data=data; insertFirst(4,400);
insertFirst(5,500);
if(isEmpty()) insertFirst(6,600);
printf(“Origninal List: ”);
printList();
while(!isEmpty())
{
struct node *temp=deleteFirst();
printf(“\n Deleted Value: ”);
printf(“(%d,%d)”,temp->key,temp->data);
}
Printf(“\n List After deleteing all items :”);
printList();
}
/////////////////////////////////////////////////////////////////////
Output:
/////////////////////////////////////////////////////////////////////
Lab Task: implement circular linked list with the help of double linked list (write down
the main alteration needed in above code)
National University of Technology
Islamabad, Pakistan
EXPERIMENT NO.07:
Implementation of Stack
OBJECTIVE:
CMS: ________________
Obtained Marks:
Remarks:
A stack can be implemented by means of Array, Structure, Pointer and Linked List. Stack can
either be a fixed size one or it may be of dynamic size. Stack operations may involve the
initializing the stack, using it and then de-initializing but the primary operations of stack are
To use the stack efficiently we need to check the status of stack as well. For this purpose
following functionality is added to stacks.
Peek ------ Get the top data element of the stack, without removing it.
Empty --- Check if stack is EMPTY
Full ------- Check if stack is FULL
The process of putting a new data element onto stack is known as Push operation. Push
operation involves the following steps
int main() {
push(10);
push(20);
push(30);
push(40);
push(50);
printf(“Element at the Top of the Stack : %d \n”, peek());
printf(“Elements : \n”);
while(!is_empty())
{
int data = pop();
printf(“%d\n”, data);
}
printf(“Stack Full : %s \ n”,is_full()?”True”:”False”);
printf(“Stack Empty : %s \ n”,is_empty()?”True”:”False”);
return 0;
}
int is_empty() {
if(Top == -1)
return 1;
else
return 0;
}
int is_full() {
if(Top == Max )
return 1;
else
return 0;
}
int peek() {
return stack[Top];
}
int pop() {
int data;
if(!is_empty()) {
data = Stack[Top];
Top = Top – 1;
return data;
}
else {
printf(“Stack is Empty !!!!!\n”);
}
}
if(!is_full()) {
Top = Top + 1;
Stack[Top] = data;
}
else
{
printf(“Stack is Full….. \n”);
}
}
/////////////////////////////////////////////////////////////////////
Task : Run the above code and take the snapshot of output window and attach it.
struct node
{
Int info;
struct node *ptr
}*top,*top1,*temp;
int top_element();
void push(int data);
void pop();
void empty();
void display();
void destroy();
void stack_count();
void create();
int count = 0;
void main()
{
int no, choice, e;
create();
while(1)
{
printf(“\n Enter the choice : ”);
scanf(“%d”, &choice);
switch(choice)
{
case 1:
printf(“Enter the data to be pushed : ”); Printf(“\n No of elements in stack :
scanf(“%d”, &no); %d”,count);
push(no); }
break; void push(int data)
case 2 : {
pop(); if(top==NULL)
break; {
case 3 : top = (struct node *) malloc(sizeof(struct
if(top==NULL) node));
printf(“No Elements in Stack”); top->ptr = NULL;
else top->info = data;
{ }
e = top_element(); else
printf(“\n Top Element = %d”,e); {
} temp = (struct node *)
break; malloc(sizeof(struct node));
case 4 : temp->ptr = top;
empty(); temp->info = data;
break; }
case 5 : count++;
exit(0); }
case 6 : void display()
display(); {
break; top1 = top;
case 7 : if(top1==NULL)
stack_count(); {
break; printf(“Stack is Empty”);
case 8 : return ;
destroy(); }
break; while(top1 != NULL)
default : {
printf(“Wrong Choice, Please Re-Enter printf(“%d“,top->info);
your choice”); top = top->ptr;
break; }
} }
} void pop()
} {
void create() top1=top;
{ if(top1==NULL)
top = NULL; {
} printf(“\n Error : Trying to poping an
void stack_count() empty stack”);
{ return;
}
else
top1 = top1->ptr;
printf(“\n Popped Value : %d”, top->info);
free(top);
top = top1;
count--;
}
int top_element()
{
return(top->info);
}
void empty()
{
if(top==NULL)
printf(“\n Stack is Empty”);
else
printf(“\n Stack is not Empty with %d elements”, count);
}
void destroy()
{
top1=top;
while(top1 != NULL)
{
top1=top->ptr;
free(top);
top=top1;
top1 = top1->ptr;
}
free(top1);
top=NULL;
printf(“\n All Stack elements destroyed”);
count=0;
}
/////////////////////////////////////////////////////////////////////
Task : Run the above code and take the snapshot of output window and attach it.
National University of Technology
Islamabad, Pakistan
EXPERIMENT NO.08:
Implementation of Queue
OBJECTIVE:
CMS: ________________
Obtained Marks:
Remarks:
Queue is an abstract data structure, somewhat similar to stack. In contrast to stack, queue is
opened at both ends. One end is always used to insert data and the other is used to remove
data. Queue follows FIFO (First In First Out) methodology. In Fifo the data items stored first
will be accessed first. A real world example of queue can be a single lane one way road,
where the vehicle enters first, exits first.
Same as stack, queue can also be implemented using array, linked list, pointer, and
structures. Queue operations may involve initializing or defining the queue, utilizing it and
then erasing it from memory. Here we shall try to understand basic operations associated
with queues.
Few more functions are required to make above mentioned queue operation efficient.
These are
Peek() ---------- Get the element at front of the queue without removing it
Isfull() ---------- Checks if queue is full
Isempty() ---------- Check if queue is empty
In queue, we always dequeue data, pointed by front pointer and while enqueing data in
queue we take help of rear pointer.
1. Enqueue Operation:
As queue maintains two data pointers, front and rear, its operations are
comparatively more difficult to implement than stack. The following steps should be
taken to enqueue data into a queue
Accessing data from queue is a process of two tasks, access the data where front is
pointing and remove the data after access. The steps are
int peek()
{ insert(3);
return Queue[front]; insert(4);
} insert(5);
struct node
{
int info;
struct node *ptr;
}*front,*rear,*temp,*front1;
int frontelement();
void enq(int data);
void deq();
void empty();
void display();
void create();
void queuesize();
int count = 0;
void create()
{
front = rear = NULL;
}
void queuesize()
{
printf("\n Queue size : %d", count);
}
void enq(int data)
{
if (rear == NULL)
{
rear = (struct node *)malloc(sizeof(struct rear->ptr = NULL;
node)); rear->info = data;
front = rear; else
} {
Else printf("\n Dequed value : %d", front-
{ >info);
temp=(struct node *)malloc(sizeof(struct free(front);
node)); front = NULL;
rear->ptr = temp; rear = NULL;
temp->info = data; }
temp->ptr = NULL; count--;
rear = temp; }
} int frontelement()
count++; {
} if ((front != NULL) && (rear != NULL))
void display() return(front->info);
{ else
front1 = front; return 0;
if ((front1 == NULL) && (rear == NULL)) }
{ void empty()
printf("Queue is empty"); {
return; if ((front == NULL) && (rear == NULL))
} printf("\n Queue empty");
while (front1 != rear) else
{ printf("Queue not empty");
printf("%d ", front1->info); }
front1 = front1->ptr; void main()
} {
if (front1 == rear) int no, ch, e;
printf("%d", front1->info); printf("\n 1 - Enque");
} printf("\n 2 - Deque");
void deq() printf("\n 3 - Front element");
{ printf("\n 4 - Empty");
front1 = front; printf("\n 5 - Exit");
if (front1 == NULL) printf("\n 6 - Display");
{ printf("\n 7 - Queue size");
printf("\n Error: Trying to display elements create();
from empty queue"); while (1)
return; {
} printf("\n Enter choice : ");
else scanf("%d", &ch);
if (front1->ptr != NULL) switch (ch)
{ {
front1 = front1->ptr; case 1:
printf("\nDequed value : %d",front->info); printf("Enter data : ");
free(front); scanf("%d", &no);
front = front1; enq(no);
} break;
case 2:
deq();
break;
case 3:
e = frontelement();
if (e != 0)
printf("Front element : %d", e);
else
printf("\n No front element in Queue as queue is empty");
break;
case 4:
empty();
break;
case 5:
exit(0);
case 6:
display();
break;
case 7:
queuesize();
break;
default:
printf("Wrong choice, Please enter correct choice ");
break;
}
}
}
////////////////////////////////////////////////////////////////////
Task: Take the snapshot of the output window and attach it.
LAB TASK:
Write down the algorithms for Enqueue and Dequeue in the boxes given below
National University of Technology
Islamabad, Pakistan
EXPERIMENT NO.9:
OBJECTIVE:
CMS: ________________
Obtained Marks:
Remarks:
Root Node at the top of the tree is root node. There is only one root per
tree and one path from root node to any node.
Path Path refers to sequence of nodes along the edges of the tree.
Parent Any node except root node has one edge upward to a node called
parent node.
Child Node below a given node connected by its edge downward is called
its child node.
Leaf Node which does not have any child node is called leaf node.
Subtree Sub tree represents the descendants of a node.
Visiting Visiting refers to checking value of the node.
Traversing Traversing means passing through nodes in a specific order.
Tree Traversal:
Tree traversal is the process to visit all the nodes of a tree and may print their values too if
needed. Because all the nodes are connected via edges we always start from the root node,
we cannot random access a node in tree. There are three ways to traverse the tree
In-order Traversal
Pre-order Traversal
Post Order Traversal
Inorder Traversal:
In this method, the left sub tree is visited first, then root and then right sub tree. Consider
the figure given below. We start from A, and following inorder traversal, we move to its left
sub tree B. B is also traversed inorder and the process goes on until all the nodes are visited.
The output of inorder traversal of this tree will be D-B-E-A-F-C-G.
Preorder Traversal:
In this traversal method, the root is visited first, and then left sub tree and finally right sub
tree. Consider the figure shown below. We start from A and following preorder traversal, we
first visited A itself and then move to its left sub tree B. B is also traversed pre ordered and
the process goes on until all the nodes are visited. The output of preorder traversal of this
tree will be A-B-D-E-C-F-G.
Postorder Traversal:
In this traversal method, the root is visited last, hence the name. First we traverse left sub
tree, then right sub tree and finally root. Consider the figure shown below. We start from A
and following the postorder traversal, we first visit left sub tree B. B is also traversed post
ordered and the process goes on until all the nodes are visited. The output of postorder
traversal of this tree will be D-E-B-F-G-C-A.
Binary Search Tree:
A binary search tree is a tree in which all nodes follows the below mentioned properties
The left sub tree of a node has value less than or equal to its parent node’s value
The right sub tree of a node has value greater than or equal to its parent node’s
value.
Thus, a binary search tree divides all its sub trees in to two segments (left sub tree and right
sub tree). An example of BST is shown below.
Operations:
Search
Insert
Preorder Traversal
Inorder Traversal
Postorder Traversal
Re call the linked list, we have same nodes (represented by structures) in tree as well but
there is one more next pointer in tree node. Tree nodes have two next pointers named
leftChild and rightChild.
Example Code
////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *leftChild;
struct node *rightChild;
};
while(1) {
parent = current;
//go to left of the tree
if(data < parent->data) {
current = current->leftChild;
return 0;
}
////////////////////////////////////////////////////////////////////
Output
////////////////////////////////////////////////////////////////
National University of Technology
Islamabad, Pakistan
EXPERIMENT NO.10:
OBJECTIVE:
CMS: ________________
Obtained Marks:
Remarks:
Linear search is a very simple search algorithm. In this type of search, a sequential
search is made over all items one by one. Every item is checked and if match founds
then that particular item is returned otherwise search continues till the end of the data
collection.
Algorithm
1. Start
2. Set i = 1;
3. If i > n then go to step 8
4. If A[i] = value then go to step 7
5. Set i = i + 1;
6. Go to step 3
7. Print Element value found at index i and go to step 9
8. Print Element not found
9. Stop
A code skeleton is written below and you have to write the linear search function by
yourself and then merge it in the program given below. After that execute the code and
write down the output of the program.
Example Code
/////////////////////////////////////////////////////////////////////
#include <stdio.h>
#define Max 10
int Array[Max] = {4,6,3,2,1,9,7,0,10,11};
int main () {
int location;
printf(“Input Array : ”);
display();
location = Search(10);
if(location != -1)
printf(“\n Element Found at location : %d”,(location+1));
else
printf(“Element Not Found”);
return 0;
}
////////////////////// Array Display Function ///////////////////////
Void display ()
{
int i;
printf(“ [ ”);
}
/////////////////////////////////////////////////////////////////////
Output
/////////////////////////////////////////////////////////////////////
2. Binary Search:
Binary search is a fast search algorithm with run time complexity of O (log n). Binary
search works on the principle of divide and conquer. For this algorithm to work properly
the data should be in sorted form. Binary search algorithm searches a particular item by
comparing the middle most item of data collection. If match occurs then index of item is
returned. If middle item is greater than item then item is searched in sub array to the
right of the middle item otherwise item will be searched in sub array to the left of the
middle item. This process continues on sub array as well until the size of sub array
reduces to zero.
Let we have a sorted array and we need to search the location of value 31.
Mid = (high - low)/2 // Mid = 0 + (9 - 0)/2 = 4.5 and after rounding Mid = 4
Now we compare the value at location 4 (Mid), with the value being searched. i.e 31. We
find that value at location 4 is 27, which is not a match, because value is greater than 27
and we have sorted array so we also know that target value must be in upper portion of
array.
Now we change our low value to mid+1 and find new mid value again. Our new mid is 7
now. Now we compare the value stored at location 7 with our target value 31.
The value at location 7 is not a match, rather it is less that what we are looking for. So
the value must be in the lower part from this location.
We compare the value at location 5 with the target value and finally match is found.
Lab-Task: Write down the algorithm for binary search in the given box below.
Algorithm
Example Code
/////////////////////////////////////////////////////////////////////
#include <stdio.h>
#define Max 10
int Array[Max] = {4,6,3,2,1,9,7,0,10,11};
int main () {
int location;
printf(“Input Array : ”);
display();
location = Search(10);
if(location != -1)
printf(“\n Element Found at location : %d”,(location+1));
else
printf(“Element Not Found”);
return 0;
}
////////////////////// Array Display Function ///////////////////////
Void display ()
{
int i;
printf(“ [ ”);
if(Array[mid]==data)
{
index = mid;
break;
} else
{
If(Array[mid] < data) {
lower = mid + 1;
}
else
{
upper = mid - 1;
}
}
}
Printf(“Total Comparisons Made : %d”,comparison);
return index;
}
/////////////////////////////////////////////////////////////////////
National University of Technology
Islamabad, Pakistan
EXPERIMENT NO.11:
OBJECTIVE:
CMS: ________________
Obtained Marks:
Remarks:
Instructor’s Signature:
______________________________
Sorting refers to arranging data in a particular format. Sorting algorithm specifies the way to
arrange data in a particular order. Importance of sorting lies in the fact that data searching
can be optimized to a very high level if data is stored in a sorted manner. Sorting is also used
to represent the data in a more readable format. Some of the basic examples of sorting are
Telephone Directory
Dictionary
If a sorting algorithm, after sorting the contents, changes the sequence of similar content in
which they appear, it is called unstable sorting.
Algorithm starts with very first two elements, comparing them to check which one is
greater, in this case value 33 is greater than 14, so it is already in sorted positions. Next two
values 33 and 27 will be compared, we find that 33 is greater than 27 so these two values
must be swapped and the new array will be
Then we will compare next two values 33 and 35 and we find that both are already at sorted
positions. Then we move to next two values 35 and 10. As 10 is smaller than 35 and these
two values will be swapped. We find that we reach at the end of the array. After first
iteration the array should look like
Notice that after each iteration, at least one value moves at the end and when there is no
swap required, bubble sort learns that array is completely sorted.
Algorithm
1. Start
2. For all elements of an Array
3. If Array[i] > Array[i+1]
4. Swap (Array[i] , Array [i+1])
5. End if
6. End for
7. Stop
Example Code
/////////////////////////////////////////////////////////////////////
#include <stdio.h>
#define Max 10
int main () {
printf(“Input Array :”);
display();
printf(“\n”);
Bubble_Sort();
Printf(“Output Array :”);
display();
return 0;
}
////////////////////// Array Display Function ///////////////////////
Void display ()
{
int i;
printf(“ [ ”);
for (i=0 ; i<Max-1 ; i++)
{
printf(“%d”,Array[i]);
}
Printf(“ ] ”);
}
////////////////////// Bubble Sort Function ///////////////////////
Void Bubble_Sort ()
{
int i,j;
int temp;
Insertion Sort:
In an insertion sort, a sub list is maintained which is always sorted. For example, the lower
part of an array is maintained to be sorted. A element which is to be inserted in the sorted
sub list, has to find the its appropriate place and insert it there. The array is searched
sequentially and unsorted items are moved and inserted in to sorted sub list (in the same
array). The algorithm is not suitable for large data sets as its worst case complexity are of
O(n2) where n are number of elements. We take an unsorted array for example
Insertion sort compares the first two elements. It finds that both 14 and 33 are already in
ascending order. For now, 14 is in sorted sub list.
Insertion sort moves ahead and compares 33 with 27 and finds that 33 is not on correction
position. 33 will be swapped with 27 and also it checks with all the elements of sorted sub
list. Here we see that sorted sub list has only one element 14 and 27 is greater than 14.
Hence sorted sub list remains sorted after swapping.
By now we have 14 and 27 in the sorted sub list. Next it compares 33 with 10 and it is found
that these values are not in sorted order so swap them.
After swapping 10 is added in the sorted sub list but in sub list 27 and 10 is not in the proper
order so 27 and 10 will swapped.
Again we find that 14 and 10 in unsorted order and we swap them. By end of the third
iteration we have a sorted sub list of 3 items.
This process goes until all the unsorted values are covered in sorted sub list.
Algorithm
1. Start
2. If it is the first element, it is already sorted. Return 1;
3. Pick next element
4. Compare with all elements in the sorted sub list
5. Find appropriate position
6. Insert the value
7. Repeat until list is sorted
8. Stop
Example Code
/////////////////////////////////////////////////////////////////////
#include <stdio.h>
#define Max 10
int Array[Max] = {1,8,4,6,0,3,5,2,7,9};
int main () {
Selection Sort:
In selection sort, whole list is divided in to two parts, sorted part at left end and unsorted
part at right end. Initially sorted part is empty and unsorted part is entire list. Selection sort
algorithm first find the minimum value in the whole array and swapped with the left most
element (first element of the array). That element becomes part of sorted array and this
process continues moving unsorted array boundary by one element to the right. This
algorithm is not suitable for the large data sets as its worst case complexity is O(n2) where n
is the number of elements. We take an unsorted array for example
For the first position in sorted list, the whole array is scanned sequentially. We search the
whole array and find that 10 is the minimum value and it will be swapped with the value
which is on the first location of an array (value 14). After first iteration the array will be
For the second position where 33 is residing, we start scanning rest of the list in linear
manner. We find that 14 is second lowest value in an array and it should be at the second
place so we swap these values. After two iterations the new array will be
The same process will continue on the rest of the element in an array until the whole array
is sorted.
Algorithm
1. Start
2. Set Min to location 0
3. Search the Min element in the Array
4. Swap the value at location Min
5. Increment Min to point to next element
6. Until Array is sorted
7. Stop
Example Code
/////////////////////////////////////////////////////////////////////
#include <stdio.h>
#define Max 10
int Array[Max] = {1,8,4,6,0,3,5,2,7,9};
int main () {
Lab Task:
2. Bubble sort and insertion sort algorithms falls in which category of sorting? (in-
place,not-in-place,stable,unstable)
3. What is the purpose of sorting? (Real Life Example)
National University of Technology
Islamabad, Pakistan
OBJECTIVE:
CMS: ________________
Obtained Marks:
Remarks:
EXPERIMENT NO.13:
OBJECTIVE:
CMS: ________________
Obtained Marks:
Remarks:
Merge sort is a sorting technique based on divide and conquer. Its worst case complexity is
O(n log n). Merge sort first divides the array in to equal halves and then combines them in a
sorted manner. To understand merge sort, we take an unsorted array.
Merge sort divides the whole array in to equal halves unless the atomic values are achieved.
As we have an array of size 8, so merge sort first divides it in two arrays each of size 4.
This does not change the sequence of appearance of items in the original. Now we divide
these two arrays in to two halves.
We further divide these arrays and we achieve atomic value which can no more be divided.
Now, we combine them in exactly same manner they were broken down. We first compare
the element for each list and then combine them in to another list in sorted manner. We see
that 14 and 19 are in sorted positions. We compare 27 and 10 and in the target list of two
values we put 10 first, followed by 27. We change the order 19 and 35. 42 and 44 are placed
in order.
In next iteration of combining phase, we compare lists of two data values, and merge them
in to a list of found data values placing all in sorted order.
Example Code
/////////////////////////////////////////////////////////////////////
#include <stdio.h>
#define Max 10
int Array[Max] = {14,19,10,27,26,31,33,35,44,42};
int temp[Max];
int main () {
printf(“Input Array : ”);
display();
Sort(0,Max);
Printf(“Output Array : ”);
display();
return 0;
}
////////////////////// Array Display Function ///////////////////////
Void display ()
{
int i;
printf(“ [ ”);
Shell Sort:
Shell sort is highly efficient sorting algorithm and is based on insertion sort algorithm. This
algorithm avoids large shifts as in case of insertion sort if smaller value is very far right and
have to move to far left. This algorithm uses insertion sort on widely spread elements first to
sort them and then sorts the less widely spaced elements. The worst case complexity of
algorithm is O(n) and n is the number of elements. This spacing is termed as interval. This
interval is based on Knuth’s formula.
To understand the shell sort algorithm, we consider an unsorted array. For ease of
understand we take interval of 4 and we make the virtual sub list of all the values located at
the interval of 4 positions.
We compare the values in each sub list and swap them if needed in the original array. After
this step, the new array will be
Now at this stage we consider the interval value 2 and this will generate two sub lists.
We compare and swap the values if needed in the original array. After this the new array
will be
After that we will sort the rest of the array using interval value 1. The step by step depiction
is shown below.
Algorithm
1. Start
2. Initialize the value of H
3. Divide the array in to smaller sub arrays of equal interval H
4. Sort these sub arrays using insertion sort algorithm
5. Repeat until complete list is sorted
6. Stop
Example Code
/////////////////////////////////////////////////////////////////////
#include <stdio.h>
#define Max 7
int Array[Max] = {4,6,3,2,1,9,7};
int temp[Max];
int main () {
printf(“Input Array : ”);
display();
Shell();
Printf(“Output Array : ”);
display();
return 0;
}
////////////////////// Array Display Function ///////////////////////
Void display ()
{
int i;
printf(“ [ ”);
Printf(“Iterations %d #”,i);
display();
Quick Sort:
Quick sort is a highly efficient sorting algorithm and is based on partitioning of array of data
in to smaller arrays. A large array is partitioned in to two arrays one of which holds values
smaller than specified value say pivot based on which the partition is made and another
array holds values greater than pivot value. The quick sort partitions an array and them calls
itself recursively twice to sort the resulting two sub array. This algorithm is quite efficient for
large data sets as its worst case complexity are of O (n log n) where n is the number of
elements. The Example of Quick sort is shown below and first element (54) is chosen as a
pivot.
Algorithm
1. Start
2. Choose pivot from median(First, Mid, Last) or [Highest index value
recommended]
3. Take two variables to point left and right
4. Left points to the low index
5. Right points to the high index
6. While value at left is less than the pivot move right
7. While value at right is greater than the pivot move left
8. If both step 6 and step 7 does not match swap left and right
9. If left >= right, the point where they met is new pivot
10. Recursively sort the left and right part of the pivot
11. Stop
Example Code
/////////////////////////////////////////////////////////////////////
#include <stdio.h>
#define Max 7
int Array[Max] = {4,6,3,2,1,9,7};
int main () {
printf(“Input Array : ”);
display();
Quicksort(0,Max-1);
Printf(“Output Array : ”);
display();
return 0;
}
////////////////////// Array Display Function ///////////////////////
Void display ()
{
int i;
printf(“ [ ”);
while(true)
{
While(array[++leftpointer]<pivot) {
}
While(rightpointer > 0 && Array[--rightpointer] > pivot) {
}
If(leftpointer >= rightpointer)
{
Break;
}
Else
{
Printf(“Item Swapped : %d,%d\n”, Array[leftpointer],Array[rightpointer]);
swap(leftpointer,rightpointer);
}
}
Printf(“Pivot Swapped : %d,%d\n”,Array[leftpointer],Array[right]);
swap(leftpointer,right);
printf(“Updated Array : ”);
display();
return leftpointer;
}
////////////////////// Quick Sort Function ///////////////////////////
Void Quicksort(int left, int right)
{
If(right-left <= 0)
{
Return;
}
Else
{
Int pivot = Array[right];
Int partitionpoint = partition(left,right,pivot);
Quicksort(left,partitionpoint-1);
Quicksort(partitionpoint+1,right);
}
}
/////////////////////////////////////////////////////////////////////
Lab Task:
Write down the best, average and worst case complexity in the table below for sorting
algorithms mentioned in the table.
EXPERIMENT NO.14:
OBJECTIVE:
CMS: ________________
Obtained Marks:
Remarks:
A graph is a visual representation of a set of objects where some pairs of objects are
connected by links. The interconnected objects are represented by points termed as
vertices, and the links that connect the vertices are called edges. A graph is a pair of sets
(V,E), where V is the set of vertices and E is the set of edges connecting the pairs of vertices.
Take a look at the following graph shown below
V = {a,b,c,d,e} E = {ab,ac,cd,bd,de}
Mathematical graphs can be represented in data structure. We can represent a graph using
an array of vertices and a two dimensional array of edges. In graph data structure some
important terms are
Vertex Each node of the graph is represented as a vertex. In the figure given
below labeled circle represents vertices (A to G).
Edge Edge represents a path between two vertices or a line between two
vertices. In the figure given below, lines from A to B, B to C are
edges.
Adjacency Two nodes or vertices are adjacent if they are connected to each
other through an edge. In the figure given below B is
adjacent to A.
Path Path represents a sequence of edges between two vertices. In figure
given below ABCD represents a path from A to D.
Basic Operations:
Add Vertex
Add Edge
Display Vertex
Consider the above graph, DFS algorithm traverses from A to B to C to D first then to E, then
to F and at last to G. it employs following rules.
Visit adjacent unvisited vertex. Mark it visited, display it and also push it in a stack.
If no adjacent vertex found, pop up a vertex from stack. It will pop up all the vertices
from the stack which do not have adjacent vertices.
Repeat rule 1 and rule 2 until stack is empty.
Example Code
////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX 5
lstVertices[i]->visited = false;
}
}
int main() {
int i, j;
for(i = 0; i<MAX; i++) // set adjacency {
for(j = 0; j<MAX; j++) // matrix to 0
adjMatrix[i][j] = 0;
}
addVertex('S'); // 0
addVertex('A'); // 1
addVertex('B'); // 2
addVertex('C'); // 3
addVertex('D'); // 4
addEdge(0, 1); // S - A
addEdge(0, 2); // S - B
addEdge(0, 3); // S - C
addEdge(1, 4); // A - D
addEdge(2, 4); // B - D
addEdge(3, 4); // C - D
Visit adjacent unvisited vertex. Mark it visited, display it and insert it in a queue.
If no adjacent vertex found, remove the first vertex from queue.
Repeat 1 and 2 until queue is empty.
Example Code
////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX 5
struct Vertex {
char label;
bool visited;
};
//queue variables
int queue[MAX];
int rear = -1;
int front = 0;
int queueItemCount = 0;
//graph variables
//array of vertices
struct Vertex* lstVertices[MAX];
//adjacency matrix
int adjMatrix[MAX][MAX];
//vertex count
int vertexCount = 0;
//queue functions
void insert(int data) { }
queue[++rear] = data;
queueItemCount++; //get the adjacent unvisited vertex
} int getAdjUnvisitedVertex(int vertexIndex) {
int i;
int removeData() {
queueItemCount--; for(i = 0; i<vertexCount; i++) {
return queue[front++]; if(adjMatrix[vertexIndex][i] == 1 &&
} lstVertices[i]->visited == false)
return i;
bool isQueueEmpty() { }
return queueItemCount == 0;
} return -1;
}
//graph functions
void breadthFirstSearch() {
//add vertex to the vertex list int i;
void addVertex(char label) {
struct Vertex* vertex = (struct Vertex*) //mark first node as visited
malloc(sizeof(struct Vertex)); lstVertices[0]->visited = true;
vertex->label = label;
vertex->visited = false; //display the vertex
lstVertices[vertexCount++] = vertex; displayVertex(0);
}
//insert vertex index in queue
//add edge to edge array insert(0);
void addEdge(int start,int end) { int unvisitedVertex;
adjMatrix[start][end] = 1;
adjMatrix[end][start] = 1; while(!isQueueEmpty()) {
} //get the unvisited vertex of vertex which
is at front of the queue
//display the vertex int tempVertex = removeData();
void displayVertex(int vertexIndex) {
printf("%c ",lstVertices[vertexIndex]->label); //no adjacent vertex found
while((unvisitedVertex =
getAdjUnvisitedVertex(tempVertex)) != -1) {
lstVertices[unvisitedVertex]->visited =
true;
displayVertex(unvisitedVertex);
insert(unvisitedVertex);
}
}
//queue is empty, search is complete,
reset //the visited flag
for(i = 0;i<vertexCount;i++) {
lstVertices[i]->visited = false;
}
}
int main() {
int i, j;
for(i = 0; i<MAX; i++) // set adjacency {
for(j = 0; j<MAX; j++) // matrix to 0
adjMatrix[i][j] = 0;
}
addVertex('S'); // 0
addVertex('A'); // 1
addVertex('B'); // 2
addVertex('C'); // 3
addVertex('D'); // 4
addEdge(0, 1); // S - A
addEdge(0, 2); // S - B
addEdge(0, 3); // S - C
addEdge(1, 4); // A - D
addEdge(2, 4); // B - D
addEdge(3, 4); // C - D
printf("\nBreadth First Search: ");
breadthFirstSearch();
return 0;