对于给定的图,P308图8.54输出该图的邻接矩阵G1,再将矩阵转换为邻接表,并输出,然后再将该邻接表转换为邻接矩阵G2,并输出。效果如下图所示:
代码如下
先创立三个简单的结构体
typedef struct Anode{//单个顶点的列(边节点)链表(以邻接矩阵为视角)
int adjvex;//顶点
struct Anode *nextacr;//指向下一条边的指针
int wt;//权重
}Acrnode;
typedef struct Vnode{//顶点
Acrnode *firstarc=NULL;//指向第一个边节点
}Vnode;
typedef struct
{
Vnode adjlist[MAX];//所有顶点的列链表(以邻接矩阵为视角)
int n,e;//总顶数以及边数
}Adjgraph;
上述三个结构体可以理解为
一个图有顶点,所有顶点在邻接矩阵中有对应的列(边节点)链表(就是那个表每行中所有点组成的单链表)
第一个结构体是每个节点的属性,第二个单链表的头,第三个是图,存储所有单链表的头结点
通过头结点即可找到每个顶点的列链表
相信大家看课本肯定能理解,顺便给大家讲解一下课本第一次结构体的定义用意
//ps:课本最前面两个结构体的理解
一个图是由边和顶点组成,对顶点而言,建立如下结构体
//typedef struct
//{
// int no;//编号No.
//}Vp;
边 直接表示,则图的结构体如下
建立结构体的本质其实就是封装
我愿称之为当一个点有多个属性的时候,我们用来包装,这里是为了方便理解
后续的结构体嵌套
//typedef struct
//{
// int edges[MAX][MAX]; //邻接矩阵
// int n,e;//顶点总数和边
// Vp vex[MAX];//顶点
//}MG;
完整代码如下:
//图的存储表示
#include<bits/stdc++.h>
using namespace std;
#define MAX 100
#define INF 0x3fffffff
const int N=6;//便于维护
//此题邻接矩阵已给,我们创立邻接表
typedef struct Anode{//单个顶点的列(边节点)链表(以邻接矩阵为视角)
int adjvex;//顶点
struct Anode *nextacr;//指向下一条边的指针
int wt;//权重
}Acrnode;
typedef struct Vnode{//顶点
Acrnode *firstarc=NULL;//指向第一个边节点
}Vnode;
typedef struct
{
Vnode adjlist[MAX];//所有顶点的列链表(以邻接矩阵为视角)
int n,e;//总顶数以及边数
}Adjgraph;
//上述三个结构体可以理解为
//一个图有顶点,所有顶点在邻接矩阵中有对应的列(边节点)链表
//(就是那个表每行中所有点组成的单链表)
//第一个结构体是每个节点的属性,第二个单链表的头,第三个是图,存储所有单链表的头结点
//通过头结点即可找到每个顶点的列链表
//打印邻接矩阵
void Printmatrix(int matrix[N][N])
{
for(int i=0;i<6;i++){
for(int j=0;j<6;j++){
if(matrix[i][j]==INF){
cout<<"∞ ";
}
else
cout<<" "<<matrix[i][j]<<" ";
}
cout<<endl;
}
cout<<endl;
}
//建立领接表
void Turnintolist(Adjgraph *&G,int matrix[N][N])
{
//理解了三个结构体的含义,G是指针,先初始化
G=new Adjgraph;
//这里我们要创立一个Acrnode
Acrnode *p;int E;
//开始模拟领接表的创立
//先遍历所有顶点
for(int i=0;i<N;i++){
//对每个顶点的列链表进行遍历,我们采用头插法故我们
for(int j=N-1;j>=0;j--){
if(matrix[i][j]!=0&&matrix[i][j]!=INF){
p=new Acrnode;//头插法
p->adjvex=j;
p->wt=matrix[i][j];
p->nextacr=G->adjlist[i].firstarc;
G->adjlist[i].firstarc=p;
E++;
}
}
}
G->n=N;G->e=E;
}
//打印领接表
void Printlist(Adjgraph *G){
for(int i=0;i<N;i++){
cout<<"V"<<i;
Acrnode *p=G->adjlist[i].firstarc;
while(p!=NULL){
cout<<"----->"<<p->adjvex<<","<<p->wt;
p=p->nextacr;
}
cout<<"^"<<endl;
}
cout<<endl;
}
void Turnintomatrix(Adjgraph *G,int matrix2[N][N])
{
//转化其实就是在一个全空的新matrix中填充我们的有权的值
Acrnode *p;
for(int i=0;i<G->n;i++){
p=G->adjlist[i].firstarc;
while(p){
matrix2[i][p->adjvex]=p->wt;
p=p->nextacr;
}
}
}
int main()
{
cout<<"1:为您输出该图的邻接矩阵:"<<endl;
int matrix[N][N]={ {0,5,INF,7,INF,INF},{INF,0,4,INF,INF,INF},{8,INF,0,INF,INF,9},
{INF,INF,5,0,INF,6},{INF,INF,INF,5,0,INF},{3,INF,INF,INF,1,0} };
Printmatrix(matrix);
cout<<"2:为您将该图邻接矩阵转化为邻接表:"<<endl;
Adjgraph *G;
Turnintolist(G,matrix);
Printlist(G);
cout<<"3:为您该图邻接表转化为邻接矩阵"<<endl;
int matrix2[N][N]={0};
Turnintomatrix(G,matrix2);
for(int i=0;i<G->n;i++){
for(int j=0;j<G->n;j++){
if(i==j)
cout<<" 0 ";
else if(matrix2[i][j])
cout<<" "<<matrix2[i][j]<<" ";
else
cout<<"∞ ";
}
cout<<endl;
}
return 0;
}
//ps:课本最前面两个结构体的理解
一个图是由边和顶点组成,对顶点而言,建立如下结构体
//typedef struct
//{
// int no;//编号No.
//}Vp;
边 直接表示,则图的结构体如下
建立结构体的本质其实就是封装
我愿称之为当一个点有多个属性的时候,我们用来包装,这里是为了方便理解
后续的结构体嵌套
//typedef struct
//{
// int edges[MAX][MAX]; //邻接矩阵
// int n,e;//顶点总数和边
// Vp vex[MAX];//顶点
//}MG;
运行结果