0% found this document useful (0 votes)
3 views32 pages

Unit II

The document provides an overview of various data structures, focusing on linked lists, stacks, and their implementations in C. It explains the characteristics and operations of single and double linked lists, as well as stack operations like push and pop. Additionally, it includes code examples for creating and manipulating these data structures.

Uploaded by

Pawan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views32 pages

Unit II

The document provides an overview of various data structures, focusing on linked lists, stacks, and their implementations in C. It explains the characteristics and operations of single and double linked lists, as well as stack operations like push and pop. Additionally, it includes code examples for creating and manipulating these data structures.

Uploaded by

Pawan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 32

DATA STRUCTURES

Linked Lists

Even if the array is dynamically allocated, an estimation of the maximum size of the list is required which
wastes lot of space if not used. Insertion and deletion are expensive because insertion at first requires first
pushing the entire array down one spot to make a room, similarly deletion requires pushed up the list.
To avoid the disadvantages of arrays introduced a new concept called linked list, which is not stored
in a contiguously locations. Linked list is also called as self-referential class or one-way list.

The linked list consists of a series of structures, which are not necessarily adjacent in memory. Each
structure contains the element and a pointer to a structure containing its successor. The Previous element to
the tail of the list is called its predecessor. Clearly head does not have a predecessor and tail does not have
successor. We call this the Next pointer.

The last cells Next pointer points to NULL. Combination data and pointer to next structure is also
called as node.

Some of the basic operations that can be performed on a list are

1. Create a list
2. Search for an element in a list
3. Delete an element from a list ( at beg, at end, at given location)
4. Add an element at a specified location of a list (at beg, at end, at given location).
5. Sort a list
6. Print a list
7. Determine the size or no of elements in a list

A list can be implemented statistically or dynamically using an array index or pointers respectively.

The declaration of a node is as follows:

In ‘C’
struct Node {
Element_type data;
struct Node *next;
}
struct Node *head;

We can form a linked list using pointers the structure of the list may be as shown below.

10 20 30 NULL

A List with Pointer values (Addresses are assumed only)

10 3000 20 4000 30 0

UNIT II
DATA STRUCTURES

1000 3000 4000


Double Linked List:

Some times it is convenient to traverse lists backwards. The standard implementation does not help
here. The cost of this is an extra link, which adds to the space requirements and also doubles the cost of
instructions and deletions because there are more pointers to fix. On the other hand it simplifies deletion,
because you no longer have to refer to a key by using a pointer to the previous cell.

Declaration of the node is,


struct node
{
struct node *previous;
Element_type data;
struct node *next;
}

A Sample Double Linked List

NUL A1 A2 A3 NUL
L L
Circular Linked List:

A Popular Convention to have the last cell keep a pointer back to the first. It can be done with or
without header.

Single Circular Linked List

A1 A2 A3

Code is here for Single Linked List operations:

#include<stdio.h>
#include<conio.h>
#include<alloc.h>

struct node
{
int data;
struct node *next;
};

UNIT II
DATA STRUCTURES

typedef struct node node;

node * create(node *);


void show();

node * insertbeg(node *);


void insertloc(node *);
void insertend(node *);

node * delbeg(node *);


void delend(node *);
void delloc(node *);

void main()
{
int ch;
node *start=NULL;

while(1)
{
clrscr();
printf("\n1.Create\n2.Insert at beg\n3.Insert at end\n4.Insert at loc\n");
printf("\n5.Del at Beg\n6.Del at Loc\n7.Del at End\n8.Show\n9.Exit");
printf("Enter your choice...");
scanf("%d",&ch);

switch(ch)
{
case 1:
start = create(start); break;
case 2:
start = insertbeg(start);break;
case 3:
insertend(start);break;
case 4:
insertloc(start); break;
case 5:
start = delbeg(start);break;
case 6:
delloc(start);break;
case 7:
delend(start); break;
case 8:
show(start); getch();break;
case 9:

default:

UNIT II
DATA STRUCTURES

return;
}
}
}

node * create(node *t)


