这一个程序写了好久,主要是对三个结构体同时操作时出现混乱。
本程序主要是关于图的创建和图的深度优先遍历DFS 和 广度优先遍历BFS。
其中,我把每个节点从a到z分别命名。这程序的输入是一个矩阵,如下:
0 11 0
11 0 13
0 13 0
由这个矩阵的对称性可以看出,它是一个无向图,当然本程序也可以处理有向图。
程序里,我是用邻接法来建立图的。有兴趣的朋友可以试试用 十字链表 来实现有向图,用 邻接多重表 来实现无向图。
但注意,我一开始限制了矩阵的维数为25 ,如需扩大,请修改Max_vertex_num的值。
对了,广度优先遍历我用的是非递归算法,深度优先遍历用的是递归算法,其它两种算法在接下去的日子里,我会补充的。
#include<iostream>
#include<queue>
using namespace std;
typedef int INFOTYPE;
typedef char VERTEXTYPE;
const INFOTYPE Max_vertex_num = 25; //定为25,则矩阵最多只能是25x25
int visited[Max_vertex_num];
typedef struct ArcNode
{
int adjvex; //这条弧的下一个结点
struct ArcNode *nextarc;
INFOTYPE info; //弧上的数据
}ArcNode;
typedef struct VNode
{
VERTEXTYPE data; //结点的数据
ArcNode *firstarc; //与之连接的第一个链结点
}VNode, AdjList[Max_vertex_num];
typedef struct
{
AdjList vertices;
int vexnum,arcnum;
int kind; //1表示无向图
}ALGraph ;
//创建(初始化)这个图
void createGraph(ALGraph &graph, INFOTYPE data[Max_vertex_num][Max_vertex_num], int v) //data指传入的矩阵,v指矩阵的维数
{
int i=0,j=0,arcnum=0,flag=1; //flag用来指示是否是无向图,1表示是。
ArcNode *tempArc=NULL,*p=NULL;
graph.vexnum = v;
for(;i < v; i ++)
{
tempArc = (ArcNode*)malloc(sizeof(ArcNode));
graph.vertices[i].firstarc = tempArc;
graph.vertices[i].data = 'a' + i; //给结点编号,从a开始
tempArc->nextarc = NULL;
p = NULL;
for(j = 0; j < v; j ++)
{
if(data[i][j] != 0)
{
arcnum ++;
if(data[j][i] == 0) flag = 0;
tempArc->adjvex = j;
tempArc->info = data[i][j];
if(p) p->nextarc = tempArc;
p = tempArc;
tempArc = tempArc->nextarc;
tempArc = (ArcNode*)malloc(sizeof(struct ArcNode));
tempArc->nextarc = NULL;
}
}
free(tempArc);
}
graph.arcnum = flag?(arcnum/2):arcnum;
graph.kind = flag;
}
//取得下标为i的第一个邻结点
int FirstAdjVex(ALGraph g, int i)
{
return g.vertices[i].firstarc->adjvex;
}
//BFS取得下一个邻结点
int BFS_NextAdjVex(ALGraph g, int i, int w)
{
ArcNode* arc = g.vertices[i].firstarc;
while(arc->adjvex != w)
{
arc = arc->nextarc;
}
if(!arc->nextarc) return -1;
return arc->nextarc->adjvex;
}
//DFS取得下一个邻结点
int DFS_NextAdjVex(ALGraph g, int i)
{
ArcNode* arc = g.vertices[i].firstarc;
//if(!g.vertices[i].firstarc) return -1;
if(visited[arc->adjvex])
{
if(arc->nextarc) return arc->nextarc->adjvex;
return -1;
}
return arc->adjvex;
}
//广度优先遍历
void BFS_traverse(ALGraph graph)
{
int i=0,n=graph.vexnum;
memset(visited,0,n*sizeof(int)); //先设为0,表示未访问过
queue<int> q;
int t,w; //临时变量,在队列操作中使用
for(i=0; i<n; i++)
{
if(!visited[i])
{
visited[i] = 1;
//开始访问
cout<<graph.vertices[i].data<<endl;
q.push(i);
while(!q.empty())
{
t = q.front();
q.pop();
for(w = FirstAdjVex(graph,t); w > 0; w = BFS_NextAdjVex(graph,t,w))
{
if(!visited[w])
{
visited[w] = 1;
//开始访问
cout<<graph.vertices[w].data<<endl;
q.push(w);
}
}
}
}
}
}
//深度优先遍历
void DFS_traverse(ALGraph graph, int v) //v表示选取v结点开始访问
{
}
//深度优先遍历(递归)
void recursion_DFS_traverse(ALGraph graph, int v) //v表示选取v结点开始访问
{
int i=0, n=graph.vexnum, w;
visited[v] = 1;
//开始访问
cout<<graph.vertices[v].data<<endl;
for(w = v; w >= 0; w = DFS_NextAdjVex(graph,w))
{
if(w>=0 && !visited[w]) recursion_DFS_traverse(graph, w);
}
}
//把图打印出来
void printGraph(ALGraph g)
{
int n = g.vexnum, visited[Max_vertex_num];
ArcNode* arc;
memset(visited,0,n*sizeof(int)); //先设为0,表示未访问过
for(int i = 0; i < n; i ++)
{
arc = g.vertices[i].firstarc;
printf("%c->%c", g.vertices[i].data, g.vertices[g.vertices[i].firstarc->adjvex].data);
while(arc->nextarc)
{
printf("->");
arc = arc->nextarc;
printf("%c", g.vertices[arc->adjvex].data);
}
printf("\n");
}
}
int main()
{
int n,i,j;
INFOTYPE data[Max_vertex_num][Max_vertex_num];
ALGraph *graph = (ALGraph*)malloc(sizeof(ALGraph));
cout<<"How many dimensions is the matrix:";
cin>>n;
memset(data,-1,n*n); //假定输入的弧数据不会是-1
//开始输入矩阵
cout<<"Input the matrix:"<<endl;
for(i = 0; i < n; i ++)
for(j = 0; j < n; j ++)
cin>>data[i][j];
createGraph(*graph,data,n);
printGraph(*graph);
BFS_traverse(*graph);
memset(visited,0,n*sizeof(int)); //先设为0,表示未访问过
recursion_DFS_traverse(*graph, 0);
//cout<<graph->vertices[1].firstarc->info;
return 0;
}
分享到:
相关推荐
与DFS类似,当从某个顶点开始执行BFS时,每遇到一个未被访问过的顶点,就将该顶点加入到树中。最终形成的树被称为BFS生成树。 #### 3.3 BFS代码实现 ```c void BFSTraverseTREE(ALGraph* G) { for (int i = 0; i ...
本文将深入探讨如何在编程中实现无向图的构建、深度优先搜索(DFS)和广度优先搜索(BFS)遍历,并输出遍历序列。 首先,我们需要理解无向图的表示方法。通常,我们可以使用邻接矩阵或邻接表来表示无向图。邻接矩阵...
在这个主题中,我们将深入探讨如何使用邻接矩阵实现图,并介绍两种常见的图遍历算法:广度优先搜索(BFS)和深度优先搜索(DFS)。 首先,邻接矩阵是表示图的一种直观方式。在二维数组中,我们为每对节点创建一个...
总的来说,理解和实现DFS与BFS对于理解图的遍历至关重要,它们在解决许多实际问题,如寻找最短路径、判断连通性等场景中都有着广泛的应用。通过这个例子,初学者可以更好地掌握这些概念,并将其应用于实际编程中。
**广度优先搜索(BFS)**是另一种图遍历算法,它与DFS不同,BFS优先访问离起点近的顶点,然后再访问较远的顶点。BFS使用队列作为辅助数据结构,其步骤如下: 1. 将起始顶点放入队列,标记为已访问。 2. 取出队首...
程序用交互方式完成图的邻接矩阵和邻接表的构造,并提供了DFS和BFS算法。
在“邻接表建立图Bfs,Dfs遍历算法.C”文件中,应该包含了这两个算法的具体实现。文件可能包含了以下内容: - 定义节点结构体,包含节点值和邻接节点的链表。 - 创建邻接表的函数,可能通过读取输入数据来构建图。 -...
本文将深入探讨如何使用邻接矩阵和邻接表这两种方法来创建图,并实现深度优先搜索(DFS)和广度优先搜索(BFS)算法。 首先,我们来看邻接矩阵。邻接矩阵是一个二维数组,其中的元素代表图中节点之间的连接状态。...
DFS 更适合于寻找某一条路径或搜索深度较大的图,而 BFS 更适合于查找最短路径或在图的层数较少时的全面搜索。 在本实验报告中,我们探讨了如何使用 DFS 和 BFS 算法来遍历图。首先,需要理解图的存储结构,常见的...
在这个项目中,"标准C的图的实现+BFS和DFS遍历+Dijkstra算法+Prim算法+Kruskal算法实现"涵盖了图的多种核心操作和算法。接下来,我们将详细讨论这些知识点。 首先,我们来看图的实现。在标准C语言中,图可以使用...
DFS和BFS是两种基本的图和树遍历算法,它们在解决各种问题时发挥着关键作用,如寻找最短路径、查找特定节点或建立连接关系的拓扑排序。理解这些概念和算法对于提升编程能力至关重要,特别是在解决算法问题和设计高效...
总结来说,理解图的建立、DFS和BFS遍历方法是学习数据结构和算法的重要部分。它们不仅理论性强,而且在许多实际编程问题中具有广泛的应用。通过实践和练习,可以提高在这些领域的技能,从而在解决问题时更加得心应手...
本主题主要探讨如何建立无向图的邻接表存储结构,并实现深度优先搜索(DFS)和广度优先搜索(BFS)这两种遍历方法。 1. **邻接表**:相比于邻接矩阵,邻接表更适合于存储稀疏图(边的数量远小于顶点数量的平方)。...
在这其中,图的建立与输出是一项基础且重要的技能。通过学习如何建立和输出图结构,学生能够深刻理解图的基本概念,并掌握图数据的存储和遍历方法,这对于后续学习更为复杂的算法和数据结构具有极大的帮助。 首先,...
对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在v之前。通常,这样的线性序列称为满足拓扑...
在计算机科学中,图是一种非常重要的数据结构,...掌握图的建立与遍历是理解和解决许多算法问题的基础,如最短路径计算、网络流问题、图着色等。了解这些基本概念和操作,将有助于在实际应用中有效地处理图结构数据。
2. 广度优先搜索(BFS):与DFS不同,BFS 使用队列进行操作,从起始节点开始,先访问所有与其相邻的节点,然后再依次访问这些相邻节点的相邻节点,直到遍历完所有节点。BFS 在寻找最短路径问题中尤为有用,例如在...
"图的创建深度广度优先"是一个编程任务,它涉及到如何通过深度优先搜索(DFS, Depth First Search)和广度优先搜索(BFS, Breadth First Search)来遍历和构建图。这两种算法在解决许多问题时都扮演着关键角色,如...
本示例通过C++编程语言,采用邻接矩阵的方式实现图的建立与遍历。本文将深入讲解相关知识点。 1. **图的基本概念**: - 图是由顶点(节点)集合和边集合组成的,每条边连接两个顶点,表示它们之间存在某种关系。 ...