实验的问题和要求:
建立图的邻接表存储结构,并将邻接表输出,对其进行深度优先遍历和广度优先遍历。
源程序及注释
#include<iostream>
using namespace std;
#define ERROR 0
#define OK 1
typedef int Status;
#define TRUE 1
#define FALSE 0
//图的邻接表存储表示
#define MVNum 100 //最大定点数
#define VertexType char
typedef struct ArcNode //边结点
{
int adjvex; //该弧所指向的顶点的位置
struct ArcNode *nextarc; //指向下一条弧的指针
}ArcNode;
typedef struct VNode {
VertexType data; //顶点信息
ArcNode *firstarc; //指向第一条依附该顶点的弧的指针
}VNode, AdjList[MVNum]; //邻接表类型:一维数组,用来分布不同顶点
typedef struct
{
AdjList vertices;
int vexnum, arcnum; //图的当前顶点数和弧数
}ALGraph;
//确定顶点的位置
Status LocateVex(ALGraph G, VertexType u)
{ /* 初始条件: 图G存在,u和G中顶点有相同特征 */
/* 操作结果: 若G中存在顶点u,则返回该顶点在图中位置;否则返回-1 */
int i;
for (i = 0; i < G.vexnum; ++i)
if (G.vertices[i].data == u)
return i;
return -1;
}
//邻接表创建无向图
Status CreateGraph(ALGraph &G)
{
int i, j, k;
VertexType va, vb;
ArcNode *p1, *p2;
cout << "请分别输入图的顶点数,边数: "<<endl;
cin >> G.vexnum >> G.arcnum;
cout << "请输入" << G.vexnum << "个顶点的值(字符型不加空格):"<<endl;
for (i = 0; i < G.vexnum; ++i) //输入各点,构造表头结点
{
cin >> G.vertices[i].data; //输入顶点值
G.vertices[i].firstarc = NULL; //初始化表头结点的指针域为NULL
}
cout << "请分别输入每条边的两个端点(以空格作为间隔): " << endl;
for (k = 0; k < G.arcnum; ++k) //输入各边,构造邻接表
{
cout << "请输入第" << k + 1 << "条边的信息:";
cin >> va >> vb;
i = LocateVex(G, va); //确定v1和v2在G中位值
j = LocateVex(G, vb);
p1 = new ArcNode; //生成一个新的边结点
p1->adjvex = j; //邻接点序号为j
p1->nextarc = G.vertices[i].firstarc; //插在第i表表头
G.vertices[i].firstarc = p1;
p2 = new(ArcNode);
p2->adjvex = i;
p2->nextarc = G.vertices[j].firstarc; //插在第j表表头
G.vertices[j].firstarc = p2;
}
return OK;
}
//输出图的邻接表
Status Display(ALGraph G)
{
int i;
ArcNode *p;
cout << G.vexnum << "个顶点:";
for (i = 0; i < G.vexnum; ++i)
cout << G.vertices[i].data << " ";
cout << endl;
cout << "邻接表为:" << endl;
for (i = 0; i < G.vexnum; i++)
{
p = G.vertices[i].firstarc;
cout << i << "|" << G.vertices[i].data;
while (p)
{
cout << "|->" << p->adjvex;
p = p->nextarc;
}
printf("|^\n");
}
return OK;
}
//深度优先遍历
bool visited[MVNum];
//访问标志数组,其初值为“false”
Status DFS_AL(ALGraph G, int v)
{
ArcNode *p;
int w;
cout << G.vertices[v].data << " ";
visited[v] = true; //访问第v个顶点
p = G.vertices[v].firstarc;
while (p) //依次检查邻接表
{
w = p->adjvex; //表示w是v的邻接点
if (!visited[w]) DFS_AL(G, w);
//如果w未访问,则递归调用DFS
p = p->nextarc; //p指向下一个边结点
}
return OK;
}
#define QElemType int
//队列的链式存储结构
typedef struct QNode
{
QElemType data;
struct QNode *next;
}QNode, *QueuePtr;
typedef struct
{
QueuePtr front; //队头指针
QueuePtr rear; //队尾指针
}LinkQueue;
//初始化
Status InitQueue(LinkQueue &Q)
{//构造一个空队列Q
Q.front = Q.rear = new QNode; //生成新结点作为头结点,队头和队尾指针指向此结点
Q.front->next = NULL; //头结点的指针域置空
return OK;
}
//入队
Status EnQueue(LinkQueue &Q, QElemType e)
{//插入元素e为Q的新的队尾元素
QueuePtr p = new QNode; //为入队元素分配结点空间,用指针p指向
p->data = e; //将新结点数据域置为e
p->next = NULL; Q.rear->next = p; //将新结点插入到队尾
Q.rear = p; //修改队尾指针
return OK;
}
//判断队列是否为空
Status QueueEmpty(LinkQueue Q) {
//判断队列为空
if (Q.front == Q.rear)
return(true);
else
return(false);
}
//出队
Status DeQueue(LinkQueue &Q, QElemType &e)
{//删除Q的队头元素, 用e返回其值
if (Q.front == Q.rear) return ERROR; //若队列空, 则返回ERROR
QueuePtr p = Q.front->next; //p指向队头元素
e = p->data; //e保存队头元素的值
Q.front->next = p->next; //修改头指针
if (Q.rear == p) //最后一个元素被删, 队尾指针指向头结点
{
Q.rear = Q.front;
}
delete p; //释放原队头元素的空间
return OK;
}
//广度优先遍历
void BFS_AL(ALGraph G, int v)
{
int u, w;
LinkQueue Q;
ArcNode *p;
cout << G.vertices[v].data << " ";
visited[v] = true; //访问第v个顶点
InitQueue(Q);
EnQueue(Q, v);
while (!QueueEmpty(Q))
{
DeQueue(Q, u);
p = G.vertices[u].firstarc;
while (p) //依次检查邻接表
{
w = p->adjvex; //表示w是v的邻接点
if (!visited[w])
{
cout << G.vertices[w].data << " "; visited[w] = true;
EnQueue(Q, w);
}
p = p->nextarc; //p指向下一个边结点
}//while
} //while
} //BFS
void BFSTraverse(ALGraph G) {
int v;
for (v = 0; v < G.vexnum; ++v)
visited[v] = false;
for (v = 0; v < G.vexnum; ++v)
if (!visited[v]) BFS_AL(G, v);
//对尚未访问的顶点调用BFS
}//BFSTraverse
Status DFSTraverse(ALGraph G) {
int v;
for (v = 0; v < G.vexnum; ++v)
visited[v] = false;
for (v = 0; v < G.vexnum; ++v)
if (!visited[v]) DFS_AL(G, v);
//对尚未访问的顶点调用DFS
return OK;
}
Status main()
{
ALGraph G;
//邻接表创建无向图
CreateGraph(G);
//输出图的邻接表
cout << "输出的邻接表为:" << endl;
Display(G);
//深度优先遍历
cout << "深度优先遍历序列为:" << endl;
DFSTraverse(G);
cout << endl;
//广度优先遍历
cout << "广度优先遍历序列为:" << endl;
BFSTraverse(G);
cout << endl;
system("pause");
return OK;
}
运行结果