0% found this document useful (0 votes)
67 views38 pages

Graphs: CS 308 - Data Structures

Graphs are a data structure consisting of vertices and edges connecting the vertices. A graph can be directed or undirected. Common graph terminology includes adjacent nodes, paths, complete graphs, and weighted graphs. Graphs can be represented using an adjacency matrix or adjacency list. Common graph algorithms include depth-first search (DFS), breadth-first search (BFS), and algorithms to solve the single-source shortest path problem like Dijkstra's algorithm.

Uploaded by

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

Graphs: CS 308 - Data Structures

Graphs are a data structure consisting of vertices and edges connecting the vertices. A graph can be directed or undirected. Common graph terminology includes adjacent nodes, paths, complete graphs, and weighted graphs. Graphs can be represented using an adjacency matrix or adjacency list. Common graph algorithms include depth-first search (DFS), breadth-first search (BFS), and algorithms to solve the single-source shortest path problem like Dijkstra's algorithm.

Uploaded by

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

Graphs

CS 308 Data Structures

What is a graph?
A data structure that consists of a set of nodes

(vertices) and a set of edges that relate the nodes


to each other
The set of edges describes relationships among the
vertices

Formal definition of graphs

A graph G is defined as follows:


G=(V,E)
V(G): a finite, nonempty set of vertices
E(G): a set of edges (pairs of vertices)

Directed vs. undirected graphs

When the edges in a graph have no

direction, the graph is called undirected

Directed vs. undirected graphs


(cont.)

When the edges in a graph have a direction,


the graph is called directed (or digraph)

Warning: if the graph is


