对于一个有向图或者无向图,我们想要对这个表进行遍历,我们该怎样做呢?
第一想到的是,找到哪里算哪里?
这里,给出第一种基本的搜索方式,即深度优先的搜索方式。
如下图所示:
共有ABCDEF六个顶点,十条边。
如果我们想要遍历四个顶点,该怎么做呢?
注意到,我们有多种情况,可以是abdc也可以是acdb又或者是abcd等等等。
而深度优先搜索则是尽可能的优先往深的地方遍历。
#include<stdio.h>
#include<malloc.h>
#define MAX 100
typedef struct ArcNode{//邻接表单元
int adjvex; //adjvex代表该单元所指顶点的序号。
struct ArcNode *nextarc;
}ArcNode;
typedef struct VNode{ //邻接表表头
char vertex; //表头顶点
ArcNode *firstarc; //表头所指的第一个单元,也就是一个边。
}VNode;
typedef VNode AdjList[MAX]; //邻接表
typedef struct ALGraph{
AdjList adjlist;
int vexnum,arcnum;
}ALGraph;
int LocateVerTex(ALGraph *G,int v) //查找顶点v在邻接表中的索引位置。
{
int k;
for(k=0;k<G->vexnum;k++)
if(v == G->adjlist[k].vertex)
return k;
return -1;
}
void CreateALGraph(ALGraph *G)
{
int i,j,k,weight;
char v1,v2;
ArcNode *tmp;
printf("请输入顶点数和边数:\n");
scanf("%d %d",&(G->vexnum),&(G->arcnum));
getchar();
printf("请输入{%d}个顶点:\n",G->vexnum);
for(i=0;i<G->vexnum;i++){
scanf("%c",&(G->adjlist[i]));
G->adjlist[i].firstarc = NULL;
}
getchar();
printf("请输入{%d}条边,格式{v1 v2 权重}\n",G->arcnum);
for(k=0;k<G->arcnum;k++){
scanf("%c %c %d",&v1,&v2,&weight);
getchar();
i = LocateVerTex(G,v1);
j = LocateVerTex(G,v2);
if(i==-1||j==-1){
printf("失败.\n");
k = k - 1;
continue;
}
else{
tmp = (ArcNode*)malloc(sizeof(ArcNode));
tmp->adjvex = j;
tmp->nextarc = G->adjlist[i].firstarc; //头插法
G->adjlist[i].firstarc = tmp; //给i这个下标顶点操作,和j是一条边。
printf("成功.\n");
}
}
}
void DFS(ALGraph *G,int v,int *visit) //DFS后继搜索函数
{
int adj;
ArcNode *p;
printf("访问顶点:{%c}\n",G->adjlist[v].vertex);
visit[v] = 1; //令该顶点在搜索数组中置1,代表已经被访问。
p = G->adjlist[v].firstarc;
while(p){
adj = p->adjvex;
if(visit[adj] == 0) //如果邻接表当前边的下一个边未被搜索过。
DFS(G,adj,visit);
p = p->nextarc;
}
}
void DFSTraverse(ALGraph *G) //深度优先搜索
{
int v;
int visit[G->vexnum]; //设立搜索数组,如果该节点索引被搜索过置1,否则为0.
for(v=0;v<G->vexnum;v++) //初始化搜索数组。
visit[v] = 0;
for(v=0;v<G->vexnum;v++){
if(visit[v] == 0)
DFS(G,v,visit); //执行DFS后继搜索函数。
}
}
int main()
{
ALGraph G;
CreateALGraph(&G);
DFSTraverse(&G);
return 0;
}
运行结果如下所示: