数据结构学习记录——如何建立图(邻接矩阵、邻接表-图节点的结构、创建并初始化、插入变、完整图的建立)

这篇具有很好参考价值的文章主要介绍了数据结构学习记录——如何建立图(邻接矩阵、邻接表-图节点的结构、创建并初始化、插入变、完整图的建立)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

邻接矩阵

图节点的结构

创建并初始化

插入边

完整的图的建立 

邻接表

图节点的结构

创建并初始化

插入边 

完整的图的建立 


邻接矩阵

图节点的结构

#include <stdio.h>
#include <stdlib.h>

#define MaxVertexNum 100 // 最大顶点数

typedef int WeightType; // 边的权重类型

typedef struct GNode* PtrToGNode;

struct GNode 
{
	int Nv; // 顶点数
	int Ne; // 边数
	WeightType G[MaxVertexNum][MaxVertexNum]; // 邻接矩阵
	/* DataType Data[MaxVertexNum]; 存储顶点的数据 */
};

typedef PtrToGNode MGraph; // 以邻接矩阵存储的图类型

定义结构体GNode,其中包含以下成员变量:

  • Nv:表示图中的顶点数。
  • Ne:表示图中的边数。

二维数组表示图的邻接矩阵。它的大小是MaxVertexNum × MaxVertexNum,用于存储顶点之间边的权重或者存在的情况。(无权重且存在边用1表示,无权重且不存在边则用0表示;有权重且存在边用其权重表示,有权重且不存在边则用一个极大值表示。)

其中,DataType Data[MaxVertexNum],可以用来存储与每个顶点相关的其他数据。例如:如果图表示一个社交网络,则可以存储每个顶点的个人资料信息(姓名、性别、年龄等),故而它的类型可以是整型,也可以是结构体类型。

创建并初始化

typedef int Vertex; /* 用顶点下标表示顶点,为整型 */

MGraph CreateGraph(int VertexNum) 
{
	Vertex V, W;
	MGraph Graph;
	Graph = (MGraph)malloc(sizeof(struct GNode));
	Graph->Nv = VertexNum;
	Graph->Ne = 0;

	/* 注意:这里默认顶点编号从0开始,到 Nv-1 */
	for (V = 0; V < Graph->Nv; V++) 
        {
		for (W = 0; W < Graph->Nv; W++) 
                {
			Graph->G[V][W] = 0; /* 如果是有权图,则设为INFINITY */
		}
	}

	return Graph;
}

变量V和W用于遍历图的顶点,Graph用于指向创建的图对象。

随后进入循环将图对象的邻接矩阵中顶点V和顶点W之间的权重(或标记)设置为0,表示它们之间没有边。注意,如果是有权图,则可以将该值设置为无穷大。

最后返回创建的图对象的指针。

插入边

typedef struct ENode* PtrToENode;
struct ENode 
{
	Vertex V1, V2; /* 有向边<V1,V2  >*/
	WeightType Weight; /* 权重  */
};
typedef PtrToENode Edge;

void InsertEdge(MGraph Graph, Edge E)
{
	/* 插入边<V1,V2> */
	Graph->G[E->V1][E->V2] = E->Weight;

	/* 如果是无向图,还要插入边<V2,V1> */
	Graph->G[E->V2][E->V1] = E->Weight;
}

这个函数用于将对应位置的邻接矩阵元素设置为权重值(无权重值则标记为1)。如果是无向图,则还需要将对称位置的元素设置为相同的权重值,以表示双向的边。

完整的图的建立 

输入格式:

MGraph BuildGraph()
{
	MGraph Graph;
	Edge E;
	Vertex V;
	int Nv, i;

	scanf("%d", &Nv);
	Graph = CreateGraph(Nv);
	scanf("%d", &(Graph->Ne));
	if (Graph->Ne != 0)
	{
		E = (Edge)malloc(sizeof(struct ENode));
		for (i = 0; i < Graph->Ne; i++)
		{
			scanf("%d %d %d", &E->V1, &E->V2, &E->Weight);
			InsertEdge(Graph, E);
		}
	}

	/* 如果顶点有数据的话,读入数据 */
	for (V = 0; V < Graph->Nv; V++)
	{
		scanf("%c", &(Graph->Data[V]));
	}
	return Graph;
}

先输入顶点数,然后去创建并初始化一个无边的图;再输入边数,如果没有边数则图建立完毕(如果顶点有数据就需要另外读入数据),可以直接返回图;如果有边数,则先开辟一个临时的变量,读入边的信息及权重存储在这个临时变量中,然后调用插入边的函数。最后返回构建好的图。

如果是为了考试,或者说需要在很短的时间内完成的话,可以改成以下的简化版:

