上篇文章已经介绍了邻接矩阵的具体作用与如果利用邻接矩阵寻找相邻顶点,这次介绍重点为邻接矩阵的创建与两种遍历方式
邻接矩阵的创建
其结构体需要能记录顶点、顶点数、边数及邻接矩阵,即
#define max 100
typedef struct {
int vex[max];//顶点(假设顶点为数字,如果为字符型则需要在创建邻接矩阵时进一步对应转换)
int arc[max][max];//邻接矩阵
int numN,numE;//顶点数与边数
}Mgraph;
创建方式则为读入边数、顶点数即各边的两个顶点和权值
void creat(Mgraph* G){
cin>>G->numN>>G->numE;//读入顶点数与边数
for (int i=0;i<G->numN;i++) cin>>G->vex[i];//记录顶点
for (int i=0;i<G->numN;i++){
for (int j=0;j<G->numN;j++){
G->arc[i][j]=0;//邻接矩阵初始化
}
}
while(G->numE--){
int n1,n2,w;
cin>>n1>>n2>>w;//读入相接的顶点及权值
G->arc[n1][n2]=w;
G->arc[n2][n1]=w;//无向图,矩阵对称
}
}
图的遍历
DFS(深度优先遍历)
DFS就是从一个顶点出发,向未被访问过的相邻节点不断深入访问,直到所有与初始顶点相连通的节点都被访问过,再回溯到前一个节点,继续尝试另一条路径。通常用栈或递归来实现。
递归代码实现如下
#define max 100
bool book[max];
void dfs(Mgraph G,int i){
...//终止条件
book[i]=false;//标记这个顶点已经被访问过
for (int j=0;j<G.numN;j++){
if (G.arc[i][j]!=0&&book[j])//如果顶点i与顶点j之间连通且未访问过j
dfs(G,j);//继续进行深搜
}
}
int main(){
Mgraph* G=new Mgraph;
creat(G);
for (int i=0;i<G->numN;i++){
book[i]=true;//初始化标记数组
}
for (int i=0;i<G->numN;i++){
if(book[i]) dfs(G,i);//对未被访问的顶点开始进行深搜
}
return 0;
}
BFS(广度优先遍历)
BFS具体操作为,从某个起点开始,先访问所有与它相邻的节点,然后再访问与这些节点相邻但还未被访问的节点,以此类推,直到遍历完整张图。bfs通常用队列来实现。
队列代码如下
(同样需要设置标记数组)
void bfs(Mgraph G){
deque<int> q;
for (int i=0;i<G.numN;i++){
if (book[i]){
book[i]=false;//标记此顶点已遍历
q.push_back(i);
while(!q.empty()){//当队列不为空时
int temp=q.front();//记录队首元素
q.pop_front();//队首出队
for (int j=0;j<G.numN;j++){
if (G.arc[temp][j]!=0&&book[j]){//将与原队首相邻的入队
book[j]=false;//标记
q.push_back(j);
}
}
}
}
}
}