例题:
编写一个程序,实现图的邻接表相关运算,并在此基础上设计一个主程序实现如下功能:
(1)建立图G 的邻接矩阵,并且将之转化为邻接表输出
(2)输出有向图G从顶点0开始的深度优先搜索遍历序列
(3)输出有向图G从顶点0开始的广度优先搜索遍历序列
//graph.h
typedef int InfoType;
#define MAXV100 /*最大顶点个数*/
/*以下定义邻接矩阵类型*/
typedef struct
{ int no; /*顶点编号*/
InfoTypeinfo; /*顶点其他信息*/
} VertexType; /*顶点类型*/
typedef struct /*图的定义*/
{ int edges[MAXV][MAXV]; /*邻接矩阵*/
int vexnum,arcnum; /*顶点数,弧数*/
VertexTypevexs[MAXV]; /*存放顶点信息*/
} MGraph; /*图的邻接矩阵类型*/
/*以下定义邻接表类型*/
typedef struct ANode /*弧的结点结构类型*/
{ intadjvex; /*该弧的终点位置*/
struct ANode *nextarc; /*指向下一条弧的指针*/
InfoType info; /*该弧的相关信息,这里用于存放权值*/
} ArcNode;
typedef int Vertex;
typedef struct Vnode /*邻接表头结点的类型*/
{ Vertexdata; /*顶点信息*/
ArcNode *firstarc; /*指向第一条弧*/
} VNode;
typedef VNode AdjList[MAXV]; /*AdjList是邻接表类型*/
typedef struct
{ AdjListadjlist; /*邻接表*/
int n,e; /*图中顶点数n和边数e*/
} ALGraph; /*图的邻接表类型*/
/*文件名:algo12-1-1.cpp*/
#include <stdio.h>
#include <malloc.h>
#include "graph.h"
#define INF 32767 /*INF表示∞*/
void MatToList(MGraph g,ALGraph *&G)
/*将邻接矩阵g转换成邻接表G*/
{
inti,j,n=g.vexnum; /*n为顶点数*/
ArcNode*p;
G=(ALGraph*)malloc(sizeof(ALGraph));
for(i=0;i<n;i++) /*给邻接表中所有头结点的指针域置初值*/
G->adjlist[i].firstarc=NULL;
for(i=0;i<n;i++) /*检查邻接矩阵中每个元素*/
for(j=n-1;j>=0;j--)
if(g.edges[i][j]!=0) /*邻接矩阵的当前元素不为0*/
{
p=(ArcNode*)malloc(sizeof(ArcNode)); /*创建一个结点*p*/
p->adjvex=j;
p->info=g.edges[i][j];
p->nextarc=G->adjlist[i].firstarc; /*将*p链到链表后*/
G->adjlist[i].firstarc=p;
}
G->n=n;G->e=g.arcnum;
}
void ListToMat(ALGraph *G,MGraph &g)
/*将邻接表G转换成邻接矩阵g*/
{
inti,j,n=G->n;
ArcNode*p;
for(i=0;i<n;i++) /*g.edges[i][j]赋初值0*/
for(j=0;j<n;j++)
g.edges[i][j]=0;
for(i=0;i<n;i++)
{
p=G->adjlist[i].firstarc;
while (p!=NULL)
{
g.edges[i][p->adjvex]=p->info;
p=p->nextarc;
}
}
g.vexnum=n;g.arcnum=G->e;
}
void DispMat(MGraph g)
/*输出邻接矩阵g*/
{
inti,j;
for(i=0;i<g.vexnum;i++)
{
for(j=0;j<g.vexnum;j++)
if(g.edges[i][j]==INF)
printf("%3s","∞");
else
printf("%3d",g.edges[i][j]);
printf("\n");
}
}
void DispAdj(ALGraph *G)
/*输出邻接表G*/
{
inti;
ArcNode*p;
for(i=0;i<G->n;i++)
{
p=G->adjlist[i].firstarc;
if(p!=NULL) printf("%3d: ",i);
while(p!=NULL)
{
printf("%3d",p->adjvex);
p=p->nextarc;
}
printf("\n");
}
}
/*文件名:algo12-1-2.cpp*/
#include <stdio.h>
#include <malloc.h>
#include "graph.h"
int visited[MAXV]; /*全局数组*/
void DFS(ALGraph *G,int v)
{
ArcNode*p;
visited[v]=1; /*置已访问标记*/
printf("%3d",v); /*输出被访问顶点的编号*/
p=G->adjlist[v].firstarc; /*p指向顶点v的第一条弧的弧头结点*/
while(p!=NULL)
{
if(visited[p->adjvex]==0) /*若p->adjvex顶点未访问,递归访问它*/
DFS(G,p->adjvex);
p=p->nextarc; /*p指向顶点v的下一条弧的弧头结点*/
}
}
void DFS1(ALGraph *G,int v)
{
inti,visited[MAXV],St[MAXV],top=-1;
ArcNode*p;
for (i=0;i<G->n;i++)
visited[i]=0; /*结点访问标志均置成0*/
printf("%3d",v); /*访问顶点v*/
top++; /*v入栈*/
St[top]=v;
visited[v]=1;
while(top>=-1) /*栈不空时循环*/
{
v=St[top];top--; /*取栈顶顶点*/
p=G->adjlist[v].firstarc;
while (p!=NULL && visited[p->adjvex]==1)
p=p->nextarc;
if (p==NULL) /*若没有退到前一个*/
top--;
else /*若有,选择一个*/
{
v=p->adjvex;
printf("%3d",v); /*访问顶点*/
visited[v]=1;
top++; /*入栈*/
St[top]=v;
}
}
printf("\n");
}
void BFS(ALGraph *G,int v)
{
ArcNode*p;
intqueue[MAXV],front=0,rear=0; /*定义循环队列并初始化*/
intvisited[MAXV]; /*定义存放结点的访问标志的数组*/
intw,i;
for(i=0;i<G->n;i++) visited[i]=0; /*访问标志数组初始化*/
printf("%3d",v); /*输出被访问顶点的编号*/
visited[v]=1; /*置已访问标记*/
rear=(rear+1)%MAXV;
queue[rear]=v; /*v进队*/
while(front!=rear) /*若队列不空时循环*/
{
front=(front+1)%MAXV;
w=queue[front]; /*出队并赋给w*/
p=G->adjlist[w].firstarc; /*找与顶点w邻接的第一个顶点*/
while(p!=NULL)
{
if(visited[p->adjvex]==0) /*若当前邻接顶点未被访问*/
{
printf("%3d",p->adjvex); /*访问相邻顶点*/
visited[p->adjvex]=1; /*置该顶点已被访问的标志*/
rear=(rear+1)%MAXV; /*该顶点进队*/
queue[rear]=p->adjvex;
}
p=p->nextarc; /*找下一个邻接顶点*/
}
}
printf("\n");
}
/*文件名:exp12-1.cpp*/
#include <stdio.h>
#include <malloc.h>
#include "graph.h"
extern void MatToList(MGraph,ALGraph *&);
extern void DispAdj(ALGraph *G);
extern void DFS(ALGraph *G,int v);
extern void DFS1(ALGraph *G,int v);
extern void BFS(ALGraph *G,int v);
void main()
{
inti,j;
MGraphg;
ALGraph*G;
intA[MAXV][6]={
{0,5,0,7,0,0},
{0,0,4,0,0,0},
{8,0,0,0,0,9},
{0,0,5,0,0,6},
{0,0,0,5,0,0},
{3,0,0,0,1,0}};
g.vexnum=6;g.arcnum=10;
for(i=0;i<g.vexnum;i++)
for(j=0;j<g.vexnum;j++)
g.edges[i][j]=A[i][j];
G=(ALGraph*)malloc(sizeof(ALGraph));
MatToList(g,G); /*图G的邻接矩阵转换成邻接表*/
printf("图G的邻接表:\n");
DispAdj(G);
printf("从顶点0开始的DFS(递归算法):\n");
DFS(G,0);printf("\n");
printf("从顶点0开始的DFS(非递归算法):\n");
DFS1(G,0);
printf("从顶点0开始的BFS(递归算法):\n");
BFS(G,0);printf("\n");
}