本程序是用邻接表表示的图的深度优先搜索,为算法导论22.3伪代码的C++实现。
对于有向图可以得到正确的结果,对于无向图貌似也可以得到遍历结果,代码如下:
#include <iostream>
using namespace std;
#define N 6
#define INFINITE 0x7fffffff
#define WHITE 1
#define GRAY 2
#define BLACK 3
//顶点结点结构
struct Vertex
{
Vertex * next;/*指向下一个顶点*/
int id;/*节点的标志*/
Vertex():next(NULL),id(0){}
};
//图结构
struct Graph
{
Vertex *Adj[N+1];//N个顶点及邻接点头指针
int color[N+1];//颜色
int p[N+1];//指向遍历树节点的父结点
int d[N+1];/*节点发现时间*/
int f[N+1];/*节点结束遍历时间*/
Graph()
{
for(int i = 1; i <= N; i++)
{
Adj[i] = new Vertex;
color[i]=WHITE;
d[i] = 0;
f[i] = 0;
p[i] = 0;
}
}
~Graph()
{
for(int i = 1; i <= N; i++)
delete Adj[i];
}
};
void Print(Graph *g);
bool Init(Graph *g);
bool InsertEdge(Graph *g , int start,int end);
void PaintColor(Graph *g,int vertex,int color);
void DepthFirstVisit(Graph *g,int vertex,int& v_time);
//插入边
bool InsertEdge(Graph *g , int start,int end)
{
Vertex* v = new Vertex();
v->id = end;
if(g->Adj[start]->next == NULL)
{/*如果不存在临界表的头结点列表中,则插入*/
Vertex* s = new Vertex();
s->id = start;
g->Adj[start] = s;
}
Vertex* tmp = g->Adj[start];
while(tmp->next)
{
tmp = tmp->next;
}
tmp->next =v;
return true;
}
/*初始化临接表表示的图,有向图。
1->2->4
2->5
3->6->5
4->2
5->4
6->6
*/
bool Init(Graph *g)
{
InsertEdge(g,1,2);
InsertEdge(g,1,4);
InsertEdge(g,2,5);
InsertEdge(g,3,5);
InsertEdge(g,3,6);
InsertEdge(g,4,2);
InsertEdge(g,5,4);
InsertEdge(g,6,6);
return true;
}
void DepthFirstVisit(Graph *g,int vertex,int& v_time)
{
g->color[vertex] = GRAY;
v_time ++;
g->d[vertex] = v_time;
Vertex * v = g->Adj[vertex];
int node = v->id;
std::cout<<node<<"\t";
v = v->next;
while(v)
{
if(g->color[v->id] == WHITE)
{
g->p[v->id] = vertex;
DepthFirstVisit(g,v->id,v_time);
}
v = v->next;
}
g->color[node] = BLACK;
g->f[node] = v_time++;
}
/*
宽度优先搜索,vertex为初始访问的节点
这种方法适合于无向图,如果是有向图会产生死循环
*/
bool DepthFirstSearch(Graph *g,int vertex)
{
for(int i=1;i<=N;i++)
{
g->color[i] = WHITE;
}
int time = 0;
for(int i=1;i<=N;i++)
{
if(g->color[i] == WHITE)
{
DepthFirstVisit(g,i,time);
}
}
return true;
}
int main()
{
//构造一个空的图
Graph *g = new Graph;
Init(g);
DepthFirstSearch(g,1);
getchar();
return 0;
}