1. Interface (Graph.h, listQueue.h)
#ifndef GRAPH_H_INCLUDED
#define GRAPH_H_INCLUDED
class Graph
{
private:
struct adjListNode{
int node;
adjListNode* next;
adjListNode(int x, adjListNode* t) : node(x), next(t) {}
};
typedef adjListNode* vtx;
vtx* adjList; // adjacency list
int countV; // number of vertices in the graph
void dfsUtil(int, bool*); // recursive procedure in DFS
public:
Graph(int);
~Graph();
void addEdge(int, int);
void removeEdge(int, int);
bool isConnected(int, int);
void showConnected(int);
void dfs(int);
void bfs(int);
};
#endif // GRAPH_H_INCLUDED
#ifndef LISTQUEUE_H_INCLUDED
#define LISTQUEUE_H_INCLUDED
template <class Item>
class Queue
{
private:
struct node{
Item item;
node *next;
node(Item x) : item(x), next(0) {}
};
typedef node *link;
link head, tail; // enqueue to the tail, dequeue from the head
public:
Queue();
~Queue();
bool isEmpty() const;
void enqueue(Item); // push item into the queue
Item dequeue(); // retrieve item back from the queue
};
template <class Item>
Queue<Item>::Queue()
{
head = 0;
tail = 0;
}
template <class Item>
Queue<Item>::~Queue()
{
delete head;
}
template <class Item>
bool Queue<Item>::isEmpty() const
{
return head == 0;
}
template <class Item>
void Queue<Item>::enqueue(Item x)
{
link t = tail;
tail = new node(x);
if (head == 0)
head = tail;
else t->next = tail;
}
template <class Item>
Item Queue<Item>::dequeue()
{
Item v = head->item;
link t = head->next;
delete head;
head = t;
return v;
}
#endif // LISTQUEUE_H_INCLUDED
2. Implementation (Graph.cpp)
/* Represent graphs by adjacency list without dummy head node. */
#include"Graph.h"
#include"listQueue.h"
#include<iostream>
using namespace std;
Graph::Graph(int N)
{
countV = N;
adjList = new vtx[countV];
for (int i = 0; i < N; ++i){
adjList[i] = new adjListNode(i, 0);
}
}
Graph::~Graph()
{
for (int i = 0; i < countV; ++i)
delete[] adjList[i];
delete[] adjList;
}
void Graph::addEdge(int x, int y)
{
if (x >= 0 && x < countV && y >= 0 && y < countV){
adjList[x] = new adjListNode(y, adjList[x]);
}
}
bool Graph::isConnected(int x, int y)
{
int check = 0;
if (x >= 0 && x < countV && y >= 0 && y < countV){
vtx newNode = adjList[x];
while (newNode->next != 0){
if (newNode->node == y){
check = 1;
break;
}
else newNode = newNode->next;
}
}
return check;
}
void Graph::removeEdge(int x, int y)
{
if (x >= 0 && x < countV && y >= 0 && y < countV){
vtx newNode1 = adjList[x], newNode2 = adjList[x];
int countLoop = 0;
while (newNode1->node != y && newNode1->next != 0){
newNode2 = newNode1;
newNode1 = newNode2->next;
++countLoop;
}
if (!countLoop){
newNode2 = newNode1->next;
adjList[x] = newNode2;
}
else{
newNode2->next = newNode1->next;
adjList[x] = newNode2;
}
}
}
void Graph::showConnected(int x)
{
cout << "The connection of vertex " << x << ":" << endl;
vtx newNode = adjList[x];
while (newNode->next != 0){
cout << newNode->node << " -> ";
newNode = newNode->next;
}
cout << x << endl;
}
void Graph::dfsUtil(int v, bool* visited)
{
visited[v] = true;
vtx newNode1 = adjList[v];
while (newNode1->next != 0){
if (!visited[newNode1->node]){
// output the node (v, newNode1->node)
cout << "(" << v << ", " << newNode1->node << ")" << endl;
// recursion
dfsUtil(newNode1->node, visited);
}
else{
newNode1 = newNode1->next;
}
}
}
void Graph::dfs(int v)
{
bool* visited = new bool[countV];
for (int i = 0; i < countV; ++i)
visited[i] = false;
dfsUtil(v, visited);
}
void Graph::bfs(int v)
{
Queue<int> q;
bool* visited = new bool[countV];
for (int i = 0; i < countV; ++i)
visited[i] = false;
q.enqueue(v);
visited[v] = true;
while (!q.isEmpty()){
int temp = q.dequeue();
while (adjList[temp]->next != 0){
if (!visited[adjList[temp]->node]){
q.enqueue(adjList[temp]->node);
visited[adjList[temp]->node] = true;
cout << "(" << temp << ", " << adjList[temp]->node << ")" << endl;
}
adjList[temp] = adjList[temp]->next;
}
}
delete[] visited;
}
3. Client (main.cpp)
#include<iostream>
#include"Graph.h"
using namespace std;
int main(int argc, char* argv[])
{
int V = atoi(argv[1]);
Graph *g = new Graph(V);
for (int i = 0; i < V; ++i){
cout << "Enter the connections of vertex " << i << ":" << endl;
int j;
while (cin >> j){
if (j >= 0 && j < V && j != i){
g->addEdge(i, j);
}
else if (j == i){
// if the input vertex is the same as the given vertex
break;
}
else cout << "Out of range." << endl;
}
}
for (int i = 0; i < V; ++i)
g->showConnected(i);
// DFS
int start = 0;
cout << "Enter the DFS starting node:";
cin >> start;
g->dfs(start);
// BFS
cout << "Enter the BFS starting node:";
cin >> start;
g->bfs(start);
return 0;
}
测试用图:
执行:
Enter the connections of vertex 0:
1 0
Enter the connections of vertex 1:
0 2 3 4 1
Enter the connections of vertex 2:
1 2
Enter the connections of vertex 3:
1 4 3
Enter the connections of vertex 4:
1 3 4
The connection of vertex 0:
1 -> 0
The connection of vertex 1:
4 -> 3 -> 2 -> 0 -> 1
The connection of vertex 2:
1 -> 2
The connection of vertex 3:
4 -> 1 -> 3
The connection of vertex 4:
3 -> 1 -> 4
Enter the DFS starting node:0
(0, 1)
(1, 4)
(4, 3)
(1, 2)
Enter the BFS starting node:4
(4, 3)
(4, 1)
(1, 2)
(1, 0)