【数据结构·考研】图的深搜和广搜

深搜和广搜 - 邻接矩阵实现

今天演示 dfs 和 bfs 的就是下边这个图。

邻接矩阵的结构声明

typedef struct{
	int numVertices; //顶点个数
	char vertice[10]; //顶点矩阵
	int edge[10][10]; //边矩阵
}MGraph; 

与顶点 v 相邻的第一个结点的下标

int fistNeighbor(MGraph& G,int v){
	for(int i = 0;i < G.numVertices;i ++)
		if(G.edge[v][i] == 1)
			return i;
	return -1;
} 

顶点 v 除 w 顶点外的下一个相邻结点的下标

int nextNeighbor(MGraph& G,int v,int w){
	for(int i = w + 1;i < G.numVertices;i ++)
		if(G.edge[v][i] == 1)
			return i;
	return -1;
} 

firstNeighbor 和 nextNeighbor 封装好后,可以忽略邻接矩阵和邻接表在 dfs 和 bfs 中的实现细节。

深搜和广搜每执行一次,就遍历了一个连通分量。

深度优先遍历

void dfs(MGraph& G,int v,int visited[]){
	cout<<G.vertice[v]<<" ";
	visited[v] = 1;
	int w = fistNeighbor(G,v);
	while(w != -1){
		if(!visited[w]) dfs(G,w,visited);
		w = nextNeighbor(G,v,w);
	}
}

void graphTraverse_dfs(MGraph& G){
	int visited[5] = {0};
	for(int i = 0;i < G.numVertices;i ++)
		if(!visited[i]) dfs(G,i,visited);
}

广度优先遍历

void bfs(MGraph& G,int v,int visited[]){
	cout<<G.vertice[v]<<" ";
	visited[v] = 1;
	queue<int> q; //广搜用队列
	q.push(v);
	while(!q.empty()){
		v = q.front();
		q.pop();
		int w = fistNeighbor(G,v);
		while(w != -1){
			if(!visited[w]){
				cout<<G.vertice[w]<<" ";
				visited[w] = 1;
				q.push(w);
			}
			w = nextNeighbor(G,v,w);
		}
	}
}

void graphTraverse_bfs(MGraph& G){
	int visited[5] = {0};
	for(int i = 0;i < G.numVertices;i ++)
		if(!visited[i]) bfs(G,i,visited);
}

完整代码如下:

#include<iostream>
#include<queue>
using namespace std;

typedef struct{
	int numVertices;
	char vertice[10];
	int edge[10][10];
}MGraph; 

//找出v的第一个邻接顶点位置
int fistNeighbor(MGraph& G,int v){
	for(int i = 0;i < G.numVertices;i ++)
		if(G.edge[v][i] == 1)
			return i;
	return -1;
} 

//找出v除w顶点的下一个邻接结点的位置
int nextNeighbor(MGraph& G,int v,int w){
	for(int i = w + 1;i < G.numVertices;i ++)
		if(G.edge[v][i] == 1)
			return i;
	return -1;
} 

void dfs(MGraph& G,int v,int visited[]){
	cout<<G.vertice[v]<<" ";
	visited[v] = 1;
	int w = fistNeighbor(G,v);
	while(w != -1){
		if(!visited[w]) dfs(G,w,visited);
		w = nextNeighbor(G,v,w);
	}
}

void bfs(MGraph& G,int v,int visited[]){
	cout<<G.vertice[v]<<" ";
	visited[v] = 1;
	queue<int> q;
	q.push(v);
	while(!q.empty()){
		v = q.front();
		q.pop();
		int w = fistNeighbor(G,v);
		while(w != -1){
			if(!visited[w]){
				cout<<G.vertice[w]<<" ";
				visited[w] = 1;
				q.push(w);
			}
			w = nextNeighbor(G,v,w);
		}
	}
}

void graphTraverse_dfs(MGraph& G){
	int visited[5] = {0};
	for(int i = 0;i < G.numVertices;i ++)
		if(!visited[i]) dfs(G,i,visited);
}

void graphTraverse_bfs(MGraph& G){
	int visited[5] = {0};
	for(int i = 0;i < G.numVertices;i ++)
		if(!visited[i]) bfs(G,i,visited);
}

int main(){
    MGraph G;
    G.numVertices = 5;
    G.vertice[0]= 'a';
    G.vertice[1]= 'b';
    G.vertice[2]= 'c';
    G.vertice[3]= 'd';
    G.vertice[4]= 'e';
    G.edge[G.numVertices][G.numVertices];
    //a
    G.edge[0][0] = 0;
    G.edge[0][1] = 1;
    G.edge[0][2] = 0;
    G.edge[0][3] = 0;
    G.edge[0][4] = 1;
    //b
    G.edge[1][0] = 0;
    G.edge[1][1] = 0;
    G.edge[1][2] = 1;
    G.edge[1][3] = 0;
    G.edge[1][4] = 0;
    //c
    G.edge[2][0] = 0;
    G.edge[2][1] = 0;
    G.edge[2][2] = 0;
    G.edge[2][3] = 1;
    G.edge[2][4] = 0; 
    //d
    G.edge[3][0] = 1;
    G.edge[3][1] = 1;
    G.edge[3][2] = 0;
    G.edge[3][3] = 0;
    G.edge[3][4] = 0;
    //e
    G.edge[4][0] = 0;
    G.edge[4][1] = 0;
    G.edge[4][2] = 1;
    G.edge[4][3] = 0;
    G.edge[4][4] = 0;
    cout<<"dfs:"<<endl;
    graphTraverse_dfs(G);
    cout<<endl;
    cout<<"bfs:"<<endl;
    graphTraverse_bfs(G);
}

