深搜和广搜 - 邻接矩阵实现
今天演示 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);
}
运行结果: