数据结构--图的存储表示

对于给定的图,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;




运行结果

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值