{
node *temp,*p;
char ch='y';

while(ch=='y')
{
temp = (node *) malloc(sizeof(node));
printf("\nEnter data : ");
scanf("%d",&temp->data);
temp->next = NULL;

if(t==NULL)
t = temp;
else
{
p = t;
while(p->next!=NULL)
p = p->next;
p->next = temp;
}
printf("\n Wish to insert one more?");
ch = getchar();
}
return t;
}
void show(node *t)
{
node *p;
for(p = t;p!=NULL;p=p->next)
printf("%d->",p->data);
printf("null\n");
}

node * insertbeg(node *t)


{
node *p;
p = (node *)malloc(sizeof(node));
printf("Enter data");
scanf("%d",&p->data);
p->next = t;
t = p;

UNIT II
DATA STRUCTURES

return t;
}
void insertloc(node *t)
{
node *p,*k;
int loc,i;

p = (node *)malloc(sizeof(node));
printf("Enter data & location");
scanf("%d%d",&p->data,&loc);

k = t;
for(i=1;i<loc;i++)
k = k->next;
p->next = k->next;
k->next = p;
}

void insertend(node *t)


{
node *p,*k;
p = (node *)malloc(sizeof(node));
printf("Enter data");
scanf("%d",&p->data);
p->next = NULL;

k = t;
while(k->next!=NULL)
k = k->next;
k->next = p;
}

node * delbeg(node *t)


{
node *p;
p = t;
t = t->next;
free(p);
return t;
}

void delend(node *t)


{
node *p,*k;

p = t; k = t->next;

while(k->next!=NULL)

UNIT II
DATA STRUCTURES

{
p = p->next;
k = k->next;
}
p->next = NULL;
free(k);
}

void delloc(node *t)


{
int loc,i;
node *p,*k;

p = t; k = t->next;
printf("\nEnter location : ");
scanf("%d",&loc);

for(i=1;i<loc;i++)
{
p = p->next;
k = k->next;
}
p->next = k->next;
free(k);
}

Stack

The stack is a data structure that is very frequently used in computing as a kind of temporary storage. It is a
list of elements to which additions and deletions can only be made at one end-the top. Consequently, the
stack becomes a last-in-first-out (LIFO) data structure; the last element added is the first to be removed. When
we add an item to the top of the stack, it is called a PUSH operation and when we remove an item from the
top, it is called a POP operation. The stack data structure maintains a stack pointer always pointing to its top.
After pushing an item, the stack pointer moves up to point always to the last item added. Similarly, after
popping an item, the stack pointer moves down to the next last item in the stack.

UNIT II
DATA STRUCTURES

Stack Model

POP (S) PUSH (R, S)


Stack S
TOP (S)
Stack can be implemented in either Fixed size stack or Dynamic size stack.
In fixed size stack we are using arrays.
Ex:
Shows a sample Stack

3 Top
2
1

After you Push 4 the Stack would be

4 Top
3
2
1

When you Pop the Stack would be

3 Top
2
1

Code is here:

#include<stdio.h>
#include<conio.h>
#define MAX 5

void push(int stk[MAX],int *top)


{
int d;
if(*top==MAX-1)
{
printf("\n Stack is FULL\n");

UNIT II
DATA STRUCTURES

return;
}
else
{
printf("\nEnter an item : ");
scanf("%d",&d);
stk[++(*top)] = d;
}
}

void pop(int stk[MAX],int *top)


{
if(*top==-1)
{
printf("\nStack is Empty !!\n");
return;
}
else
printf("\nDeleted item : %d\n",stk[(*top)--]);
}

void show(int stk[MAX],int *top)


{
int i = *top;

printf("\n\n");

while(i>=0)
printf("%4d",stk[i--]);

printf("\n");
}

void main()
{
int ch;
int stk[MAX];
int top = -1;

clrscr();

while(1)
{
printf("\nSTACK OPERATIONS\n----------------\n1.Push\n2.Pop\n3.Show\n");
printf("4.Exit\n\nEnter your chioce...");
scanf("%d",&ch);
switch(ch)

UNIT II
DATA STRUCTURES

{
case 1:
push(stk,&top);
break;
case 2:
pop(stk,&top); break;
case 3:
show(stk,&top); break;
case 4:
default:
return;
}
}
}

