图的两种表示方式

文件目录


图:
图是线性表和树的结合,图中任意两个数据对象之间都可能存在某种特定关系
两部分构成:结点和边,结点必不可少
存储:

邻接矩阵

书写:
1、二维数组存储边,其中的数据1表示右边,0表示无边;对于有权重的图,存储的数据也可以为权重
2、会有一个一维数组进行数据来代表各个结点,其下标被二维数组所使用

缺点:表中的数据一半都是重复的,浪费了空间和时间,更多的用于数据比较多的表

代码实现
基本思路:

  • 定义图
  • 定义边
  • 初始化图
  • 插入边中的元素
  • 建立图
  1. 构造图
  • 做好数据初始化的操作
  • 给图做一个定义:包含顶点数、边、二维数组为矩阵,存放数据的位置
  • 这里将邻接矩阵的图称为MGraph
#define MaxVertexNum 100  /*最大顶点数设为100*/
#define INFINITY 65535 /*用作当数据未被访问到*/
typedef int Vertex; /*用顶点的下标表示顶点*/
typedef int WeightType; /*设置边的权值*/
typedef char DataType; /*顶点存储的数据类型*/

typedef struct GNode* PtrToGNode;
struct GNode {
	int Nv; /*顶点数*/
	int Ne;/*边*/
	WeightType G[MaxVertexNum][MaxVertexNum];/*邻接矩阵*/
	DataType Data[MaxVertexNum];/*存放数据*/
};
typedef PtrToGNode MGraph;
  1. 构造边
  • V1、V2为有向边的两端;
  • weight表示权重
//构造边
typedef struct ENode* PtrToENode;
struct ENode {
	Vertex V1, V2;
	WeightType weight;
};
typedef PtrToENode Edge;
  1. 初始化图
  • 传入元素为顶点的数目
  • 为Graphmalloc申请一块空间
  • 将Graph中的每一个元素存储为最大值(便于之后与访问过区分开来)
//初始化
MGraph CreateGraph(int VertexNum)
{
	Vertex V, M;
	MGraph Graph;

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

	for (V = 0; V < Graph->Nv; V++)
	{
		for (M = 0; M < Graph->Nv; M++)
		{
			Graph->G[V][M] = INFINITY;
		}
	}
	return Graph;
}
  1. 插入元素
  • 传入数据为图、边
  • 对图中的数据进行更新
void InsertEdge(MGraph Graph, Edge E)
{
	Graph->G[E->V1][E->V2] = E->weight;
	Graph->G[E ->V2][E->V1] = E->weight;//无向图为什么也要插入边呢
}

5、建立图

  • 通过输入有多少顶点的值、边的值来进行元素的插入、图的构建
MGraph BuidGraph()
{
	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;

}

邻接表

邻接表:头节点为一个数组,不同的数据下标代表不同链表的头部,其中每一个头节点后面跟上一串链表,链表中是从头节点到其它结点能通的路线

实现
1、定义关于邻接表的图
2、定义一个头结点的数组
3、有一个结构体存放每一个结点
4、每一条边

代码实现
1、定义图

  • 顶点数
  • 边数
  • 邻接表
    邻接表为LGraph
#define MaxVertexNum 100
typedef int Vertex;
typedef int WeightType;
typedef char DataType;

#include <stdlib.h>


//图结点的定义
typedef struct GNode* PtrToGNode;
struct GNode {
	int Nv;  //顶点数
	int Ne;//边数
	AdjList G;//邻接表
};
typedef PtrToGNode LGraph;

2、定义头节点数组
包含:一条指向结点的指针 进行数据存储

//头结点
typedef struct Vnode {
	PtrToAdjVNode FirstEdge;
	DataType Data; //很多时候顶点无数据,故Data可以不出现
}AdjList[MaxVertexNum];//一共有多少个顶点就有多大

3、存放每一个结点
需要存储:终点的数据、权重、指向下一个的指针

//每一个结点  -----放在每一个顶点的链表里面---只需要存储它的终点即可
typedef struct AdjVNode* PtrToAdjVNode;
struct AdjVNode {
	Vertex AdjV;
	WeightType Weight;  //有权图需要存储权重
	PtrToAdjVNode Next;
};

4、每一条边

//每一个结点  -----放在每一个顶点的链表里面---只需要存储它的终点即可
typedef struct AdjVNode* PtrToAdjVNode;
struct AdjVNode {
	Vertex AdjV;
	WeightType Weight;  //有权图需要存储权重
	PtrToAdjVNode Next;
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值