话不多说,直接上代码。有关深度优先遍历的概念请参考我的前一篇博文。
#include <iostream>
#include <cstring>
using namespace std;
typedef char VertexType;
typedef int EdgeType;
const int MAXVEX = 110;
typedef struct EdgeNode{ //存储边表节点
int adjvex; //邻接点域,存储该顶点对应的下标。
EdgeType weight; //存储权值
struct EdgeNode *next; //指向下一个邻接点
}EdgeNode;
typedef struct VertexNode{ //存储表顶点,实现方法位将表顶点存放在数组中
VertexType data; //存储顶点信息(权值)
EdgeNode *firstedge; //边表头指针
}VertexNode,AdjList[MAXVEX];//实现方法为数组
typedef struct{ //存储图的结构体
AdjList adjList; /*adjList存储一个图的邻接表数组,相当于一个GraphAdjList
变量存储一张图*/
int numVertexe,numEdges;//图中顶点的总个数与边的总个数
}GraphAdjList;
void CreateALGraph(GraphAdjList *G){
int i,j,k;
EdgeNode *e;
//i,j,k,*e均为一会儿建立图时需用到的变量,此处提前声明
cout<<"请输入顶点数和边数:";
cin>>G->numVertexe>>G->numEdges;
cout<<"请输入"<<G->numVertexe<<"个顶点存储的信息";
for(i=0;i<G->numVertexe;i++){//输入顶点信息,建立顶点表
cin>>G->adjList[i].data;
G->adjList[i].firstedge=NULL;//将边表置为空
}
for(k=0;k<G->numEdges;k++){//建立边表
cout<<"输入边(vi,vj)上的顶点序号:";
cin>>i>>j;//输入边(vi,vj)上的顶点序号
e = new EdgeNode; //生成边表结点
e->adjvex = j;//邻接序号为j
e->next = G->adjList[i].firstedge;//第一步
G->adjList[i].firstedge=e;//第二步
/*由于建立的是一个无向图,因此两个结点间都应有关联,第一步与第二步的作用
就是使两个方向均有关联,下同。*/
/*!*/e = new EdgeNode;
e->adjvex=i;
e->next=G->adjList[j].firstedge;
G->adjList[j].firstedge=e;/*!*/
/*双叹号注释的区间,看似与上面的代码如初一辙,实际上这正是实现邻接表的关
键。邻接表的表头是存放在数组当中的,数组中的下标已经存放了每一个顶点的信
息。而此处建立的是一个无向图,举个例子来说,我们建立的是由i到j的无向图,
那么显然先建立i到j的关系,在头数组中找到节点i,在其后建立边表节点j。而反
过来,j与i也有关联,也需要在头数组中找到节点j,在其后建立边表节点i,如此
,才能建立一个无向图的邻接表。*/
/*!主函数略,此处仅给出邻接表的声明与建立邻接表的函数。!*/
}
}
bool visited[MAXVEX];
void DFS(GraphAdjList GL,int i){
EdgeNode *p;//边表结点temp变量
visited[i] = true;
cout<<GL.adjList[i].data;
p=GL.adjList[i].firstedge;
while(p){
if(!visited[p->adjvex]){
DFS(GL,p->adjvex);
}
p=p->next;
}
}
void DFSTraverse(GraphAdjList GL){
memset(visited,false,sizeof(visited));
for(int i=0;i<GL.numVertexe;i++){
if(!visited[i]){
DFS(GL,i);
}
}
}
int main()
{
GraphAdjList GL;
CreateALGraph(&GL);
DFSTraverse(GL);
return 0;
}