Doubly Linked List:

Code is here:

#include<stdio.h>
#include<conio.h>
#include<alloc.h>

struct dnode
{
int data;
struct dnode *prev,*next;
};

typedef struct dnode dnode;

dnode * create(dnode *);


void show();

dnode * insertbeg(dnode *);


void insertloc(dnode *);
void insertend(dnode *);

dnode * delbeg(dnode *);


void delend(dnode *);
void delloc(dnode *);

void main()
{
int ch;
dnode *start=NULL;

UNIT II
DATA STRUCTURES

while(1)
{
clrscr();
printf("\n1.Create\n2.Insert at beg\n3.Insert at end\n4.Insert at loc\n");
printf("\n5.Del at Beg\n6.Del at Loc\n7.Del at End\n8.Show\n9.Exit");
printf("\n\nEnter your choice...");
scanf("%d",&ch);

switch(ch)
{
case 1:
start = create(start); break;
case 2:
start = insertbeg(start);break;
case 3:
insertend(start);break;
case 4:
insertloc(start); break;
case 5:
start = delbeg(start);break;
case 6:
delloc(start);break;
case 7:
delend(start); break;
case 8:
show(start); getch();break;
case 9:

default:
return;
}
}
}

dnode * create(dnode *t)


{
dnode *temp,*p;
char ch='y';

while(ch=='y')
{
temp = (dnode *) malloc(sizeof(dnode));
printf("\nEnter data : ");
scanf("%d",&temp->data);
temp->prev = temp->next = NULL;

if(t==NULL)

UNIT II
DATA STRUCTURES

t = temp;
else
{
p = t;
while(p->next!=NULL)
p = p->next;
p->next = temp;
temp->prev = p;
}
fflush(stdin);
printf("\n Wish to insert one more?");
ch = getchar();
}
return t;
}

void show(dnode *t)


