#include<iostream>
using namespace std;
#define VNum 100 //图的最大顶点数
#define NullGraph 0 //图之间没有连线
#define QMaxsize 100 //队列最大长度
typedef int ElemType; //结点数据类型
typedef char VElemType; //结点名称
typedef struct Graph //图的结构体
{
int vex, arc; //vex是点个数,arc是边条数
ElemType Gra[VNum][VNum]; //存储结点的连线
VElemType Vex[VNum]; //存储结点名称
}Graph;
typedef struct Queue//队列的结构体
{
ElemType *base; //基地址,用来申请空间
int front, rear;//front队首指针,rear队尾指针
}Queue;
int InitQueue(Queue &Q)//初始化队列
{
Q.base = new ElemType[QMaxsize];
if (Q.base == NULL) return 0;//没申请到空间,return 0
Q.front = Q.rear = 0;
return 1;// 初始化成功,return 1
}
int EnQueue(Queue &Q, ElemType e)//入队列
{
if ((Q.rear + 1) % QMaxsize == Q.front)//队列满,return 0
return 0;
Q.base[Q.rear] = e;
Q.rear = (Q.rear + 1) % QMaxsize;
return 1;//入队列成功,return1
}
int DeQueue(Queue &Q,ElemType &e)//出队列
{
if (Q.rear == Q.front) return 0;//队空
e = Q.base[Q.front];
Q.front = (Q.front + 1) % QMaxsize;
return 1;//出队成功
}
ElemType GetHead(Queue Q)//取队头元素
{
if (Q.rear != Q.front) return Q.base[Q.front];
}
int IsEmpty(Queue Q)//判断队列是否为空
{
if (Q.rear == Q.front) return 0;//队空
else return 1;
}
int LocationVex(Graph G, VElemType v)//找到结点v的位置
{
for (int i = 0; i < G.vex; i++)
{
if (v == G.Vex[i]) return i;
}
}
int FirstAdj(Graph G,int v)//找到v的第一个邻接点
{
int i;
for (i=0; i < G.vex; i++)
if (G.Gra[v][i] != 0)
{
return i; break;
}
}
int NextAdj(Graph G,int v,int j)//找到第一个之后邻接点,j是上一个邻接点
{
bool tmp = true;
for (int i = j+1; i < G.vex; i++)
{
if (G.Gra[v][i] != 0)
{
tmp = false;
return i; break;
}
}
if(tmp) return -1;//如果没有邻接点,return -1
}
bool vis[VNum]; //初始化访问标志为false
/*void DepthFirstSearch(Graph G, int v)//深度优先遍历,从第v个结点出发开始
{
cout << G.Vex[v];vis[v] = true;//访问v结点
for (int w = 0; w < G.vex; w++)
{
if ((G.Gra[v][w] != 0) && (!vis[w]))
DepthFirstSearch(G, w);
}
}*/
void DepthFirstSearch(Graph G, int v)//深度优先遍历,从第v个结点出发开始
{
cout << G.Vex[v]; vis[v] = true;//访问v结点
int w = 0;
for (w = FirstAdj(G, v); w >= 0; w = NextAdj(G, v, w))
{
if (!vis[w])
{
DepthFirstSearch(G, w);
}
}
}
bool vis1[VNum]; //初始化访问标志为false
void BroadFirstSearch(Graph G, int v)//广度优先遍历,从第v个结点出发开始
{
cout << G.Vex[v]; vis1[v] = true;
Queue Q;
InitQueue(Q);
EnQueue(Q, v);
int w = 0;
while (IsEmpty(Q))//队列非空时
{
int u;
DeQueue(Q,u);
for (w = FirstAdj(G, u); w >= 0; w = NextAdj(G, u, w))
{
if (!vis1[w])
{
cout << G.Vex[w];
vis1[w] = true;
EnQueue(Q, w);
}
}
}
}
void CreateGraph(Graph &G)//根据输入创建图,0代表没连线,1代表有连线
{
cout << "请依次输入结点数和边数:";
cin >> G.vex>>G.arc; //输入结点数和边数
for (int i = 0; i < G.vex; i++) //初始化为空
for (int j = 0; j < G.vex; j++)
G.Gra[i][j] = NullGraph;
cout << "请依次输入结点名称:";
for (int i = 0; i < G.vex; i++)//输入结点的名称
{
cin >> G.Vex[i];
}
VElemType v1, v2;
for (int k = 0; k < G.arc; k++)
{
cout << "第" << k + 1<<"条边的对应结点:";
cin >> v1>>v2;
int i = LocationVex(G, v1); //i获取图中v1的位置
int j = LocationVex(G, v2); //j获取图中v2的位置
G.Gra[j][i]=G.Gra[i][j] = 1; //v1和v2之间有边
}
}
int main(void)
{
Graph G; //图G初始化为NULL
CreateGraph(G);
int v0;
for (int i = 0; i < 2; i++) //遍历
{
cout << "请输入开始遍历的结点序号v0:";
cin >> v0;
cout << "深度遍历为:"; DepthFirstSearch(G, v0 - 1);
cout << endl;
cout << "广度遍历为:"; BroadFirstSearch(G, v0 - 1);
cout << endl;
for (int j = 0; j < VNum; j++)//遍历一次之后把访问数组置为0
{
vis[j] = false;
vis1[j] = false;
}
}
system("pause");
}
C++——图的深度优先遍历和广度优先遍历
最新推荐文章于 2024-08-18 17:46:51 发布