运行结果:

深搜和广搜 - 邻接表实现

邻接表结构声明

//边结点
struct edgeNode{
	int dest; //数字下标 
	edgeNode *next = NULL; 
}; 

//顶点结点 
struct vertexNode{
	char dest; //字母下标
	edgeNode *first = NULL;
};

//邻接表
struct ALGraph{
	vertexNode vertice[5];
	int numVertices = 5;
};  

与顶点 v 相邻的第一个结点的下标

int fistNeighbor(ALGraph& G,int v){
	if(G.vertice[v].first != NULL) 
		return G.vertice[v].first->dest;
	else return -1;
}

顶点 v 除 w 顶点外的下一个相邻结点的下标

int nextNeighbor(ALGraph& G,int v,int w){
	edgeNode* p = G.vertice[v].first;
	while(p != NULL && p->dest != w) p = p->next;
	if(p != NULL && p->next != NULL) return p->next->dest;
	else return -1;
}

深度优先遍历

void dfs(ALGraph& G,int v,int visited[]){
	cout<<G.vertice[v].dest<<" ";
	visited[v] = 1;
	int w = fistNeighbor(G,v);
	while(w != -1){
		if(!visited[w]) dfs(G,w,visited);
		w = nextNeighbor(G,v,w);
	}
}

void graphTraverse_dfs(ALGraph& G){
	int visited[5] = {0};
	for(int i = 0;i < G.numVertices;i ++)
		if(!visited[i]) dfs(G,i,visited);
}

广度优先遍历

void bfs(ALGraph& G,int v,int visited[]){
	cout<<G.vertice[v].dest<<" ";
	visited[v] = 1;
	queue<int> q;
	q.push(v);
	while(!q.empty()){
		v = q.front();
		q.pop();
		int w = fistNeighbor(G,v);
		while(w != -1){
			if(!visited[w]){
				cout<<G.vertice[w].dest<<" ";
				visited[w] = 1;
				q.push(w);
			}
			w = nextNeighbor(G,v,w);
		}
	}
}

void graphTraverse_bfs(ALGraph& G){
	int visited[5] = {0};
	for(int i = 0;i < G.numVertices;i ++)
		if(!visited[i]) bfs(G,i,visited);
}

完整代码如下:

#include<iostream>
#include<queue>
using namespace std;

//边结点
struct edgeNode{
	int dest; //数字下标 
	edgeNode *next = NULL; 
}; 

//顶点结点 
struct vertexNode{
	char dest; //字母下标
	edgeNode *first = NULL;
};

//邻接表
struct ALGraph{
	vertexNode vertice[5];
	int numVertices = 5;
};  

//找出v的第一个邻接顶点位置
int fistNeighbor(ALGraph& G,int v){
	if(G.vertice[v].first != NULL) 
		return G.vertice[v].first->dest;
	else return -1;
}
		
//找出v除w顶点的下一个邻接结点的位置
int nextNeighbor(ALGraph& G,int v,int w){
	edgeNode* p = G.vertice[v].first;
	while(p != NULL && p->dest != w) p = p->next;
	if(p != NULL && p->next != NULL) return p->next->dest;
	else return -1;
}

void dfs(ALGraph& G,int v,int visited[]){
	cout<<G.vertice[v].dest<<" ";
	visited[v] = 1;
	int w = fistNeighbor(G,v);
	while(w != -1){
		if(!visited[w]) dfs(G,w,visited);
		w = nextNeighbor(G,v,w);
	}
}

void bfs(ALGraph& G,int v,int visited[]){
	cout<<G.vertice[v].dest<<" ";
	visited[v] = 1;
	queue<int> q;
	q.push(v);
	while(!q.empty()){
		v = q.front();
		q.pop();
		int w = fistNeighbor(G,v);
		while(w != -1){
			if(!visited[w]){
				cout<<G.vertice[w].dest<<" ";
				visited[w] = 1;
				q.push(w);
			}
			w = nextNeighbor(G,v,w);
		}
	}
}

void graphTraverse_dfs(ALGraph& G){
	int visited[5] = {0};
	for(int i = 0;i < G.numVertices;i ++)
		if(!visited[i]) dfs(G,i,visited);
}

void graphTraverse_bfs(ALGraph& G){
	int visited[5] = {0};
	for(int i = 0;i < G.numVertices;i ++)
		if(!visited[i]) bfs(G,i,visited);
}
 
int main(){
	ALGraph G;
	G.vertice[0].dest = 'a';
	G.vertice[1].dest = 'b';
	G.vertice[2].dest = 'c';
	G.vertice[3].dest = 'd';
	G.vertice[4].dest = 'e';
	//a
	G.vertice[0].first = new edgeNode;
	G.vertice[0].first->dest = 1;
	G.vertice[0].first->next = new edgeNode;
	G.vertice[0].first->next->dest = 4;
	//b
	G.vertice[1].first = new edgeNode;
	G.vertice[1].first->dest = 2;
	//c
	G.vertice[2].first = new edgeNode;
	G.vertice[2].first->dest = 3;
	//d
	G.vertice[3].first = new edgeNode;
	G.vertice[3].first->dest = 0;
	G.vertice[3].first->next = new edgeNode;
	G.vertice[3].first->next->dest = 1;
	//e
	G.vertice[4].first = new edgeNode;
	G.vertice[4].first->dest = 2;
	
	cout<<"dfs:"<<endl;
	graphTraverse_dfs(G);
	cout<<endl;
	cout<<"bfs:"<<endl;
	graphTraverse_bfs(G);	
} 

运行结果:

猜你喜欢

转载自blog.csdn.net/cjw838982809/article/details/108461225