{
dnode *p;

for(p = t;p->next!=NULL;p=p->next)
printf("%d->",p->data);
printf("%d->null\n",p->data);

for(;p!=NULL;p=p->prev)
printf("%d->",p->data);
printf("null\n");

dnode * insertbeg(dnode *t)


{
dnode *p;
p = (dnode *)malloc(sizeof(dnode));
printf("Enter data");
scanf("%d",&p->data);
p->next = t;
t->prev = p;
t = p;
return t;
}
void insertloc(dnode *t)
{
dnode *p,*k;
int loc,i;

p = (dnode *)malloc(sizeof(dnode));
printf("Enter data & location");

UNIT II
DATA STRUCTURES

scanf("%d%d",&p->data,&loc);

k = t;
for(i=1;i<loc;i++)
k = k->next;

p->next = k->next;
k->next->prev = p;
k->next = p;
p->prev = k;
}

void insertend(dnode *t)


{
dnode *p,*k;
p = (dnode *)malloc(sizeof(dnode));
printf("Enter data");
scanf("%d",&p->data);
p->next = NULL;

k = t;
while(k->next!=NULL)
k = k->next;
k->next = p;
p->prev = k;
}

dnode * delbeg(dnode *t)


{
dnode *p;

p = t;
t = t->next;
t->prev = NULL;
free(p);

return t;
}

void delend(dnode *t)


{
dnode *p,*k;

p = t; k = t->next;

while(k->next!=NULL)
{
p = p->next;

UNIT II
DATA STRUCTURES

k = k->next;
}
p->next = NULL;
free(k);
}

void delloc(dnode *t)


{
int loc,i;
dnode *p,*k;

p = t; k = t->next;
printf("\nEnter location : ");
scanf("%d",&loc);

for(i=1;i<loc;i++)
{
p = p->next;
k = k->next;
}
p->next = k->next;
k->next->prev = p;
free(k);
}

Linked List Implementation of Stack or dynamic size stack:

The first implementation of a stack uses a single linked list. We perform a push by inserting at the
front of the list. We perform a pop by deleting the element at the front of the list. A top operation merely
examines the element at the front of the list, returns its value.

Ex:
Shows a sample Stack
top

3 2 1 NULL

After you Push 4 the stack would be


top

4 3 2 1 NULL
When you Pop, the Stack would be

UNIT II
DATA STRUCTURES

top

3 2 1 NULL

Code is here:

Applications of Stacks:

1. Compilers will take the help of stack for checking syntax errors (Symbol Balancing)
2. Stacks were used in evaluating postfix expressions (Reverse polish notation).
3. Stacks are used in conversion of infix expressions to postfix expressions.
4. Stack for matching brackets in an expression.
5. Stacks were used in function call.

i.e. When there is a function call, all the important information that needs to be saved, such as register
values and the return addresses are saved onto the stack. The information saved is called either an activation
record or stack frame.

Conversions:

Infix to Postfix conversion Code:

#include<stdio.h>
#include<conio.h>
#define MAX 7

void conversion(char *,char *);


int pcd(char);

UNIT II
DATA STRUCTURES

void main()
{
char infix[20],post[20];

clrscr();

printf("Enter any infix notation : ");


gets(infix);

conversion(infix,post);

puts("Infix notation : ");


puts(infix);
puts("Postfix notation : ");
puts(post);

getch();
}

void conversion(char in[20],char post[20])


{
int i,j,top=-1;
char ch;
char stk[MAX];

j = 0;

for(i=0;in[i]!='\0';i++)
{
ch = in[i];

if(isalpha(ch))
post[j++] = ch;
else
if(ch=='(')
stk[++top] = ch;
else
if(ch==')')
{
while(stk[top]!='(')
post[j++] = stk[top--];
top--;
}
else
{
while(pcd(stk[top]) >= pcd(ch))
post[j++] = stk[top--];

UNIT II
DATA STRUCTURES

stk[++top] = ch;
}
}

while(top>-1)
post[j++] = stk[top--];

post[j] = '\0';
}

int pcd(char op)


{
if(op=='$')
return 5;
else
if((op=='*')||(op=='/'))
return 4;
else
if((op=='+')||(op=='-'))
return 3;
else
return -1;
}

Evaluation of Post fix expression:

Code is given below:

#include<stdio.h>
#include<conio.h>

UNIT II
DATA STRUCTURES

#define MAX 7

float evaluate(char *);


float calculate(float,float,char);

void main()
{
char postfix[20];

clrscr();

puts("\nEnter any postfix notation : ");


gets(postfix);

printf("After evaluation : %f",evaluate(postfix));

getch();
}

float evaluate(char post[20])


{
float stk[MAX],a,b,c;
char ch;
int i,top=-1;

i = 0;
while(post[i]!='\0')
{
ch = post[i];

if(isdigit(ch))
stk[++top] = (float) ch-'0';
else
{
b = stk[top--];
a = stk[top--];
c = calculate(a,b,ch);
stk[++top] = c;
}
i++;
}
return stk[top--];
}

float calculate(float a, float b,char op)


{
switch(op)
{

UNIT II
DATA STRUCTURES

case '+': return a+b;


case '-': return a-b;
case '/': return a/b;
case '$': return pow(a,b);
case '*': return a*b;
}
}

Queue

Like Stacks, Queues are lists. With a queue, however, insertion is done at one end called rear end, where as
deletion is performed at the other end called front end. Some times it is called FIFO (First in First out) List.
The basic operations on a queue are Enqueue, which inserts an element at the end of the list (called
the rear), and Dequeue, which deletes the elements at the start of the list.

Array Implementation of Queue

Model of a Queue is

Dequeue(Q) Enqueue(Q)
Queue Q

Consider a queue, which can add a maximum of five elements

After Create

0 1 2 3 4
Front = 0, Rear = 0

After adding 5, 7, and 9 in same sequence the queue will be

5 7 9

0 1 2 3 4

Front Rear
After an Dequeue operation

7 9

0 1 2 3 4

Front Rear

UNIT II
DATA STRUCTURES

But there is one potential problem with the above implementation after some Enqueue operation the Queue
appears to be full. (Suppose rear = 4 and front = 2 for 5 cell queue the queue appears to be full but not). Then
you cannot insert further till the queue is empty.

The Simple solution is that whenever front and rear gets to the end of the array, it is wrapped around to the
beginning. This is known as circular Queue.

Applications of queues:

1. Uses of Queues in operating systems: Operating system maintains several queues like ready queue, device
queue etc. for handling multiple processes.

2. Use of Queue in Network Ex: for Queuing jobs in file Server.

3. A Whole branch of mathematics, known as queuing theory, deals with computing, probabilistically, how
long users expect to wait on a line, how long the line gets, and other such questions.

Code for Queue operations is here:

#include<stdio.h>
#include<conio.h>
#define MAX 5

int q[MAX];
int front,rear;

void enqueue()
{
int d;
if(rear==MAX-1)
{
printf("\n Queue is FULL\n");
return;
}
else
{
printf("\nEnter an item : ");
scanf("%d",&d);
q[++rear] = d;
}
}

void dequeue()
{
if(front==rear+1)

UNIT II
DATA STRUCTURES

{
printf("\nQueue is Empty !!\n");
return;
}
else
printf("\nDeleted item : %d\n",q[front++]);
}

void show()
{
int i = front;

printf("\n\n");

while(i<=rear)
printf("%4d",q[i++]);

printf("\n");
}

void main()
{
int ch;

front = 0;
rear = -1;

while(1)
{
printf("\nQUEUE OPERATIONS\n\n1.Enqueue\n2.Dequeue\n3.Show\n");
printf("4.Exit\n\nEnter your chioce...");
scanf("%d",&ch);
switch(ch)
{
case 1:
enqueue(); break;
case 2:
dequeue(); break;
case 3:
show(); break;
case 4:
default:
return;
}
}
}

UNIT II
DATA STRUCTURES

Trees

Def: A tree is a collection of nodes. A Tree consists of a distinguished node r, called the root, and zero or
more nonempty (sub) trees T1, T2…Tk each of whose roots are connected by a directed edge from r.
The root of each subtree is said to be child of r, and r is the parent of each sub root.
A Tree of n nodes will consist of n-1 edges. Node with no children is called Leaf. Nodes with
same parent are called Siblings. A Path from n1 to nk is defined as a sequence of nodes n1,n2,----,nk such that
ni is the parent of ni + 1 for 1 <= i<= k. the Length of the path is the no of edges on the path. There is a path
of length zero from every node to itself.

Note:- In a tree there is only one path from root to each node.

For any node ni, the depth of ni is the length of the unique path from the root is at depth 0.

The Height of ni is the longest path from ni to a leaf. If there is path from n1 to n2, there n1 is an ancestor of n2
and n2 is a descendent of n1. If n1 n2 then n1 is a proper ancestor of n2 and n2 is a proper descendent of n1.

Applications of Trees

1) Help analyze electrical circuits and to represent the structure of mathematical formulas.
2) Trees are used to represent the syntactic structure of source programs in compilers.
3) Trees are used in expression evaluation
4) Trees are used in storing records into the database (e.g. B-Trees). This improves the performance of data
storage and retrieval.
5) Trees are used in maintaining the directory and file system within the operating systems.
6) Used to represent web page structures.

