由于非连通图的深度优先遍历比起连通图的深度优先遍历思路完全一样,只是非连通图多了一个检测是否所有元素都已经遍历的函数,故不再写连通图的深度优先遍历算法,需要的直接把下面代码的DFSTraverse()函数删除就行(其实不删除也可以遍历连通图啊)。
先是预定义和类型定义:
#define OK 1
#define ERROR 0
#define MAXSIZE 100
typedef int Status;
typedef int OtherInfo;
typedef char VerTexType;
typedef struct ArcNode{
int adjvex;
ArcNode *nextarc;
OtherInfo info;
}ArcNode;
typedef struct VNode{
VerTexType data;
ArcNode *firstarc;
}VNode,AdjList[MAXSIZE];
typedef struct{
AdjList vertices;
int vexnum, arcnum;
}ALGraph;
声明一个bool类型的数组,记录节点是否已经被访问:
bool visited[MAXSIZE];
创建图:
int Locate(ALGraph *G, VerTexType v)
{
int i;
for (i = 0; i < G->vexnum; i++)
{
if (G->vertices[i].data == v)
return i;
}
}
Status CreateUDG(ALGraph *G)
{
int i, j, k;
ArcNode *p1, *p2;
VerTexType v1, v2;
printf("输入总节点数和总边数:");
scanf("%d %d", &G->vexnum, &G->arcnum);
printf("输入各个节点的值:");
fflush(stdin);
for (i = 0; i < G->vexnum; i++)
{
scanf("%c", &G->vertices[i].data);
G->vertices[i].firstarc = NULL;
visited[i] = false;
}
for (k = 0; k < G->arcnum; k++)
{
printf("输入一条边的两个顶点的值:");
fflush(stdin);
scanf("%c %c", &v1, &v2);
i = Locate(G, v1);
j = Locate(G, v2);
p1 = (ArcNode *)malloc(sizeof(ArcNode));
p1->adjvex = j;
p1->nextarc = G->vertices[i].firstarc;
G->vertices[i].firstarc = p1;
p2 = (ArcNode *)malloc(sizeof(ArcNode));
p2->adjvex = i;
p2->nextarc = G->vertices[j].firstarc;
G->vertices[j].firstarc = p2;
}
return OK;
}
这和之前创建图的算法一样,只不过在初始化的时候加入了对数组visited[]的初始化。
深度优先算法:
void DFS(ALGraph G,int v)
{
ArcNode *p;
printf("%c ", G.vertices[v].data);
visited[v] = true;
for (p = G.vertices[v].firstarc; p; p = p->nextarc)
{
if (!visited[p->adjvex])
DFS(G, p->adjvex);
}
}
先输出遍历到的元素,并在visited[]数组中标记为已经遍历。之后的for循环用于对与其有联系节点的遍历:让指针p指向刚刚遍历过节点的第一条边,如果p不为空指针,则判断该边的另一个节点是否遍历,如果尚未遍历,则引用DFS()函数进行遍历。结束后让p指向下一条边。
非连通图的深度优先算法:
void DFSTraverse(ALGraph G)
{
int i;
for (i = 0; i < G.vexnum; i++)
{
if (!visited[i])
DFS(G, i);
}
}
依次检测第i个元素是否已经遍历,如果没有遍历过,则对其遍历。
加入main():
int main(void)
{
ALGraph G;
CreateUDG(&G);
DFSTraverse(G);
printf("\n");
return 0;
}