数据结构C语言版 图的遍历 DFS和BFS算法,用邻接矩阵储存 急阿在线等 求大神指点
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构C语言版 图的遍历 DFS和BFS算法,用邻接矩阵储存 急阿在线等 求大神指点相关的知识,希望对你有一定的参考价值。
图的生成与操作
【问题描述】
很多涉及图上操作的算法都是以图的遍历操作作为基础的。试写一个程序,实现对连通的无向图访问全部结点的操作。
【基本要求】
建立图的邻接表或邻接矩阵存储结构,并利用DFS及BFS算法对此图进行遍历,输出遍历结果。
#include<string.h>
#include<stack>
#include<queue>
const int Max=100;
const int VISITED=101010;
const int UNVISITED=111111;
const int AFFINITY=101010;
const int INFINITY=111111;
using namespace std;
class Edge
public:
int start;
int end;
int weight;
Edge(int st=0,int en=0,int w=0):start(st),end(en),weight(w)
bool operator>(Edge oneEdge)return weight>oneEdge.weight?true:false;
bool operator<(Edge oneEdge)return weight<oneEdge.weight?true:false;
bool operator!=(Edge oneEdge)
if(weight!=oneEdge.weight||start!=oneEdge.start||end!=oneEdge.end)
return true;
return false;
;
class AdjGraf
private:
int verticesNum;
int edgeNum;
int **matrix;
int *Mark;
public:
AdjGraf(int vert)
int i=0,j=0;
verticesNum=vert;
matrix=(int**)new int*[vert];
for(i=0;i<vert;i++)
matrix[i]=new int[vert];
Mark=new int[vert];
for(i=0;i<vert;i++)
for(j=0;j<vert;j++)
matrix[i][j]=0;
for( int m=0;m<verticesNum;m++)
Mark[m]=UNVISITED;
~AdjGraf();
//返回与顶点oneVertex相关联的第一条边
Edge FirstEdge(int oneVertex);
//返回与边PreEdge有相同关联顶点oneVertex的下一条边
Edge NextEdge( Edge preEdge);
//添加一条边
void setEdge(int fromVertex,int toVertex,int weight);
//删一条边
void delEdge(int fromVertex,int toVertex);
//如果oneEdge是边则返回TRUE,否则返回FALSE
bool IsEdge( Edge oneEdge)
if(oneEdge.start>=0&&oneEdge.start<verticesNum&&
oneEdge.end>=0&&oneEdge.end<verticesNum)
return true;
else return false;
//返回边oneEdge的始点
int FromVertex(Edge oneEdge)return oneEdge.start;
//返回边oneEdge的终点
int ToVertex(Edge oneEdge)return oneEdge.end;
//返回边oneEdge的权
int Weight(Edge oneEdge)return oneEdge.weight;
void visit(int i)cout<<i+1<<" ";
void BFS(int i=1);
void DFS(int i);
void DFSTraverse(int v);
void DFSNoReverse(int f=1);
Edge UNVISITEDEdge(int f);
;
AdjGraf::~AdjGraf()
for(int i=0;i<verticesNum;i++)
delete[]matrix[i];
delete[]matrix;
Edge AdjGraf::FirstEdge(int oneVertex)
int i;
Edge tempEdge;
tempEdge.start=oneVertex;
for( i=0;i<verticesNum;i++)
if(matrix[oneVertex][i]!=0)
break;
tempEdge.end=i;
tempEdge.weight=matrix[oneVertex][i];
return tempEdge;
Edge AdjGraf ::NextEdge( Edge preEdge)
Edge tempEdge;
tempEdge.start=preEdge.start;
int i=0;
for(i=preEdge.end+1;i<verticesNum;i++)
if(matrix[preEdge.start][i]!=0)
break;
tempEdge.end=i;
tempEdge.weight=matrix[preEdge.start][i];
return tempEdge;
void AdjGraf::setEdge(int fromVertex,int toVertex,int weight)
if(matrix[fromVertex-1][toVertex-1]==0)
edgeNum++;
matrix[fromVertex-1][toVertex-1]=weight;
void AdjGraf::delEdge(int fromVertex,int toVertex)
if(matrix[fromVertex][toVertex]==0)
edgeNum--;
matrix[fromVertex][toVertex]=0;
/*************递归实现深度优先****************/
void AdjGraf::DFS(int i)
visit(i);
Mark[i]=VISITED;
for(Edge e=FirstEdge(i);IsEdge(e);e=NextEdge(e))
if(Mark[ToVertex(e)] == UNVISITED)
DFS(ToVertex(e));
void AdjGraf::DFSTraverse(int v)
v--;
int i;
for(i=0;i<verticesNum;i++)
Mark[i]=UNVISITED;
for(i=v;i<v+verticesNum;i++)
if (Mark[i]== UNVISITED)
DFS(i);
Edge AdjGraf::UNVISITEDEdge(int f)
int i;
for( Edge e=FirstEdge(f);IsEdge(e);e=NextEdge(e))
if(Mark[e.end]==UNVISITED)
return e;
return Edge(verticesNum,verticesNum,0) ;
/*************非递归实现深度优先**************/
void AdjGraf::DFSNoReverse(int f)
f--;
int i,counter=0,j,flag;
stack<int>Temp;
for(i=0;i<verticesNum;i++)
Mark[i]=UNVISITED;
flag=f;
while(counter<12)
while(flag!=verticesNum&&IsEdge(UNVISITEDEdge(flag))||!Temp.empty())
// Edge tempEdge=UNVISITEDEdge(j);
while(flag!=verticesNum&&Mark[flag]==UNVISITED)
visit(flag);
Mark[flag]=VISITED;
Temp.push(flag);
flag=UNVISITEDEdge(flag).end;
if(!Temp.empty())
flag=UNVISITEDEdge(Temp.top()).end;
Temp.pop();
if(Mark[counter]==UNVISITED) flag=counter;
else counter++;
/*************非递归实现广度优先**************/
void AdjGraf::BFS(int v)
int i;
v--;
for( i=0;i<verticesNum;i++)
Mark[i]=UNVISITED;
queue<int>tempqueue;
i=0;
/*********v先从指定位置开始,然后从v=0,1,2......
依次检查是否有孤立结点*****************/
while(i<verticesNum)
tempqueue.push(v);
while(!tempqueue.empty())
v=tempqueue.front();
tempqueue.pop();
if(Mark[v]==UNVISITED)
visit(v);
Mark[v]=VISITED;
for(Edge e=FirstEdge(v);IsEdge(e);e=NextEdge(e))
v=ToVertex(e);
tempqueue.push(v);
/***********防止出现孤立点****************/
if(Mark[i]==VISITED) i++;
else v=i;
int main()
AdjGraf Graph(12);
Graph.setEdge(1,2,1);
Graph.setEdge(2,1,1);
Graph.setEdge(1,3,5);
Graph.setEdge(3,1,5);/** V1 V12 V11 */
Graph.setEdge(2,4,3);/** / \ / \ */
Graph.setEdge(4,2,3);/** v2 v3 V10 V9 */
Graph.setEdge(2,5,7);/** / \ / \ */
Graph.setEdge(5,2,7);/** v4 v5 v6-v7 */
Graph.setEdge(4,8,4);/** \ / */
Graph.setEdge(8,4,4);/** v8 */
Graph.setEdge(5,8,3);
Graph.setEdge(8,5,3);
Graph.setEdge(3,6,2);
Graph.setEdge(6,3,2);
Graph.setEdge(3,7,1);
Graph.setEdge(7,3,1);
Graph.setEdge(6,7,6);
Graph.setEdge(7,6,6);
Graph.setEdge(12,9,6);
Graph.setEdge(9,12,6);
Graph.setEdge(12,10,6);
Graph.setEdge(10,12,6);
Graph.setEdge(11,11,6);
cout<<"DFSTraverse:"<<endl;
Graph.DFSTraverse(3);
cout<<endl;
cout<<"DFSNoReverse:"<<endl;
Graph.DFSNoReverse(3);
cout<<endl;
cout<<"BFS:"<<endl;
Graph.BFS(3);
cout<<endl;
return 0;
以上代码运行环境codeblocks 程序采用DFS递归算法 DFS非递归算法 BFS非递归算法
望采纳~追问
是要用C语言编写 大神难道是自己写的嘛 能帮我改下么.
追答C语言啊 C语言可以用类吗
追问不可以阿 您这写的是C++ 我们要求是C语言 唉
好的 麻烦你了 非常感谢
追答已私信~~收到了吗
望查收~~
学习笔记:图的DFS和BFS的两种搜索办法
在学习图结构的过程中,DFS和BFS是两种不同的遍历方式,其寻找元素具有不同的优点和缺陷。
BFS被称作广度优先算法, 在遍历整个图的过程中,BFS将采用入队的方式进行,值得一提的是,这和树结构中的层序遍历有很大的相似之处。
在层序遍历中,将父亲节点入队后,在父亲节点出队后,将其儿子节点入队。
同理在图的BFS遍历中,先让BFS的首元素入队,在收元素入队后将他的儿子节点入队,放能够实现BFS搜索,他们的整体思想是一样的。
1 void TraversalGraph_BFS(LGraph Graph,Vertex vertex){ 2 Visit(vertex); 3 VISIT[vertex]=1; 4 enqueue(queue,vertex); 5 while(!isEmpty(queue)){ 6 DelQueue(queue); 7 for(w=Graph->G[vertex].FirstNode;w;w=w->Next){ 8 if(!Visit[w]){ 9 Visit[w]; 10 Visit[w->vertex]=1; 11 enqueue(queue,w); 12 } 13 } 14 } 15 }
DFS又被称作深度优先算法,与BFS不同的是,DFS会首先遍历其儿子节点,这样有点类似在树结构中的前序遍历。
在理解方面相比比较容易,DFS采用了递归的思路,在用链表实现DFS时,思路是当遇到一个没有遍历的节点,则进入该节点,然后同理往下递归,直到某个节点无法在继续则返回。
1 void TraversalGraph_DFS(LGraph Graph,Vertex vertex,void(*Visit)(Vertex)){ 2 PtrToAdjVNode W; 3 Visit(vertex); 4 Visit[vertex]=1; 5 for(w=Graph->G[vertex].FirstNode;w;w=w->Next){ 6 if(!Visit[w->vertex]) 7 TraversalGraph_DFS(Graph,w->Vertex) 8 } 9 }
下面是程序结构体的前置定义
1 #include<stdio.h> 2 #include<stdlib.h> 3 4 typedef struct Enode *PtrToEnode; 5 typedef int Vertex; 6 typedef int WeightType; 7 typedef DataType Data; 8 struct Enode{ 9 Vertex v1,v2; 10 WeightType Weight; 11 }; 12 typedef PtrToEnode Edge; 13 14 typedef struct AdjVNode *PtrToAdjVNode; 15 struct AdjVNode{ 16 Vertex vertex; 17 WeightType Weight; 18 PtrToAdjVNode Next; 19 }; 20 21 typedef struct HeadNode *PtrToHead; 22 struct HeadNode{ 23 PtrToAdjVNode FirstNode; 24 DataType Data; 25 }HeadNode[Max]; 26 27 typedef struct Graph *PtrToGNode; 28 struct Graph{ 29 int Ne; 30 int Nv; 31 HeadNode G; 32 }; 33 typedef *PtrToGNode LGraph; 34 35 LGraph creatGraph(int MaxNumb){ 36 LGraph Graph; 37 Graph=(LGraph)malloc(sizeof(struct Graph)); 38 Graph->Ne=0; 39 Graph->Nv=MaxNumb; 40 for(i=0;i<Graph->Nv;i++){ 41 Graph->G[i].FirstNode=NULL; 42 } 43 return(Graph); 44 } 45 46 void Insert(LGraph Graph,Edge E){ 47 AdjVNode NewNode; 48 NewNode=(PtrToAdjVNode)malloc(sizeof(struct AdjVNode)) 49 NewNode->Weight=E->W; 50 NewNode->vertex=E->v1 51 Graph->G[E->v2].Next=NewNode->Next; 52 Graph->G[E->v2].Next=NewNode; 53 } 54 55 void Visit(LGraph Graph){ 56 printf("Now VISIT %d",V); 57 }
以上是关于数据结构C语言版 图的遍历 DFS和BFS算法,用邻接矩阵储存 急阿在线等 求大神指点的主要内容,如果未能解决你的问题,请参考以下文章
(王道408考研数据结构)第六章图-第三节:图的遍历(DFS和BFS)