#define MAXN 100
int G[MAXN][MAXN], Nv, Ne;
void BuildGraph_()
{
	int i, j, v1, v2, w;

	scanf("%d", &Nv);
	/* CreateGraph */
	for (i = 0; i < Nv; i++)
	{
		for (j = 0; j < Nv; j++)
		{
			G[i][j] = 0; /* 或INFINITY */
		}
	}
	scanf("%d", &Ne);
	for (i = 0; i < Ne; i++)
	{
		scanf("%d %d %d", &v1, &v2, &w);
		/* InsertEdge */
		G[v1][v2] = w;
		G[v2][v1] = w;
	}
}

邻接表

图节点的结构

#include <stdio.h>
#include <stdlib.h>
#define MaxVertexNum 100 // 最大顶点数
typedef int Vertex;  /* 用顶点下标表示顶点,为整型 */
typedef float DataType;

typedef int WeightType; // 边的权重类型
// 定义指向图节点的指针类型 PtrToGNode
typedef struct GNode* PtrToGNode;

// 图节点结构体定义
struct GNode {
	int Nv;            // 顶点数
	int Ne;            // 边数
	AdjList G;         // 邻接表
};

// 图类型别名定义
typedef PtrToGNode LGraph;


// 邻接表节点结构体定义
typedef struct Vnode {
	PtrToAdjVNode FirstEdge;  // 指向第一个邻接点的指针
	DataType Data;            // 存储顶点的数据
} AdjList[MaxVertexNum];      // 邻接表类型定义


// 邻接表节点指针类型别名定义
typedef struct AdjVNode* PtrToAdjVNode;

// 邻接点结构体定义
struct AdjVNode {
	Vertex AdjV;             // 邻接点下标
	WeightType Weight;       // 边权重
	PtrToAdjVNode Next;      // 指向下一个邻接点的指针
};

创建并初始化

LGraph CreateGraph(int VertexNum)
{
	Vertex V, W;
	LGraph Graph;

	Graph = (LGraph)malloc(sizeof(struct GNode));
	Graph->Nv = VertexNum;
	Graph->Ne = 0;

	for (V = 0; V < Graph->Nv; V++)
	{
		Graph->G[V].FirstEdge = NULL;
	}
	return Graph;
}

这里的初始化要注意的一点是:“Graph->G[V].FirstEdge = NULL;”将当前顶点的邻接表的第一个邻接点指针FirstEdge设置为NULL,表示当前顶点暂时没有邻接点。

插入边 

typedef PtrToENode Edge;

void InsertEdge(LGraph Graph, Edge E)
{
	PtrToAdjVNode NewNode;

	/* 插入边<V1,V2>  */
	/*  先为V2建立新的邻接点 */
	NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));
	NewNode->AdjV = E->V2;
	NewNode->Weight = E->Weight;
	/* 将V2插入V1的表头 */
	NewNode->Next = Graph->G[E->V1].FirstEdge;
	Graph->G[E->V1].FirstEdge = NewNode;

	/* 如果是无向图,还要插入边<V2,V1> */
	NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));
	NewNode->AdjV = E->V1;
	NewNode->Weight = E->Weight;
	/* 将V1插入V2的表头 */
	NewNode->Next = Graph->G[E->V2].FirstEdge;
	Graph->G[E->V2].FirstEdge = NewNode;
}
  1. 为边的顶点V2创建一个新的邻接点(NewNode)。
  2. 将边的顶点V2和权重赋值给新建立的邻接点(NewNode)。
  3. 将新建立的邻接点(NewNode)插入到顶点V1的邻接表的头部。

如果是无向图,则再反过来执行一遍。

 文章来源地址https://www.toymoban.com/news/detail-460238.html

完整的图的建立 

LGraph BuildGraph()
{
	int Nv,i;
	Vertex V;
	LGraph Graph;
	Edge E;

	scanf("%d", Graph->Nv);
	Graph = CreateGraph(Graph->Nv);

	scanf("%d", Graph->Ne);

	if ((Graph->Ne) != 0) 
	{
		E = (Edge)malloc(sizeof(struct ENode));

		printf("Enter the edges (format: V1 V2 Weight):\n");
		for (i = 0; i < Graph->Ne; i++) 
		{
			scanf("%d %d %d", &(E->V1), &(E->V2), &(E->Weight));
			InsertEdge(Graph, E);
		}

		free(E);
	}

	return Graph;
}

与邻接矩阵的实现类似


end


学习自:MOOC数据结构——陈越、何钦铭

 

