<span style="font-size:18px;">#include<stdio.h>
#include <iostream>
#include<algorithm>
#include<queue>
#include<string.h>
#define true 1
#define MVNum 100010 //最多定点数
using namespace std;
queue<int>Q;
int visited[MVNum];
typedef int VerTexType;
typedef struct ArcNode // 边结点
{
int adjvex; // 边所指向的顶点位置
struct ArcNode * nextarc; // 指向下一条边的指针
}ArcNode;
typedef struct VNode
{
VerTexType data; // 顶点信息
ArcNode * firstarc; // 指向第一条依附该顶点的指针
}VNode, AdjList[MVNum]; // AdjList 表示邻接表类型
typedef struct
{
AdjList vertices; // 邻接表
int vexnum, arcnum; // 图的当前顶点数和边数
}ALGraph;
ALGraph G; // 作全局变量防止超内存
int LocateVex(ALGraph &G, int v)
{
if (v >= 1 && v <= G.vexnum) // 只访问 1 到 G.vexnum(最大顶点)的所有点
return v;
else return 0;
}
void CreateUDG(ALGraph &G) // 采用邻接表表示法,创建无向图 G
{
scanf("%d %d", &G.vexnum, &G.arcnum); // 输入图的顶点数,和总边数
for (int i = 1; i <= G.vexnum; i++) // 顶定点从 1 到 G.vexnum
{
//scanf("%VerTexType", &G.vertices[i].data); // 顶定点信息
G.vertices[i].data = i;
G.vertices[i].firstarc = NULL;
}
for (int k = 0; k < G.arcnum; k++) // 输入各边,构造邻接表
{
int v1, v2;
ArcNode *p1, *p2;
scanf("%d %d", &v1, &v2); // v1,v2 为该边连通的两个顶点
int i = LocateVex(G, v1); int j = LocateVex(G, v2);
if (i&&j)
{
p1 = new ArcNode;
p1->adjvex = j;
p1->nextarc = G.vertices[i].firstarc; G.vertices[i].firstarc = p1; // 将新结点*p1插入顶点 vi 的边表头部
p2 = new ArcNode;
p2->adjvex = i;
p2->nextarc = G.vertices[j].firstarc; G.vertices[j].firstarc = p2; // 将新结点*p2插入顶点 vj 的边表头部
}
}
}
void DFS(ALGraph &G, int v) // 深度优选遍历
{
if (!visited[v]) printf("%d ", v); // 输出访问的点
visited[v] = true;
ArcNode *p;
int w;
p = G.vertices[v].firstarc;
while (p != NULL) // 边结点非空
{
w = p->adjvex; // 表示 w 是 v 的邻接点
if (!visited[w]) DFS(G, w); // 如果 w 未访问,则递归调用 DFS
p = p->nextarc; // p指向下一边结点
}
}
void BFS(ALGraph &G, int v)
{
memset(visited, 0, sizeof (visited));
Q.push(v);// 进队
if (!visited[v]) printf("%d ", v); // 输出访问的点
visited[v] = true;
ArcNode *p;
int w;
while (!Q.empty())
{
v = Q.front(); Q.pop(); // 出队
p = G.vertices[v].firstarc;
while (p != NULL) //邻接顶点入队列
{
w = p->adjvex;
if (!visited[w])
{
Q.push(w); // 进队
printf("%d ", w); //printf("%d ", v); // 输出访问的点 输出访问的点
visited[w] = true;
}
p = p->nextarc;
}
}
memset(visited, 0, sizeof (visited));
}
int main()
{
memset(visited, 0, sizeof(visited));
printf("先输入图的顶点数,和总边数。然后输入每条边的两个顶点.\n");
CreateUDG(G);
BFS(G, 1); // 仅遍历以与 1 连通的所有结点
/*
for (int i = 1; i <= G.vexnum;i++) // 遍历整个图包扩非连通图
{
BFS(G, i);
}
*/
printf("\n");
DFS(G, 1); // 仅遍历以与 1 连通的所有结点
/*
for (int i = 1; i <= G.vexnum;i++) // 遍历整个图包扩非连通图
{
DFS(G, i);
}
*/
return 0;
}
</span>
图的遍历(头插法)(DFS和BFS)
最新推荐文章于 2023-08-29 16:22:25 发布