紧接着上一个博客,补上了广度优先遍历
//数据结构之图的存储结构,初始化,遍历,应用
#include<iostream>
#include <stdlib.h>
#include<string>
#include<stdio.h>
using namespace std;
#define VertexType char//顶点类型
//存储结构
#define MaxSize 100//顶点数目最大值
typedef struct ArcNode {//边表结点存储结构
int adjvex;//adj是邻接的意思,该弧所指向的顶点的位置,即顶点数组的位置
ArcNode *next;//指向下一个边的指针
}ArcNode;
typedef struct VNode {//顶点表结点及邻接表存储结构
VertexType data;//定点类型
ArcNode *firstedge;//第一个边结点的指针
}Vnode,AdjList[MaxSize];//AdjList即邻接表
typedef struct {//图的存储结构
AdjList adjlist1;//一个图对应着一个邻接表存储
int vexnum, arcnum;//图的结点个数和边的个数,在遍历和应用的时候会用到
}Graph;
#define quedata int
typedef struct quenode
{
quedata data;
quenode* next;
}quenode;
typedef struct queque
{
quenode* head;
quenode* tail;
}queue;
void _init(queue &Q)
{
//Q.head = NULL;
Q.head = (quenode*)malloc(sizeof(quenode));
Q.tail = Q.head;
}
bool _empty(queue Q)
{
if (Q.head == Q.tail)return true;
else
return false;
}
void qpush(queue &Q, quedata e)
{
quenode* s;
s = (quenode*)malloc(sizeof(quenode));
s->data = e;
s->next = NULL;
Q.tail->next = s;
Q.tail = s;
}
bool qpop(queue &Q, quedata &v)
{
if (Q.head == Q.tail)return false;
quenode* s;
s = (quenode*)malloc(sizeof(quenode));
s = Q.head->next;
v= s->data;
Q.head->next = s->next;
if (Q.tail == s)Q.tail = Q.head;
free(s);
}
//初始化
void graph_init(Graph &g)//这里用一个实例图
// A
// / | \
// / | \
// / | \
// B D----C-----G
// | |
// E F
//
{
g.arcnum = 7;
g.vexnum = 7;
g.adjlist1[0].data = 'A';
g.adjlist1[1].data = 'B';
g.adjlist1[2].data = 'C';
g.adjlist1[3].data = 'D';
g.adjlist1[4].data = 'E';
g.adjlist1[5].data = 'F';
g.adjlist1[6].data = 'G';
ArcNode *p;
{//这个初始化看着麻烦但是代码都是可以重用的,而且应该能改成循环手动输入
p = (ArcNode*)malloc(sizeof(ArcNode)); p->next = NULL;
p->adjvex = 1;
g.adjlist1[0].firstedge = p;
p = (ArcNode*)malloc(sizeof(ArcNode)); p->next = NULL;
p->adjvex = 2;
g.adjlist1[0].firstedge->next = p;
p = (ArcNode*)malloc(sizeof(ArcNode)); p->next = NULL;
p->adjvex = 3;
g.adjlist1[0].firstedge->next->next = p;
//p->next = NULL;
//adjlist1[0],下面以此类推.代码重用,改一些数值即可
//A
}
{
//B
p = (ArcNode*)malloc(sizeof(ArcNode)); p->next = NULL;
p->adjvex = 0;
g.adjlist1[1].firstedge = p;
p = (ArcNode*)malloc(sizeof(ArcNode)); p->next = NULL;
p->adjvex = 4;
g.adjlist1[1].firstedge->next = p;
}
{
//C
p = (ArcNode*)malloc(sizeof(ArcNode)); p->next = NULL;
p->adjvex = 0;
g.adjlist1[2].firstedge = p;
p = (ArcNode*)malloc(sizeof(ArcNode)); p->next = NULL;
p->adjvex = 3;
g.adjlist1[2].firstedge->next = p;
p = (ArcNode*)malloc(sizeof(ArcNode)); p->next = NULL;
p->adjvex = 5;
g.adjlist1[2].firstedge->next->next = p;
p = (ArcNode*)malloc(sizeof(ArcNode)); p->next = NULL;
p->adjvex = 6;
g.adjlist1[2].firstedge->next->next->next = p;
}
{
//D
p = (ArcNode*)malloc(sizeof(ArcNode)); p->next = NULL;
p->adjvex = 0;
g.adjlist1[3].firstedge = p;
p = (ArcNode*)malloc(sizeof(ArcNode)); p->next = NULL;
p->adjvex = 2;
g.adjlist1[3].firstedge->next = p;
}
{//E
p = (ArcNode*)malloc(sizeof(ArcNode)); p->next = NULL;
p->adjvex = 1;
g.adjlist1[4].firstedge = p;
}
{//F
p = (ArcNode*)malloc(sizeof(ArcNode)); p->next = NULL;
p->adjvex = 2;
g.adjlist1[5].firstedge = p;
}
{//G
p = (ArcNode*)malloc(sizeof(ArcNode)); p->next = NULL;
p->adjvex = 2;
g.adjlist1[6].firstedge = p;
}
}
void visit(int v,Graph g)
{
cout << g.adjlist1[v].data;
}
//BFS,即广度优先遍历
bool visited[MaxSize];
void initvisit(Graph g)//图g的判定数组初始化false
{
for (int i = 0; i < g.vexnum; i++)
{
visited[i] = false;
}
}
void BFS(Graph g, int v)
{
queue Q;//定义一个工作队列
ArcNode *p;//工作指针
_init(Q);//队列初始化
visit(v,g);//访问v下标的结点
visited[v] = true;//访问后置正
qpush(Q, v);//访问后入队列
while (!_empty(Q))
{
qpop(Q,v);//弹出队首,记录队首结点的下标数
p = g.adjlist1[v].firstedge;//该下标数对应的边表开始循环访问
while (p)
{
if (!visited[p->adjvex])//该节点没访问过的话就访问,然后入队列
{//访问过了的话就下一个
visit(p->adjvex,g);
visited[p->adjvex] = true;
qpush(Q, p->adjvex);
}
p = p->next;
//直到这个下标对应节点的边表访问结束后
}
//继续弹出队首这样循环往复直到所有遍历完成
}
}
//DFS,即深度优先遍历
void DFS(Graph g, int v)
{
ArcNode *p;//工作指针
visit(v,g);//访问该点结点
visited[v] = true;//判定数组置为正
p = g.adjlist1[v].firstedge;//该点结点的头指针赋值给工作指针
while (p != NULL) {
if (!visited[p->adjvex]) {//访问了就下一个,没访问就以这个点继续递归
DFS(g, p->adjvex);
}
p = p->next;
}
}
int main()
{
Graph g;
graph_init(g);
initvisit(g);
// A
// / | \
// / | \
// / | \
// B D----C-----G
// | |
// E F
//
string A1 = " A";
string A2 = " / | \\";
string A3 = " / | \\";
string A4 = " / | \\";
string A5 = " B D----C-----G";
string A6 = " | |";
string A7 = " E F";
cout << "初始化图为:" << endl;
cout << A1 << endl;
cout << A2 << endl;
cout << A3 << endl;
cout << A4 << endl;
cout << A5 << endl;
cout << A6 << endl;
cout << A7 << endl;
cout << "注意ABCDEFG分别对应下标0123456\n" << endl;
cout << "邻接表为:" << endl;
for (int i = 0; i < g.vexnum; i++)
{
cout << g.adjlist1[i].data << "|firstedge->";
ArcNode *p;
p = g.adjlist1[i].firstedge;
while (p != NULL)
{
cout << p->adjvex << "|next->";
p = p->next;
}
cout << "NULL\n";
}
cout << "深度遍历输出为:" << endl;
DFS(g, 0);
cout << endl;
initvisit(g);
cout << "广度遍历输出为:" << endl;
BFS(g, 0);
cout << endl;
}