UNIT II
DATA STRUCTURES

Node Declaration for Trees:

struct Tree_Node
{
Element_Type data;
Struct Tree_Node *First_Child;
struct Tree_Node *Next_Silding;
. . . .
};

A Sample Tree:
A

B D E
C

F
I
G
H
Binary Trees:

A Binary tree is a tree in which no node can have more than two children. The first subset contains a single
element called the ‘root’ of the tree. The other two subsets themselves binary tree, called the ‘left’ and ‘right’
sub trees of the original tree.
If every non-leaf node in a binary tree has nonempty left and right sub trees, the tree is termed a
‘strictly binary tree’. A ‘complete binary tree’ of depth d is the strictly binary tree all of whose leaves are at
level d.

A A
Ex:
B
B C
C
D D

E
E

UNIT II
DATA STRUCTURES

The Average depth of binary tree is O(n).


The average depth of binary search tree is O (log n).
The depth of a binary tree can be as long an n-1 in worst case
i.e. Ex:

Binary Search Tree (BST)

A binary search tree is a binary tree in which all elements stored in the left sub tree of any node X are all less
than the element stored at X, and all elements stored in the right sub tree of X are greater than the element
stored at X. Minimum element of the BST is the left leaf node and Maximum element of the BST is the right
most leaf node. Searching of any element is very fast. The average depth of a binary search tree is O(log n).
Ex:

