#include<iostream>
using namespace std;
#define MAXV 5 //矩阵长宽
#define INF 32767 //无穷
typedef struct ANode
{
int adjvex; //该边的邻接点编号
struct ANode* nextarc; //指向下一条边的指针
int weight; //该边的相关信息,如权值
}ArcNode; //边结点的类型
typedef struct Vnode
{
int info; //顶点的其他信息
ArcNode* firstarc; //指向第一个边结点
}VNode; //邻接表的头结点类型
typedef struct
{
VNode adjlist[MAXV]; //邻接表的头结点数组
int n, e; //n定点数,e边数
}AdjGraph; //完整的图邻接表类型
void CreateAdj(AdjGraph*& G, int A[MAXV][MAXV], int n, int e) //创建图的邻接表
{
int i, j; ArcNode* p; //i,j计数变量
G = (AdjGraph*)malloc(sizeof(AdjGraph)); //给G分配空间
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 (A[i][j] != 0 && A[i][j] != INF) //存在一条边
{
p = (ArcNode*)malloc(sizeof(ArcNode)); //创建一个节点p
p->adjvex = j; //存放邻接点
p->weight = A[i][j]; //存放权
p->nextarc = G->adjlist[i].firstarc; //采用头插法插入节点p
G->adjlist[i].firstarc = p;
}
G->n = n; G->e = e;
}
void DestroyAdj(AdjGraph*& G) { //销毁邻接表
int i; ArcNode* pre, * p;
for (i = 0; i < G->n; i++) { //扫描所有的单链表
pre = G->adjlist[i].firstarc; //p指向第i个单链表的头结点
if (pre != NULL) {
p = pre->nextarc;
while (p != NULL)
{
free(pre); //释放pre
pre = p; p = p->nextarc;
}
free(pre); //最后循环结束,释放pre
}
}
free(G); //释放邻接表指针
}
int A[MAXV][MAXV] = { {0,1,0,1,1},
{1,0,1,1,0},
{0,1,0,1,1},
{1,1,1,0,1},
{1,0,1,1,0} }; //我们的邻接矩阵数组
int visited[MAXV] = { 0 }; //深度优先遍历的全局变量
const int MaxSize = 20;
typedef struct {//队列的 顺序队结构
int data[MaxSize];//队列长度
int front, rear;//队头队尾下标注
}SqQueue;
void InitQueue(SqQueue*& q) {//初始化队列
q = (SqQueue*)malloc(sizeof(SqQueue));
q->front = q->rear = -1;
}
bool enQueue(SqQueue*& q, int e) {//进队列
if (q->rear == MaxSize - 1)
return false;
q->rear++;
q->data[q->rear] = e;
return true;
}
bool QueueEmpty(SqQueue*& q) {//判断队列是否为空
return(q->front == q->rear);
}
bool deQueue(SqQueue*& q, int& e) {//出队列
if (q->front == q->rear)
return false;
q->front++;
e = q->data[q->front];
return true;
}
void BFS(AdjGraph* G, int v)
{
int w, i; ArcNode* p;
SqQueue* qu; //定义环形队列指针
InitQueue(qu); //初始化队列
int visited[MAXV]; //定义定点访问标记数组
for (i = 0; i < G->n; i++)visited[i] = 0; //将数组都设为未访问状态0
cout<<v; //输出第一个被访问的结点编号
visited[v] = 1; //将其设置为已访问状态
enQueue(qu, v); //加入队列
while (!QueueEmpty(qu)) //如果队列不空则循环
{
deQueue(qu, w); //出队
p = G->adjlist[w].firstarc; //p为v的第一个邻接点
while (p != NULL) //如果p不空
{
if (visited[p->adjvex] == 0) //如果该点未被访问过
{
cout << p->adjvex; //输出该点的编号
visited[p->adjvex] = 1; //设置为已访问状态1
enQueue(qu, p->adjvex); //进队
}
p = p->nextarc;
}
}
cout << endl;
}
int main() {
AdjGraph* G = new AdjGraph; //邻接表指针
int n = 5;
int e = 8;
CreateAdj(G, A, n, e); //创建图的邻接表
cout << "广度优先遍历BFS:";
BFS(G, 4); //从编号为2的结点开始遍历
DestroyAdj(G); //释放图的邻接表
}
图的广度优先遍历
最新推荐文章于 2023-11-18 19:15:48 发布