【数据结构与算法】图

图目录

一.图的原理

图在我们的日常生活中,可谓是应用广泛,最长见的就有地图.

图可以是双向的,也可以是单向的.

图是一种由节点和边组成的数据结构.

节点(顶点):图中的基本单位,表示实体。

边:连接两个节点,表示实体之间的关系。

路径:从一个节点到另一个节点的一系列边。

权重:边可以带有权重,表示连接两个节点的成本或距离。

权重就像这个车票一样,当然还可以综合考虑,主要看你最看重的是什么,距离,还是路况等等都可以作为权重.

二.图的表示

图是比较复杂的一种数据结构,直接表示我们不好表示,我们间接表示.

1.邻接列表

就是我们将每个节点作为一个头结点数组,然后后面跟着相关联边的节点.

可以看这个列子:

这样我们就巧妙的将,两个有关联的顶点放在了一起.

但是有一个缺点就是我们要找到目标路径需要遍历节点,因为每个节点相关联边的节点有很多,需要逐一比对,才能知道有没有目标路径.

很像我们的哈希表哦,哈哈.

2.邻接矩阵

这个的优点很明显,就是只需要看数组的值是不是零,不为零就可以走通.

但是缺点同样很明显,那就是如果我们要插入或者删除一个节点,那么会需要重新构建一个二维数组,并且很多空间是浪费的.

所以大多数的情况下,我们都是用的邻接列表,而不是矩阵,除非每个节点都与很多节点相关联.

三.图的结构------邻接表

这里我们就用邻接列表来构建我们的图.

我框的三个部分,就是我们这个结构的主题.

三个层次,我们先从最里面的开始.

这就是与节点关联的边,将邻接的顶点记录下来,还有指向下一个与节点关联的边.

第二部分,就是咱们的顶点.

需要有数据和与之相关联的第一条边.,其他的可以连接在边的后面.

最外面的一层就是这个顶点数组.

这里我们打算动态分配,所以定义的顶点的指针.

四.邻接表的初始化

动态分配顶点数组.

五.邻接表的创建

先输入顶点数和边数,和顶点的数据,并将各个顶点相关联的边设置为空.

输入相关联边的两个顶点数据,进行连接.

因为我们是输入的数据,我们要找到其在数组中的下标,然后再用前插法,插入到顶点之后.

我们边保存的节点就是在数组中的下标位置.

这里权重没有设置.

六.完整代码

cpp 复制代码
#include <iostream>

using namespace std;
#define MaxSize 1024

typedef struct _EdgeNode//与节点连接边的定义
{
	int adjvex;//邻接的顶点
	int weight;//权重
	struct _EdgeNode* next;//下一条边
}EdgeNode;

typedef struct _VertexNode//顶点节点
{
	char data;//节点数据
	EdgeNode* first;//指向邻接第一条边,头节点
}VertexNode,AdjList;

typedef struct _AdjListGraph
{
	AdjList* adjlist;
	int vex;//顶点数
	int edge;//边数
}AdjListGraph;


int Location(AdjListGraph& G, char c);

//图的初始化
void init(AdjListGraph& G)
{
	G.adjlist = new AdjList[MaxSize];
	G.edge = 0;
	G.vex = 0;
}

//图的创建
void Create(AdjListGraph& G)
{
	cout << "请输入图的顶点数以及边数:" << endl;
	cin >> G.vex >> G.edge;
	cout << "请输入相关的顶点:" << endl;
	for (int i = 0; i < G.vex; i++)
	{
		cin >> G.adjlist[i].data;
		G.adjlist[i].first = NULL;
	}

	char v1=0, v2=0;//保存输入顶点的字符
	int i1, i2;//保存顶点在数组中的下标

	cout << "请输入相关联边的顶点:" << endl;
	for (int i = 0; i < G.edge; i++)
	{
		cin >> v1 >> v2;
		i1 = Location(G, v1);
		i2= Location(G, v2);

		if (i1!=-1 && i2!=-1)//寻找到位置
		{
			EdgeNode* temp = new EdgeNode;
			temp->adjvex = i2;
			temp->next = G.adjlist[i1].first;
			G.adjlist[i1].first = temp;
		}
	}
}


//通过顶点对应的字符寻找顶点在图中的邻接点
int Location(AdjListGraph& G, char c)
{
	for (int i = 0; i < G.vex; i++)
	{
		if (G.adjlist[i].data == c)
		{
			return i;
		}
	}
	return -1;
}

2024年8月14日11:39:35

相关推荐
唐诺2 小时前
几种广泛使用的 C++ 编译器
c++·编译器
XH华2 小时前
初识C语言之二维数组(下)
c语言·算法
南宫生3 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
不想当程序猿_3 小时前
【蓝桥杯每日一题】求和——前缀和
算法·前缀和·蓝桥杯
sanguine__3 小时前
Web APIs学习 (操作DOM BOM)
学习
落魄君子3 小时前
GA-BP分类-遗传算法(Genetic Algorithm)和反向传播算法(Backpropagation)
算法·分类·数据挖掘
冷眼看人间恩怨3 小时前
【Qt笔记】QDockWidget控件详解
c++·笔记·qt·qdockwidget
菜鸡中的奋斗鸡→挣扎鸡3 小时前
滑动窗口 + 算法复习
数据结构·算法
红龙创客3 小时前
某狐畅游24校招-C++开发岗笔试(单选题)
开发语言·c++
Lenyiin4 小时前
第146场双周赛:统计符合条件长度为3的子数组数目、统计异或值为给定值的路径数目、判断网格图能否被切割成块、唯一中间众数子序列 Ⅰ
c++·算法·leetcode·周赛·lenyiin