图的储存结构之邻接表

邻接表是图的一种链式储存结构。

在边数小于节点数的图中,如果继续使用邻接矩阵,那么就会造成资源浪费。比如我们有一个有图,一共五个节点,却只有4 条边,生成5*5的邻接矩阵时,此时在这25个内存空间中只有4个被有效的利用,这就造成了浪费。

这时,我们可以联想到链式结构。在前面的知识中,可以知道,链表相对与数组可以更有效的利用起内存空间,避免资源浪费。

因为链表是动态的,大小不用事先确定。

那么我们怎么用链表来表示图的呢?

在图中(下面说的图都为无向图),每个节点都会与一个或者多个节点连接,我们为每一个节点创建一个链表,以储存他们所连接的节点,可是我们知道,节点的next指针只能有一个,如果一个节点与多个节点连接,就会出现指针不够用的情况。为了解决这个问题,我们可以先建立一个结构体数组储存节点,再建立一个链表储存每个节点指向其他节点所在数组的下标。在结构体数组中,每个数组元素都包含着一个链表。如下图所示:

#include<iostream>
using namespace std;

const int MAXNUM = 100;
typedef int DATETYPE;

typedef struct ArcNode {
	int adjvex;     //顶点下标,该边所指向的节点的位置
	struct ArcNode *next;  //指向下一边的指针
	int info;    //改边的相关信息(如权值),用的不多
}ArcNode;
typedef struct VextexNode {
	DATETYPE date; //顶点信息
	ArcNode *firstarc;//指向第一条边的指针
}VextexNode;
typedef struct AdjListGraph {
	VextexNode adjlist[MAXNUM];//邻接表
	int NumNodes, NumEdges;//顶点数和边数
}AdjListGraph;

void Create(AdjListGraph &G) {
	int i, j, k;
	ArcNode *pev;
	cout << "请输入邻接表的顶点数以及边数(空格隔开):" << endl;
	cin >> G.NumNodes >> G.NumEdges;
	cout << "请输入每个顶点的值(回车):" << endl;
	for (i = 0; i < G.NumNodes; ++i) {
		cin >> G.adjlist[i].date;
		G.adjlist[i].firstarc = NULL;
	}
	for (k = 0; k< G.NumEdges; ++k){
		cout << "输入边(vi,vj)的顶点序号i,j(空格分隔):";
		cin >> i >> j;
		if (!(pev = (ArcNode *)malloc(sizeof(ArcNode)))) return;
		pev->adjvex = j;//邻接序号为j
		pev->next = G.adjlist[i].firstarc;//将pev指向当前顶点指向的顶点
		G.adjlist[i].firstarc = pev;
		/*由于是无向的边,故将对j的操作对i进行一次*/
		if (!(pev = (ArcNode *)malloc(sizeof(ArcNode)))) return; 
		pev->adjvex = i;
		pev->next = G.adjlist[j].firstarc;
		G.adjlist[j].firstarc = pev;
	}
}

void main() {
	AdjListGraph G;
	Create(G);
	system("pause");
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值