【数据结构】浅谈图常用的两种存储结构

写程序时,需要一定的结构存储图,本文将介绍两种图常用的存储结构:邻接矩阵邻接表

邻接矩阵

邻接矩阵是通过二维数组对图中边的信息(包括边依附的两个顶点以及边的权值)进行存储。

邻接矩阵数组的大小取决于图中顶点的数量。

准备工作

使用邻接矩阵前,需要开一个一维数组数组,以存储各个顶点的数据(数组的编号与邻接矩阵中顶点的编号一一对应)

构造函数

邻接矩阵建图的构造函数要完成的三件事

1.存储图的基本信息(顶点数、边数)

2.存顶点

3.存边(构造邻接矩阵)

MGraph(DateType a[],int n,int e){
	vertxNum=n,EdgeNum=e;						//1.顶点数、边数传入 
	int i,j,k,w;	//i,j记录顶点;k记录边		
	for(i=0;i<vertxNum;i++) vertx[i]=a[i];		//2.顶点数组录入数据
				
	for(i=0;i<vertxNum;i++)						//3.初始化邻接矩阵 
		for(j=0;j<vertxNum;j++)
			edge[i][j]=0; 
	for(k=0;k<EdgeNum;k++){
        cout<<"输入边依附的两个顶点的编号,以及边上的权值:";
		cin >> i >> j >> w;                    //4.输入边依附的两个顶点的编号及边的权值 
		edge[i][j]=w;
	/*	edge[j][i]=w; */	//若为无向图,可以加本行;若为有向图,不可加入本行! 
	}
}

析构函数

邻接矩阵本质上是数组,为静态存储,所以类中无需手动写析构函数,使用默认析构函数即可

~MGraph(){}

邻接表

邻接表,存储与树的孩子链表示法相类似,是顺序分配和链式分配相结合的存储结构。

如果顶点表中的顶点存在相邻顶点,则把相邻顶点依次存放于表头结点所指向的单向链表中。

准备工作

使用邻接表存储图,需要构造两个结构体:

1.邻接边表

struct EdgeNode       	//邻接边表结点
{
  int adjvex;         	//邻接点域
  EdgeNode *next;		//指向邻接表的指针
};

2.顶点表

struct VertexNode     //顶点表结点
{
  int in;				//入度域
  DataType vertex;		//顶点数据
  EdgeNode *firstEdge;	//指向邻接表的指针
};

构造函数

使用面向对象完成邻接表,一般情况需要在构造函数中完成两件事

1.存储顶点信息到顶点表;

2.存边权信息到邻接表 。

ALGraph(char a[],int n,int e){ 
//邻接表的构造干两件事:1.存储顶点信息到顶点表;2.存边权信息到邻接表 
	vertexNum=n, edgeNum=e;  
	int i,j,k;  
	//存顶点 
	for(i=0;i<vertxNum;i++){
		adjlist[i].vertx=a[i];
		adjlist[i].firstEdge=NULL;
	} 
	
	EdgeNode *p=NUll;
	//存边 
	for(k=0;k<EdgeNum;k++){
		cin>>i>>j;		//输入顶点i编号和其邻接点j编号 
		//头插法将邻接点的信息存入表中,此时顶点表的每个顶点就相当于单链表中的头结点first,firstEdge等价于单链表头结点中的next域(first->next) 
		p=new EdgeNode;		//工作指针p,用于操作新加入的结点 
		p->adjlist=j;		//邻接表记录邻接点
		p->next=adjlist[i].firstEdge;	//插入点的下一位置指向头结点下一位置(插入元素置于邻接表表头) 
		adjlist[i].firstEdge=p; 		//头结点指向新插入点 
		 								//如此循环,输入的邻接点信息就可以依次插入到邻接表的头部 
	} 

析构函数

由于邻接表本质是链表,存储数据时为动态存储,需要手动析构!

因此,析构函数要完成的工作是循环删除每个结点!!

~ALGraph(){
	EdgeNode *p,*q;		//工作指针p ,临时指针q(暂存被删除元素) 
	p=NULL,q=NULL;
	for(int i=0;i<vertxNum;i++){
		p=adjlist[i].firstEdge;	//工作指针,用于向后移动 
		q=adjlist[i].firstEdge;	//暂存被删元素 
		while(p!=NULL){
			p=p->next;
			delete q;
			q=p;
		} 
	}
} 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值