对“图的存储结构”的理解

图的存储结构

1 邻接矩阵
两个数组来表示图
1)一个【一维数组】存储图的【顶点】信息
2)一个【二维数组】存储图的【边】的信息
a) 无向图
无向图的邻接矩阵是一个 对称矩阵 并且对角线上元素数值为 0
因为无向图只要两个顶点v1,v2之间有边,那么不管是v1 -> v2 还是 v2 -> v1都是有边 
又因为,在图结构中,目前只研究简单图结构(无向图两个顶点之间只有一条边
并且顶点没有到自身的边)所以邻接矩阵对角线上的元素为 0
两个顶点v1,v2之间有边 -> 邻接矩阵中的(v1,v2) = 1; 否则 (v1,v2)= 0

无向图中的度:
顶点所对应的行 或 列 中非0元素的个数,就是该顶点的度

b) 有向图
有向图的邻接矩阵不是一个对称矩阵,但是矩阵主对角线上的值 仍然为 0,原因和无向图中的一样

两个顶点的边是由顺序的 (v1,v2)有边,!= (v2,v1)就有边,正因为这个原因
有向图的邻接矩阵不是对称矩阵

邻接矩阵中的值,比如(v1,v2)的值,就是v1,v2之间的权值

有向图中的度分为,出度,入度,在邻接矩阵中,入度,出度是这样计算的:
入度:顶点所对应的【列】中非0元素的个数
出度:顶点所对应的【行】中非0元素的个数
3)创建邻接矩阵
a) 创建邻接矩阵存储结构
typedef char VertexType;
typedef int EdgeType;
#define Max 100 //最大顶点数
#define INFINITY 65535 //如果两个顶点之间没有权重,就为 无穷大

typedef struct 
{
VertexType vexs[Max]; //存储顶点信息的一维数组
EdgeType arc[Max][Max]; //二维数组组成的邻接矩阵,可看作边表
int numEdge,numVertex; //边数  顶点数
}MGraph;

b) 构造图,给顶点表和邻接矩阵输入数据的过程
void CreatMGraph(MGraph *G)
{
//01 输入边数,顶点数
int i,j;
int numEdge,numVertex;
cout << "输入边数,顶点数: " ;
cin >> numEdge >> numVertex;

//02 输入顶点信息,建立顶点表
cout << "请输入顶点信息: " << endl;
for(i = 0; i < numVertex; i++)
{
cin >> G->vexs[i];
}

//03 初始化邻接矩阵
for(i = 0; i < numEdge; i++)
{
for(j = 0; j < numEdge; j++)
{
G->arc[i][j] = INFINITY;
}
}

//04 输入边信息
for(int k = 0; k < numVertex; k++)
{
cout << "请输入边(v1,v2)两个顶点的下标i,j,以及边权重w" <<endl;
cin >> i >> j >> w;
G->arc[i][j] = w; //边的权重为w
G->arc[j][i] = G->[i][j]; //无向图,矩阵对称
}
}
4)邻接矩阵的缺点:
当图中的表边数较少时,邻接矩阵仍然需要开辟 numVertex*numVertex个空间,这是对内存空间的浪费

2 邻接表
用一个一维数组或单链表记录图中顶点的信息
(data firstedge)data 顶点信息  firstedge第一个邻接点的指针
用一个线性链表存储每个顶点的所有邻接点
(agjvex weight next)agjvex 邻接点在一维数组(顶点表)中的下标 weight 权重   next  下一个结点的指针

邻接表由三部分结构体组成:
typedef char VertexType
typedef int EdgeType

1)记录邻接边信息的结构体 EdgeNode
typedef struct EdgeNode
{
int agjvex; //邻接点域,存储该点对应的下标
EdgeType weight; //存储权重,非网图可以不要
EdgeNode *next; //链域,指向下一个链接点
}EdgeNode;

2)记录顶点信息的结构体 VertexNode
typedef struct VertexNode 
{
int data; //存储顶点数据
EdgeNode *firstedge;//边表头指针,指向与该点组成边的另一个点对应的下标
}VertexNode,AdjList[Max]; //AdjList[Max] 存储顶点信息的一维数组
多个VertexNode类型的元素组成一维数组,存储顶点信息

3)记录当前图中的顶点个数,边的个数  GraphAdjList
typedef struct GraphAdjList 
{
AdjList adjList; 
int numEdge,numVertex; //当前图 的顶点个数,边数
}GraphAdjList;

4)存储邻接边信息 (邻接边是 EdgeNode 类型的) GraphAdjList *G
a) 输入顶点个数numVertex,边的个数numEdge
循环输入顶点信息,建立顶点表,顶点信息存储在AdjList[i].data中
将G->adjList[i].firstedge = null

b) 建立边表
每循环一次,就向内存申请一次的空间e EdgeNode类型,存放邻接边信息,没有某种结构类型来存储,比如数组

输入(Vi,Vj)邻接边 的 序号i,j    
e->adjvex = j;     //顶点i的邻接序号
e->next = G->adjList[i].firstedge; //使用的是单链表中的头插法 将当前顶点的 firstedge 给 e指针指向
G->adjList[i].firstedge = e; //将当前顶点的 firstedge 指向 e

同样,对于下标为j的顶点,它的边表的建立如下:
e->adjvex = i;
e->next = G->adjList[j].firstedge;
G->adjList[j].firstedge = e;

3 十字链表
1)将邻接表和逆邻接表结合起来
2)顶点表结构:
data firstin firstout
data :顶点数据
firstin :顶点的入边的第一个结点
firstout :表示出边表头指针,指向该顶点的出边表中的第一个结点
3)边表结构:
tailvex headvex headlink tailink
tailvex : 弧【起】点在顶点表中的下标
headvex : 弧【终】点在顶点表中的下标
headlink :指入边表指针域,指向【终点相同】的下一条边
tailink : 指出边表指针域,指向【起点相同】的下一条边
4)代码和邻接表的类似:
typedef char VertexType;
typedef int EdgeType;
#define Max 65535

//01 顶点表结构体 VertexNode
typedef struct VertexNode
{
VertexType data;
EdgeNode *firstin;
EdgeNode * firstout;
}VertexNode,AdjList[Max];

//02 边表结构体 EdgeNode
typedef struct EdgeNode
{
int tailvex,headvex;
struct EdgeNode *headlink;
struct EdgeNode *tailink;
}EdgeNode;

//03 顶点数,边数
typedef struct GraphAdjList
{
AdjList adjList;
int numEdge,numVertex;
}GraphAdjList;

//04 建立十字链接表结构
void CreatOrthogonal(GraphAdjList *G)
{
int i,j;
//1 输入顶点个数numVertex,边的个数numEdge
cout << "输入边数,顶点数: ";
cin >> numEdge >> numVertex;
cout << endl;

//2 输入顶点信息,建立顶点表
cout << "输入顶点信息,建立顶点表:" << endl;
for(i = 0; i < numVertex; i++)
{
cin >> G->adjList[i].data;
G->adjList[i].firstin = null; //出入边表为空
G->adjList[i].firstout = null;
}

//3 构建十字链表结构

}

4 邻接多重表
ivex illink jvex jlink

illink : 指向依附顶点ivex的下一条边
jlink : 指向依附顶点jvex的下一条边
ivex jvex  :与某条边依附的两个顶点在顶点表中的下标
 
5 边集数组

begin end weight

部分代码摘抄自《大话数据结构》


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值