图的介绍和邻接矩阵、邻接表的创建(以有向图为例)

小编满血复活,更新力度感人~

先让我们看看有向图长什么样吧

有向图是指节点与节点之间连线是有方向性的。

一.图的介绍

图分为有向图和无向图。

图由许多的节点组成,这些节点我们称为顶点

有向图是指顶点之间的指向有方向性,顶点之间用<x,y>表示;

无向图的顶点之间没有单一的方向,是双向的 顶点之间用(x,y)表示。

对于两个相互连接的(不论有无方向性)顶点,它们互称邻接点

,分为入度和出度,入度是指指向该顶点的边个数,出度是指从这个顶点出去的边的个数,入度和出度相加就是度。

二.邻接矩阵的创建

邻接矩阵是用来表示图中顶点关系的一种方式。

它通过一个二维数组来表示一个图的结点之间的相互关系。

上图!:

这就是一个邻接矩阵, 我们在其中举个例子,假设这个二维数组命名为str。

str[a][d]的值是1, 这说明顶点a可以到顶点d,但str[d][a]是0,说明a到d是单向的。

由此,我们只需要遍历这个图,把所有的位置关系表示出来即可。

#define Maxvex 100
typedef int undform;
typedef struct UND//邻接矩阵
{
	undform form[Maxvex][Maxvex];
}UND;
void CreatUND(Graph* gp, UND* u)//创建邻接矩阵
{
	cout << "---------------------------" << endl;
	cout << "邻接矩阵为:" << endl;
	for (int i = 0; i < gp->vexnum; i++)//邻接矩阵的初始化
	{
		for (int j = 0; j < gp->vexnum; j++)
		{
			u->form[i][j] = 0;
		}
	}
	for (int i = 0; i < gp->vexnum; i++)//邻接矩阵的创建
	{
		Arcnode* arc = gp->vexall[i].Nextarc;
		while (arc)
		{
			u->form[i][arc->arcnode] = 1;
			arc = arc->nextarcnode;
		}
	}
	//邻接矩阵的打印
	cout << " ";
	for (int i = 0; i < gp->vexnum; i++)
	{
		cout << " " << gp->vexall[i].val;
	}
	cout << endl;
	for (int i = 0; i < gp->vexnum; i++)
	{
		cout << gp->vexall[i].val << " ";
		for (int j = 0; j < gp->vexnum; j++)
		{
			cout << u->form[i][j] << " ";
		}
		cout << endl;
	}
}

三.邻接表的创建

邻接表能够利用指针把顶点关系表示出来,就是图的一种创建方式。

先让我们看看邻接表长什么样子吧:

邻接表由顶点表边表两个部分组成 。

顶点表可以理解成是一个结构体数组,图中的顶点依次放入每一个结构体中,每个结构体里除了这个顶点还有一个指向边表的指针,这个指针指向的边表里装着这个顶点所指向的下一个顶点。

边表里头装着的也是顶点,但边表不能作为头节点。

一个定点表结构体(a)指向一个边表(b),这个边表(b)所代表的顶点就是该定点表结构体(a)所代表的顶点指向的,同理,这个边表(b)指向的边表(c),也是该结构体(a)指向的。

typedef char vextype;
#define Maxvex 100
typedef struct arcnode//边表
{
	int arcnode;//
	struct arcnode* nextarcnode;//下一个此根节点指向的边节点
	int weight;//边的权值
}Arcnode;

typedef struct vexnode//节点表
{
	vextype val;//节点值
	Arcnode* Nextarc;//节点指向的第一个边
}Vexnode[Maxvex], onevexnode;

typedef struct Graph//图
{
	Vexnode vexall;//所有的节点作为一个数组
	int vexnum, arcnum;//节点,边的个数
}Graph;
void CreatGraph(Graph* gp)
{
	cout << "节点数:"; cin >> gp->vexnum;
	cout << "边数:"; cin >> gp->arcnum;
	for (int i = 0; i < gp->vexnum; i++)//初始化节点
	{
		cout << "输入第" << i + 1 << "个节点:";
		cin >> gp->vexall[i].val ;
		gp->vexall[i].Nextarc = NULL;
	}
	cout << "进行图的创建:" << endl;
	for (int i = 0; i < gp->arcnum; i++)//图的创建
	{
		char g1, g2;
		cout << "输入第一个节点:"; cin >> g1;
		cout << "输入第二个节点:"; cin >> g2;
		int s1 = Findvex(gp, g1), s2 = Findvex(gp, g2);
		//节点与边的正向链接
		Arcnode* newarc = new Arcnode;
		newarc->arcnode  = s2;
		newarc->nextarcnode = gp->vexall[s1].Nextarc;
		gp->vexall[s1].Nextarc = newarc;
}
int Findvex(Graph* gp, vextype a)//找到对应的节点
{
	int sub;//对应的节点下标
	for (int i = 0; i < gp->vexnum; i++)
	{
		if (gp->vexall[i].val == a)
		{
			sub = i;
			break;
		}
	}
	return sub;
}

创作不易,恳求三连,如有错误,敬请斧正 

  • 26
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 22
    评论
图论中,有向图(Directed Graph)是一种特殊的数据结构,用于表示一组节点(顶点)之间的有方向的连接。有两种常见的数据结构用于表示有向图邻接矩阵邻接表。 **1. 邻接矩阵**: 邻接矩阵是一个二维数组,其中的行代表源节点,列表示目标节点。对于有向图中的每条边 (u, v),矩阵中的元素 A[u][v] 将为 1(或非零值),表示从 u 到 v 有一条有向边。如果不存在这条边,则 A[u][v] 通常为 0 或空。邻接矩阵适合于以下情况: - 求解路径查询或判断两点间是否有路径时,时间复杂度为 O(1)。 - 当的边数相对较多且稠密时,空间效率较高。 **2. 邻接表**: 邻接表则是一个链表数组,每个节点对应一个顶点,链表里存储的是所有指向该节点的边。对于每条边 (u, v),邻接表会有一个链表,其中包含指向从 u 出发到 v 的边的信息。邻接表的主要优点和适用场景是: - 空间效率高,特别适用于稀疏,即边的数量远小于节点数量的平方。 - 插入和删除边的时间复杂度通常为 O(1),因为只需要更新对应的链表。 - 对于求解路径查询,如果使用深度优先搜索(DFS)或广度优先搜索(BFS),邻接表的表现更好,因为它们不需要预先计算所有可能的路径。 **相关问题--:** 1. 邻接矩阵如何表示无向? 2. 什么情况下会选择邻接表而不是邻接矩阵? 3. 如何在邻接表中查找某个顶点的所有出边?
评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

就要 宅在家

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值