directed, the order of the
vertices in each edge is
important !!
E(Graph2) = {(1,3) (3,1) (5,9) (9,11) (5,7)

Trees vs graphs

Trees are special cases of graphs!!

Graph terminology
Adjacent nodes: two nodes are adjacent if they are
connected by an edge

5 is adjacent to 7
7 is adjacent from 5

Path: a sequence of vertices that connect two nodes in a

graph
Complete graph: a graph in which every vertex is
directly connected to every other vertex

Graph terminology (cont.)

What is the number of edges in a complete


directed graph with N vertices?
N * (N-1)

O( N )

Graph terminology (cont.)

What is the number of edges in a complete


undirected graph with N vertices?
N * (N-1) / 2

O( N )

Graph terminology (cont.)

Weighted graph: a graph in which each edge


carries a value

Graph implementation

Array-based implementation
A 1D array is used to represent the vertices
A 2D array (adjacency matrix) is used to
represent the edges

Array-based implementation

Graph implementation (cont.)

Linked-list implementation
A 1D array is used to represent the vertices
A list is used for each vertex v which contains the
vertices which are adjacent from v (adjacency list)

Linked-list implementation

Adjacency matrix vs. adjacency list


representation

Adjacency matrix

Good for dense graphs --|E|~O(|V|2)


Memory requirements: O(|V| + |E| ) = O(|V|2 )
Connectivity between two vertices can be tested
quickly

Adjacency list

Good for sparse graphs -- |E|~O(|V|)


Memory requirements: O(|V| + |E|)=O(|V|)
Vertices adjacent to another vertex can be found
quickly

Graph specification based on


adjacency matrix representation
const int NULL_EDGE = 0;

private:
template<class VertexType>
int numVertices;
class GraphType {
int maxVertices;
public:
VertexType* vertices;
GraphType(int);
int **edges;
~GraphType();
bool* marks;
void MakeEmpty();
};
bool IsEmpty() const;
bool IsFull() const;
void AddVertex(VertexType);
void AddEdge(VertexType, VertexType, int);
int WeightIs(VertexType, VertexType);
void GetToVertices(VertexType, QueType<VertexType>&);
void ClearMarks();
void MarkVertex(VertexType);
bool IsMarked(VertexType) const;
(continues)

template<class VertexType>
GraphType<VertexType>::GraphType(int maxV)
{
numVertices = 0;
maxVertices = maxV;
vertices = new VertexType[maxV];
edges = new int[maxV];
for(int i = 0; i < maxV; i++)
edges[i] = new int[maxV];
marks = new bool[maxV];
}
template<class VertexType>
GraphType<VertexType>::~GraphType()
{
delete [] vertices;
for(int i = 0; i < maxVertices; i++)
delete [] edges[i];
delete [] edges;
delete [] marks;
}

(continues)

void GraphType<VertexType>::AddVertex(VertexType vertex)


{

vertices[numVertices] = vertex;
for(int index = 0; index < numVertices; index++) {
edges[numVertices][index] = NULL_EDGE;
edges[index][numVertices] = NULL_EDGE;

}
}

numVertices++;

template<class VertexType>
void GraphType<VertexType>::AddEdge(VertexType fromVertex,
VertexType toVertex, int weight)
{

int row;
int column;
row = IndexIs(vertices, fromVertex);
col = IndexIs(vertices, toVertex);
edges[row][col] = weight;

(continues)

template<class VertexType>
int GraphType<VertexType>::WeightIs(VertexType fromVertex,
VertexType toVertex)
{
int row;
int column;
row = IndexIs(vertices, fromVertex);
col = IndexIs(vertices, toVertex);
return edges[row][col];
}

Graph searching

Problem: find a path between two nodes of

the graph (e.g., Austin and Washington)


Methods: Depth-First-Search (DFS) or
Breadth-First-Search (BFS)

Depth-First-Search (DFS)

What is the idea behind DFS?


Travel as far as you can down a path
Back up as little as possible when you reach a
"dead end" (i.e., next vertex has been "marked"
or there is no next vertex)

DFS can be implemented efficiently using a


stack

Depth-First-Search (DFS) (cont.)


Set found to false
stack.Push(startVertex)
DO
stack.Pop(vertex)
IF vertex == endVertex
Set found to true
ELSE
Push all adjacent vertices onto stack
WHILE !stack.IsEmpty() AND !found
IF(!found)
Write "Path does not exist"

start

end

(initialization)

template <class ItemType>


void DepthFirstSearch(GraphType<VertexType> graph, VertexType
startVertex, VertexType endVertex)
{

StackType<VertexType> stack;
QueType<VertexType> vertexQ;
bool found = false;
VertexType vertex;
VertexType item;
graph.ClearMarks();
stack.Push(startVertex);
do {
stack.Pop(vertex);
if(vertex == endVertex)
found = true;

(continues)

else {
if(!graph.IsMarked(vertex)) {
graph.MarkVertex(vertex);
graph.GetToVertices(vertex, vertexQ);
while(!vertexQ.IsEmpty()) {
vertexQ.Dequeue(item);
if(!graph.IsMarked(item))
stack.Push(item);
}
}
} while(!stack.IsEmpty() && !found);
if(!found)
cout << "Path not found" << endl;
}

(continues)

template<class VertexType>
void GraphType<VertexType>::GetToVertices(VertexType vertex,
QueTye<VertexType>& adjvertexQ)
{
int fromIndex;
int toIndex;
fromIndex = IndexIs(vertices, vertex);
for(toIndex = 0; toIndex < numVertices; toIndex++)
if(edges[fromIndex][toIndex] != NULL_EDGE)
adjvertexQ.Enqueue(vertices[toIndex]);
}

Breadth-First-Searching (BFS)

What is the idea behind BFS?


Look at all possible paths at the same depth
before you go at a deeper level
Back up as far as possible when you reach a
"dead end" (i.e., next vertex has been "marked"
or there is no next vertex)

Breadth-First-Searching (BFS) (cont.)

BFS can be implemented efficiently using a queue


IF(!found)
Set found to false
Write "Path does not exist"
queue.Enqueue(startVertex)
DO
queue.Dequeue(vertex)
IF vertex == endVertex
Set found to true
ELSE
Enqueue all adjacent vertices onto queue
WHILE !queue.IsEmpty() AND !found

Should we mark a vertex when it is enqueued or


when it is dequeued ?

start

end

(initialization)

next:

template<class VertexType>
void BreadthFirtsSearch(GraphType<VertexType> graph,
VertexType startVertex, VertexType endVertex);
{
QueType<VertexType> queue;
QueType<VertexType> vertexQ;//
bool found = false;
VertexType vertex;
VertexType item;
graph.ClearMarks();
queue.Enqueue(startVertex);
do {
queue.Dequeue(vertex);
if(vertex == endVertex)
found = true;
(continues)

else {
if(!graph.IsMarked(vertex)) {
graph.MarkVertex(vertex);
graph.GetToVertices(vertex, vertexQ);
while(!vertxQ.IsEmpty()) {
vertexQ.Dequeue(item);
if(!graph.IsMarked(item))
queue.Enqueue(item);
}
}
}
} while (!queue.IsEmpty() && !found);
if(!found)
cout << "Path not found" << endl;
}

Single-source shortest-path problem

There are multiple paths from a source vertex

to a destination vertex
Shortest path: the path whose total weight
(i.e., sum of edge weights) is minimum
Examples:

Austin->Houston->Atlanta->Washington:
1560 miles
Austin->Dallas->Denver->Atlanta->Washington:
2980 miles

Single-source shortest-path problem


(cont.)

Common algorithms: Dijkstra's algorithm,

Bellman-Ford algorithm
BFS can be used to solve the shortest graph
problem when the graph is weightless or all
the weights are the same
(mark vertices before Enqueue)

Exercises

24-37

You might also like