图的邻接表存储结构

实验的问题和要求:

建立图的邻接表存储结构,并将邻接表输出对其进行深度优先遍历和广度优先遍历

源程序及注释

#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;

}

运行结果

 

  • 3
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

亦悰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值