图的邻接表储存方法和基本运算算法

10 篇文章 0 订阅

包括

  1. 图的邻接表储存结构
  2. 图的邻接表储存结构的创建
  3. 图的输出
  4. 图的销毁

图的邻接表储存结构

#define MAXV 5  //矩阵长宽
#define INF 32767  //无穷
typedef struct ANode
{
	int adjvex;  //该边的邻接点编号
	struct ANode* nextarc;  //指向下一条边的指针
	int weight;  //该边的相关信息,如权值
}ArcNode;  //边结点的类型
typedef struct Vnode
{
	int info;  //顶点的其他信息
	ArcNode* firstarc;  //指向第一个边结点
}VNode;  //邻接表的头结点类型
typedef struct
{
	VNode adjlist[MAXV];  //邻接表的头结点数组
	int n, e;  //n定点数,e边数
}AdjGraph;  //完整的图邻接表类型

示例邻接矩阵(先横再竖)
在这里插入图片描述
对应的图
在这里插入图片描述

总代码

#include<iostream>
using namespace std;

#define MAXV 5  //矩阵长宽
#define INF 32767  //无穷
typedef struct ANode
{
	int adjvex;  //该边的邻接点编号
	struct ANode* nextarc;  //指向下一条边的指针
	int weight;  //该边的相关信息,如权值
}ArcNode;  //边结点的类型
typedef struct Vnode
{
	int info;  //顶点的其他信息
	ArcNode* firstarc;  //指向第一个边结点
}VNode;  //邻接表的头结点类型
typedef struct
{
	VNode adjlist[MAXV];  //邻接表的头结点数组
	int n, e;  //n定点数,e边数
}AdjGraph;  //完整的图邻接表类型

void CreateAdj(AdjGraph*& G, int A[MAXV][MAXV], int n, int e)  //创建图的邻接表
{
	int i, j; ArcNode* p;  //i,j计数变量
	G = (AdjGraph*)malloc(sizeof(AdjGraph));  //给G分配空间
	for (i = 0; i < n; i++)
		G->adjlist[i].firstarc = NULL;  //给邻接表中所有头结点的指针域赋予初值
	for(i=0;i<n;i++)  //检查邻接矩阵中的每个元素
		for(j=n-1;j>=0;j--)
			if (A[i][j] != 0 && A[i][j] != INF)  //存在一条边
			{
				p = (ArcNode*)malloc(sizeof(ArcNode));  //创建一个节点p
				p->adjvex = j;   //存放邻接点
				p->weight = A[i][j];  //存放权
				p->nextarc = G->adjlist[i].firstarc;  //采用头插法插入节点p
				G->adjlist[i].firstarc = p;
			}
	G->n = n; G->e = e;
}

void DispAdj(AdjGraph* G)  //输出邻接表G
{
	int i; ArcNode* p;  //指针p和计数变量i
	for (i = 0; i < G->n; i++)
	{
		p = G->adjlist[i].firstarc;  //边结点
		cout << i;  //边结点的编号
		cout << ":";
		while (p != NULL)  //如果p邻接点不为空,输出p的编号和权值
		{
			cout << p->adjvex;
			cout <<"[";
			cout << +p->weight;
			cout << "]→";
			p = p->nextarc;
		}
		cout << "  ∧\n";  //尾部
	}
}

void DestroyAdj(AdjGraph*& G) {  //销毁邻接表
	int i; ArcNode* pre, * p;
	for (i = 0; i < G->n; i++) {  //扫描所有的单链表
		pre = G->adjlist[i].firstarc;  //p指向第i个单链表的头结点
		if (pre != NULL) {  
			p = pre->nextarc;
			while (p != NULL)
			{
				free(pre);  //释放pre
				pre = p; p = p->nextarc;
			}
			free(pre);  //最后循环结束,释放pre
		}
	}
	free(G);  //释放邻接表指针
}

int main() {
	int A[MAXV][MAXV] = { {0,1,0,1,1},
						  {1,0,1,1,0},
						  {0,1,0,1,1},
						  {1,1,1,0,1},
						  {1,0,1,1,0} };  //我们的邻接矩阵数组
	AdjGraph *G = new AdjGraph;  //邻接表指针
	int n = 5;
	int e = 8;
	CreateAdj(G, A, n, e);  //创建图的邻接表
	DispAdj(G);  //输出图的邻接表
	DestroyAdj(G);  //释放图的邻接表
}

输出结果:在这里插入图片描述
第一列数字表示顶点,中括号前的数字表示顶点,中括号里的数字表示权值,∧表示结尾。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值