之前我们实现过根据输入构建邻接表的代码,并且对邻接表表示的图进行深搜和广搜,今天我们实现由输入构建邻接矩阵的代码并且进行深度优先遍历和广度优先遍历。
结构声明:
//结构声明
typedef struct{
int numVertices; //顶点数
int numEdges;
int VerticesList[maxVertices]; //顶点数组
int Edge[maxVertices][maxVertices]; //边数组
}MGraph;
根据输入构建邻接矩阵:
/*
创建邻接矩阵
*/
void createGraph(MGraph& G) {
cin >> G.numVertices >> G.numEdges; //输入顶点数和边数
for(int i = 0; i < G.numVertices; i ++)
for(int j = 0; j < G.numVertices; j ++)
G.Edge[i][j] = 0;
for(int i = 0; i < G.numVertices; i ++)
cin >> G.VerticesList[i]; //顶点名称
for(int i = 0; i < G.numEdges; i ++){
int tail, head; //定义边
cin >> tail >> head; //输入边
G.Edge[tail][head] = 1;
}
}
打印邻接矩阵的函数:
/*
打印邻接矩阵
*/
void printGraph(MGraph& G) {
cout <<" ";
for(int i = 0; i < G.numVertices; i ++)
cout<< G.VerticesList[i] <<" ";
cout<<endl;
for(int i = 0; i < G.numVertices; i ++) {
cout << G.VerticesList[i] <<" ";
for(int j = 0; j < G.numVertices; j ++)
cout << G.Edge[i][j] <<" ";
cout << endl;
}
}
两个辅助函数,让深搜和广搜忽略掉图的实现方式:
/*
两个辅助函数
*/
//与顶点v相邻的第一个结点的下标
int firstNeighbor(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.VerticesList[v] <<" ";
visited[v] = 1;
int w = firstNeighbor(G, v);
while(w != -1){
if(!visited[w])
dfs(G, w, visited);
w= nextNeighbor(G, v, w);
}
}
void graphTraverse_dfs(MGraph& G, int visited[]){
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.VerticesList[v] <<" ";
visited[v] = 1;
queue<int> q;
q.push(v);
while(!q.empty()){
v = q.front();
q.pop();
int w = firstNeighbor(G, v);
while(w != -1){
if(!visited[w]){
cout << G.VerticesList[w]<<" ";
visited[w] = 1;
q.push(w);
}
w=nextNeighbor(G,v,w) ;
}
}
}
void graphTraverse_bfs(MGraph& G,int visited[]){
for(int i = 0; i < G.numVertices; i ++)
if(!visited[i]) bfs(G, i, visited);
}
完整代码:
#include<iostream>
#include<queue>
using namespace std;
#define maxVertices 10
//结构声明
typedef struct{
int numVertices; //顶点数
int numEdges;
int VerticesList[maxVertices]; //顶点数组
int Edge[maxVertices][maxVertices]; //边数组
}MGraph;
/*
创建邻接矩阵
*/
void createGraph(MGraph& G) {
cin >> G.numVertices >> G.numEdges; //输入顶点数和边数
for(int i = 0; i < G.numVertices; i ++)
for(int j = 0; j < G.numVertices; j ++)
G.Edge[i][j] = 0;
for(int i = 0; i < G.numVertices; i ++)
cin >> G.VerticesList[i]; //顶点名称
for(int i = 0; i < G.numEdges; i ++){
int tail, head; //定义边
cin >> tail >> head; //输入边
G.Edge[tail][head] = 1;
}
}
/*
打印邻接矩阵
*/
void printGraph(MGraph& G) {
cout <<" ";
for(int i = 0; i < G.numVertices; i ++)
cout<< G.VerticesList[i] <<" ";
cout<<endl;
for(int i = 0; i < G.numVertices; i ++) {
cout << G.VerticesList[i] <<" ";
for(int j = 0; j < G.numVertices; j ++)
cout << G.Edge[i][j] <<" ";
cout << endl;
}
}
/*
两个辅助函数
*/
//与顶点v相邻的第一个结点的下标
int firstNeighbor(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.VerticesList[v] <<" ";
visited[v] = 1;
int w = firstNeighbor(G, v);
while(w != -1){
if(!visited[w])
dfs(G, w, visited);
w= nextNeighbor(G, v, w);
}
}
void graphTraverse_dfs(MGraph& G, int visited[]){
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.VerticesList[v] <<" ";
visited[v] = 1;
queue<int> q;
q.push(v);
while(!q.empty()){
v = q.front();
q.pop();
int w = firstNeighbor(G, v);
while(w != -1){
if(!visited[w]){
cout << G.VerticesList[w]<<" ";
visited[w] = 1;
q.push(w);
}
w=nextNeighbor(G,v,w) ;
}
}
}
void graphTraverse_bfs(MGraph& G,int visited[]){
for(int i = 0; i < G.numVertices; i ++)
if(!visited[i]) bfs(G, i, visited);
}
int main(){
MGraph G;
/*
5
5
0 1 2 3 4
0 1
1 2
2 3
4 3
0 4
*/
cout << "构造邻接矩阵:" << endl;
createGraph(G);
cout << "构造结果:" << endl;
printGraph(G);
int visit[5] = {0};
cout << "深度优先遍历:" << endl;
graphTraverse_dfs(G, visit);
cout << endl;
int visited[5] = {0};
cout << "广度优先遍历:" << endl;
graphTraverse_bfs(G, visited);
}
运行结果:
更多代码请参考:手撕考研数据结构(代码汇总)