2 8

1 4

Insert Operation: Consider a Binary Search tree

To insert any element first check whether this element is already exists in a tree if the element is not found,
then check whether the element is greater than the root or less than the root if the element is greater than
the root then it moves towards right words if it is less than the root then it moves left words, this process
continues recursively and finding a correct location and insert an element.

After Inserting 5

6
5<6 6
2 8
5>2 2 8
5>4 1 4
1 4

Inserted 3
3 5
UNIT II
DATA STRUCTURES

Remove or Delete Operation

Once we have found the node to be removed, we need to consider several possibilities
1. If node is a leaf, it can be deleted immediately
2. If the node has one child, the node can be removed after its parent adjusts
a pointer to bypass the node. Notice that the removed node is now
Unreferenced and can be deleted only if a pointer to it has been saved.
3. The complicated case is when a node has two childrens the general strategy is to replace the key of this
node will the smallest key of the right sub tree and remove that smallest key from the right sub tree.
Ex:
Consider a BST
6

2 8

1 4

3
3.
5

After removing 2 which has two children

6
Minimum of
8
Right sub Tree 3

1 4

3.
5
Where 3 is the minimum of sub tree and 3 is deleted from right sub tree.

Traversals of Binary trees:-

Let T be a binary tree. There are different methods that differ in the order in which they visit the
nodes. The three different traversal methods are

(1) Inorder,
(2) Preorder,

UNIT II
DATA STRUCTURES

(3) Postorder

Inorder Traversal:

It follows the general strategy of left-root-right. In this traversal, if T is not empty


(1) Traverse the left sub tree,
(2) Visit the root node of T,
(3) Then traverse the right sub tree.
Consider a binary tree,

B C

D E F
The inorder traversal of the given binary tree is,
D B E A F C

Preorder Traversal:

This follows the strategy of Root-Left-Right i.e,


(1) Visit the root node
(2) Traverse the left sub tree in preorder,
(3) Traverse the right sub tree in preorder.

For the above tree the Preorder Traversal is,


A B D E C F

Post order Traversal:

This follows the strategy of Left-Right-Root i.e,


(1) Traverse the left sub tree in Post order,
(2) Traverse the right sub tree in Post order,
(3) Visit the root.

For the above tree the post order traversal is,


D E B F C A

Code is given below:

#include<stdio.h>
#include<conio.h>
#include<process.h>

UNIT II
DATA STRUCTURES

struct node
{
int data;
node *left,*right;
};

node * insert(node *,int);


void preorder(node *);
void inorder(node *);
void postorder(node *);

node * insert(node *t,int x)


{
if(t==NULL)
{
t = new node;
t->data = x;
t->left= t->right = NULL;
return t;
}
else
if(x < t->data)
t->left = insert(t->left,x);
else
if(x > t->data)
t->right= insert(t->right,x);
else
{
cout<<"\n Data already Exists !!";
return t;
}
return t;
}

void preorder(node *t)


{
if(t!=NULL)
{
printf("%3d",t->data);
preorder(t->left);
preorder(t->right);
}
}

UNIT II
DATA STRUCTURES

void inorder(node *t)


{
if(t!=NULL)
{
inorder(t->left);
printf("%3d",t->data);
inorder(t->right);
}
}

void postorder(node *t)


{
if(t!=NULL)
{
postorder(t->left);
postorder(t->right);
printf("%3d",t->data);
}
}

void main()
{

int ch;
int data;
node *t=NULL;

clrscr();

while(1)
{
cout<<"\n\nM A I N M E N U\n- - - - - - - -\n";
cout<<"\n1. Insert \n 2. Preorder \n 3. Inorder \n 4. Postorder\n";
cout<<"\n5. Exit\n Enter ur choice :";
cin>>ch;
switch(ch)
{
case 1:
printf("\nEnter data :");
scanf("%d",&data);
t = insert(t,data);
break;
case 2:
printf("\n\n");

UNIT II
DATA STRUCTURES

preorder(t);break;
case 3:
printf("\n\n");
inorder(t);break;
case 4:
printf("\n\n");
postorder(t);break;
case 5:
default:
exit(0);
}
}

Graphs

A Graph G consists of a set V of vertices (Nodes) and a set of edges (arcs)E. We write G = (V, E). V is a finite
and non empty set of vertices. E is a set of pairs of vertices called edges.
An edge e = (v, w) is a pair of vertices v and w, and is said to be incident with v and w. Nodes v and w
are called as endpoints of e, and u and v are said to be adjacent nodes or neighbors. Ex: An example graph G

A B

C
V (G) = { A, B, C }
E (G) = { (A, B) (A, C) (B, C) }

Representation of Graphs:

There are two types in which we can represent graphs.

1. Adjacency Matrix
2. Adjacency Lists

The Choice of representative depends on the application and function to be performed on the graph.

Adjacency Matrix:

The Adjacency Matrix A for a graph G = (V, E) with n vertices, is an n x n Matrix if bits, such that A

1 If there is an edge Vi to Vj(un weighted graph)


Aij =
0 If not

UNIT II
DATA STRUCTURES

In case of weighted graph we are measuring a weight instead of 1.

Ex:
Let us consider a graph

1 2

4 3

The Adjacency Matrix would be

1 2 3 4
A= 1 0 1 0 1
2 0 0 1 0
3 0 0 0 0
4 0 0 1 0

Observe that have we needed n2 bits to represent a graph with n nodes.

The disadvantages of this kind of representations are


1) It takes O (n2) spaces to represent a graph with n vertices, even for sparse graphs
2) It takes O (n2) time to solve most of the graph problems.

Adjacency List Representation

In this representation, we store a graph as a linked structure. We store all the vertices in a list and
then for each vertex, we have a linked list of the adjacent vertices.

Ex:
Let us consider a Graph

1 2

4 3

There fore the representation would be

1
2 4 NULL
2

3 NULL
UNIT II
NULL
DATA STRUCTURES

Graph Traversals:

Given Undirected graph G and a vertex V in V(G) we are interested in visiting all vertices in G that are
reachable from V1 we shall look at two ways of doing this
1. Depth first Search
2. Breadth first Search

Depth first Search:

Depth first Search of an undirected graph proceeds as follows. The start Vertex V is visited. Next an
unvisited Vertex W adjacent to V is

selected and a depth first search from W initiated. When a vertex U is reached such that all its adjacent vertices
have been visited. We back up to the last vertex visited which has an unvisited Vertex W adjacent to it and
initiate a depth first search from W. The search terminates when no unvisited vertex can be reached from any
of the visited ones.

Pseudo Code

Void DFS(Vertex V)
{
visited[v] = True;
for each Vertex W adjacent to V
if(! Visited[W])
DFS(W);
}

Ex:
A
For the Given Graph

A
B

B D E
C

UNIT II
C
D E
DATA STRUCTURES

The DFS of the given graph is

Here dashed line i.e. the back


Edge which indicates those
edges that are not really part of the tree but are available in
graph.

Breadth-First-Search

Starting at vertex V and marking it an visited. BFS differs from Depth first search in that all unvisited
vertices adjacent to V are visited next. Then unvisited vertices adjacent to these vertices are visited and so on.

Pseudo code

Void BFS(Vertex V)
{
initialize Q to be Empty //Q is a Queue
while(1)
{
for each vertex W adjacent to V
if(visited[W] = false)
{
Enqueue(Q, W);
Visited[W] = True;
}
if(Q is Empty)
return;
V = Dequeue(Q);
}
}

Ex:
Let the given graph be The BFS of the given graph is

A
A

B D E
B D E

C
UNIT II

C
DATA STRUCTURES

Here dashed line indicates Back edges which are not really part of the tree but are available in graph.

UNIT II

You might also like