到了这里,关于数据结构学习记录——如何建立图(邻接矩阵、邻接表-图节点的结构、创建并初始化、插入变、完整图的建立)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【数据结构与算法】图——邻接表与邻接矩阵

    图(Graph)是由顶点的有穷非空集合和顶点之间边的集合组成,通常表示为:G(V,E),其中, G表示一个图,V是顶点的集合,E是边的集合 。 在图中数据元素,我们则称之为顶点(Vertex)。 图中,任意两个顶点之间都可能有关系,顶点之间的逻辑关系用边来表示,边集可以是

    2024年02月02日
    浏览(42)
  • C++数据结构之图的存储结构——邻接矩阵和邻接表实现无向图

    关键点: 1.构建二维数组 2.对应边的位置赋值为1 由于比较简单就直接上代码: 个人对邻接表实现无向图的理解如下,仅供参考:         由于无向图的组成是由多个顶点和多条无向边组成的,因此我们可以把它拆分成两个结构,分别是顶点和无向边,又由于我们是使用

    2024年02月05日
    浏览(55)
  • 【数据结构】邻接矩阵法

    顶点用一维数组Vex表示,其中可存放较为复杂的信息(如下标),边表用二维数组Edge表示,存放边的信息(两顶点之间有直接相连的边为1,否则为0)。  如何求顶点的入度 、出度? 对于无向图  第 i 个节点的度: 该结点所在行列的非0元素个数 对于有向图  第i个节点的

    2024年02月12日
    浏览(60)
  • 数据结构之邻接表

    邻接表是一种表示图的数据结构,它通过链表的形式,将每个节点的邻居节点记录下来。具体原理如下: 对于每个节点,我们创建一个链表。链表中存储该节点所连接的所有边的信息。 对于每条边,我们在两个节点之间的链表中分别存储该边的信息。例如,如果节点A和节点

    2024年02月02日
    浏览(31)
  • 【数据结构】算法题:邻接表构造相应的逆邻接表

    编写算法:根据含有n个顶点的有向图邻接表,构造相应的逆邻接表。 1.算法的思想: 邻接表和逆链接表的 顶点信息是相同的 ,直接复制即可。把 出边信息转换成入边信息 ,则需要逐一访问邻接表的各结点的出边表,把边结点通过头插法插入相应的入边表中。 2.算法的实现

    2024年02月11日
    浏览(48)
  • 数据结构——图篇(邻接矩阵、邻接表、深度优先搜索、广度优先搜索)

    描述 图比树更为复杂,展现的是一种多对多的关系,图的结构是任意两个数据对象之间都可能存在某种特定的关系的数据结构 概念 顶点 : 基本介绍 顶点集合表示为V集合,要求图中顶点至少要有一个,即V集合不能为空集。通常使用|V|来表示顶点的个数,通常使用E(V)来表示

    2024年02月04日
    浏览(41)
  • 24考研数据结构-图的存储结构邻接矩阵

    【1】顶点的结点结构 ——————— | data | firstarc | ——————— data数据域:储存顶点vi firstarc链域:指向链表中第一个结点 【2】弧的结点结构 —————————— | adjvex | info | nextarc | —————————— adjvex邻接点域:与顶点vi邻接的点在图中的位置 info数据域

    2024年02月14日
    浏览(56)
  • 数据结构--图的存储邻接表法

    邻接矩阵: 数组实现的顺序存储,空间复杂度高,不适合存储稀疏图 邻接表: 顺序+链式存储 无向图: 边结点的数量是 2|E|, 整体空间复杂度为 O(|V| + 2|E|) 有向图: 边结点的数量是 |E|, 整体空间复杂度为 O(|V| + |E|) 图的邻接表表示方式并不唯一 color{red}图的邻接表表示方

    2024年02月16日
    浏览(47)
  • 数据结构-邻接矩阵的创建与遍历

    上篇文章已经介绍了邻接矩阵的具体作用与如果利用邻接矩阵寻找相邻顶点,这次介绍重点为邻接矩阵的创建与两种遍历方式 邻接矩阵的创建 其结构体需要能记录顶点、顶点数、边数及邻接矩阵,即 创建方式则为读入边数、顶点数即各边的两个顶点和权值 图的遍历 DFS(深

    2024年02月20日
    浏览(46)
  • 【数据结构】图的创建(邻接矩阵,邻接表)以及深度广度遍历(BFS,DFS)

    图是由顶点集合及顶点间的关系组成的一种数据结构:G = (V, E),其中: 顶点集合V = {x|x属于某个数据对象集}是有穷非空集合; E = {(x,y)|x,y属于V}或者E = {x, y|x,y属于V Path(x, y)}是顶点间关系的有穷集合,也叫 做边的集合。 完全图:在有n个顶点的无向图中,若有n * (n-1)/2条边,

    2024年02月04日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包