数据结构C语言版 图的遍历 DFS和BFS算法,用邻接矩阵储存 急阿在线等 求大神指点

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构C语言版 图的遍历 DFS和BFS算法,用邻接矩阵储存 急阿在线等 求大神指点相关的知识,希望对你有一定的参考价值。

图的生成与操作
【问题描述】
很多涉及图上操作的算法都是以图的遍历操作作为基础的。试写一个程序,实现对连通的无向图访问全部结点的操作。
【基本要求】
建立图的邻接表或邻接矩阵存储结构,并利用DFS及BFS算法对此图进行遍历,输出遍历结果。

参考技术A #include <iostream>
#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)

算法笔记图结构及图的 DFS 和 BFS 介绍

图的深度优先遍历DFS和广度优先遍历BFS(邻接矩阵存储)超详细完整代码进阶版

图的DFS和BFS

图的基本算法(BFS和DFS)

图的深度优先遍历(DFS)和广度优先遍历(BFS)算法分析