以清华大学《计算机软件技术基础》习题2.34为例。
题目如下:
深度优先搜索的主要部分代码如下:
//用邻接表结构进行深度优先搜索
typedef int Boolean; //定义布尔类型,用于标记点是否被访问
Boolean visited[MAXVEX]; //标记已访问的点
//算法
void DFS(GraphList *GL,int i) //从下标为i的顶点开始搜索
{
EdgeNode *p;
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(GraphList *GL)
{
int i;
//对所有顶点状态初始化
for (i=0;i<GL->numV;i++)
visited[i] = false;
for(i=0;i<GL->numV;i++)
{
if(!visited[i])
DFS(GL,i);
}
}
广度优先搜索的主要部分代码如下:(其中用到的队的结构及算法见完整代码)
//广度优先搜索主体部分
void BFSTraverse(GraphList *GL)
{
typedef int Boolean; //定义布尔类型,用于标记点是否被访问
Boolean visited[MAXVEX]; //标记已访问的点
int i;
EdgeNode *p;
LinkQ *Q;
//对所有顶点状态初始化
for (i=0;i<GL->numV;i++)
visited[i] = false;
Q = new LinkQ ;
InitQueue(Q);
for (i=0;i<GL->numV;i++)
{
if (!visited[i])
{
visited[i]=true;
cout<<GL->adjlist[i].data<<" "; //输出已访问的点
EnQueue(Q,i);
while(Q->rear != Q->front)
{
DeQueue(Q,i);
p = GL->adjlist[i].firstedge;
while(!p)
{
if (!visited[p->adjvex]) //若该点没有被访问
{
cout<<GL->adjlist[p->adjvex].data<<" "; //则输出该顶点
visited[p->adjvex] = true;
EnQueue(Q,p->adjvex); //并将该顶点的下标入队
}
p = p->next;
}
}
}
}
}
整道题完整代码如下:
(其中包括无向图的邻接矩阵、邻接表的创建,队结构和队的部分算法创建,深度优先、广度优先算法)
#include <iostream>
#include <stdlib.h>
using namespace std;
typedef int Vtype; //定义顶点类型
#define MAXVEX 20 //最大顶点个数
//定义图结构
struct MGraph
{
Vtype v[MAXVEX]; //顶点表
int arr[MAXVEX][MAXVEX]; //邻接矩阵
int numV,numE; //图中当前顶点数和边数
};
//定义边表结点
struct EdgeNode
{
Vtype adjvex; //邻接点的下标
EdgeNode *next; //指向下一个邻接点
};
//定义顶点表结点
struct VertexNode
{
Vtype data; //顶点信息
EdgeNode *firstedge; //边表的头指针
};
struct GraphList
{
VertexNode adjlist[MAXVEX];
int numV,numE; //图中当前顶点数和边数
};
//同时建立无向图的邻接矩阵和邻接表
void CreatGraph(MGraph *G,GraphList *GL)
{
int i,j,k;
EdgeNode *p;
cout<<"输入顶点数和边数\n";
cin>>G->numV>>G->numE;
GL->numV = G->numV;
GL->numE = G->numE;
cout<<"输入顶点信息\n";
for(i = 0;i < G->numV;i++)
{
cin>>G->v[i];
GL->adjlist[i].data = G->v[i];
GL->adjlist[i].firstedge = NULL;
}
//邻接矩阵初始化
for(i = 0;i < G->numV;i++)
{
for(j = 0;j < G->numV;j++)
G->arr[i][j] = 0;
}
//创建邻接矩阵和邻接表
for(k = 0;k < G->numE;k++)
{
cout<<"输入边对应两顶点的下标(注意是下标不是信息!)\n";
cin>>i>>j;
G->arr[i][j] = 1;
G->arr[j][i] = 1;
p = new EdgeNode;
p->adjvex = j;
p->next = GL->adjlist[i].firstedge;
GL->adjlist[i].firstedge = p;
p = new EdgeNode;
p->adjvex = i;
p->next = GL->adjlist[j].firstedge;
GL->adjlist[j].firstedge = p;
}
//打印邻接表和邻接矩阵
cout<<"邻接矩阵为:\n";
for(i=0;i<G->numV;i++)
{
for(j=0;j<G->numV;j++)
cout<<G->arr[i][j]<<" ";
cout<<"\n";
}
cout<<"邻接表为:\n";
for(i=0;i<GL->numV;i++)
{
p=GL->adjlist[i].firstedge;
cout<<GL->adjlist[i].data;
while(p)
{
cout<<"->"<<GL->adjlist[p->adjvex].data;
p=p->next;
}
cout<<"\n";
}
}
//用邻接表结构进行深度优先搜索
typedef int Boolean; //定义布尔类型,用于标记点是否被访问
Boolean visited[MAXVEX]; //标记已访问的点
//算法
void DFS(GraphList *GL,int i) //从下标为i的顶点开始搜索
{
EdgeNode *p;
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(GraphList *GL)
{
int i;
//对所有顶点状态初始化
for (i=0;i<GL->numV;i++)
visited[i] = false;
for(i=0;i<GL->numV;i++)
{
if(!visited[i])
DFS(GL,i);
}
}
//用邻接表结构进行广度优先搜索
//创建链队列的结构
struct QNode //结点结构
{
int num; // 顶点下标
QNode *next;
};
struct LinkQ //队列的链表结构
{
QNode *front,*rear; //队头队尾指针
};
//队列初始化操作
void InitQueue(LinkQ *Q)
{
Q->front = new QNode ; //建立头结点
Q->front->next = NULL;
Q->rear = Q->front; //初始为空
}
//入队操作
int EnQueue(LinkQ *Q,int e) //插入元素e为Q的新的队尾元素
{
QNode *s;
s = new QNode;
s->num = e;
s->next = NULL;
Q->rear->next = s;
Q->rear = s;
return 1;
}
//出队操作
int DeQueue(LinkQ *Q,int e) //若队列不空,删除Q的队头元素,用e返回其值,并返回1,否则返回0
{
QNode *p;
if(Q->front == Q->rear)
return 0;
p = Q->front->next; //注意队列中第一个结点是没有储存编号的
e = p->num;
Q->front->next = p->next;
if(Q->rear==p)
Q->rear = Q->front;
free(p);
return 1;
}
//广度优先搜索主体部分
void BFSTraverse(GraphList *GL)
{
typedef int Boolean; //定义布尔类型,用于标记点是否被访问
Boolean visited[MAXVEX]; //标记已访问的点
int i;
EdgeNode *p;
LinkQ *Q;
//对所有顶点状态初始化
for (i=0;i<GL->numV;i++)
visited[i] = false;
Q = new LinkQ ;
InitQueue(Q);
for (i=0;i<GL->numV;i++)
{
if (!visited[i])
{
visited[i]=true;
cout<<GL->adjlist[i].data<<" "; //输出已访问的点
EnQueue(Q,i);
while(Q->rear != Q->front)
{
DeQueue(Q,i);
p = GL->adjlist[i].firstedge;
while(!p)
{
if (!visited[p->adjvex]) //若该点没有被访问
{
cout<<GL->adjlist[p->adjvex].data<<" "; //则输出该顶点
visited[p->adjvex] = true;
EnQueue(Q,p->adjvex); //并将该顶点的下标入队
}
p = p->next;
}
}
}
}
}
int main()
{
MGraph *G;
GraphList *GL;
G = new MGraph;
GL = new GraphList;
CreatGraph(G,GL); //输出邻接矩阵和邻接表
cout<<"深度优先搜索结果为:";
DFSTraverse (GL);
cout<<"\n广度优先搜索结果为:";
BFSTraverse(GL);
system("pause");
return 0;
}
输出的结果如下: