图的存储结构
无向图邻接表表示法
1.定义表结点数据结构
关联同一顶点的边,用线性链表存储
#define MAX_VERTEX_NUM 100
typedef struct ArcNode
{
int adjVex; //该边所指向的顶点的位置 数组序号
struct ArcNode *nextArc; //指针域,指向下一个边结点
int weight; //权值
}ArcNode;
2.定义头结点(顶点)数据类型
按编号顺序将顶点数据存储在一维数组中
typedef int VertexType;
typedef struct VNode
{
VertexType data; //顶点数据 v1 v2 v3 v4 v5
ArcNode *firstArc; //指向链表中第一个表结点
}VNode,AdjList[MAX_VERTEX_NUM];
3.定义图的邻接表类型
typedef struct
{
AdjList vertices;
int vexNum; //顶点数
int arcNum; //弧数
// int kind; 图的类型
}ALGraph;
特点
- 邻接表不唯一
- 若无向图有n个顶点、e条边,则其邻接表需n个头结点和2e个表结点。适宜存储稀疏图。
- 无向图中顶点vi的度为第i个单链表中的结点数
有向图邻接表表示法
特点
- 顶点vi的出度为第i个单链表中结点的个数
- 顶点vi的入度为整个单链表中邻接点域值是i-1的结点个数
找出度易,找入度难
逆邻接表
特点
- 顶点vi的入度为第i个单链表中结点的个数
- 顶点vi的出度为整个单链表中邻接点域值是i-1的结点个数
找入度易,找出度难
邻接表
邻接表操作举例:
ALGraph G; //定义了邻接表表示图G
G.vexNum = 5; //图G包含了5个顶点
G.arcNum = 5; //图G包含了5条边
G.vertices[1].data = 'b'; //图G中第二个顶点是b
p = G.vertices[1].firstArc; //指针p指向顶点b的第一天边结点
p -> adjVex = 4; //p指针所指边结点是到下标为4的结点的边
邻接表法创建无向图
算法思想
- 输入总顶点数和总边数rc
- 建立顶点表:依次输入点的信息存入顶点表中,使每个表头结点的指针域firstArc初始化为NULL
- 创建邻接表:依次输入每条边衣服的两个顶点,确定两个顶点的序号i和j,建立边结点,将此边结点分别插入到vi和vj对应的两个边链表的头部
代码实现
#include <stdio.h>
#include <stdlib.h>
#define MAX_VERTEX_NUM 100
typedef char VertexType;
//表结点
typedef struct ArcNode
{
int adjvex; //该边所指向的顶点的位置
struct ArcNode *nextArc;
} ArcNode;
//头结点(顶点)表结点
typedef struct VNode
{
VertexType data;
ArcNode *firstArc;
} VNode, AdjList[MAX_VERTEX_NUM];
//图的邻接表类型
typedef struct
{
AdjList vertices;
int vexNum, arcNum;
} ALGraph;
//创建邻接表
void CreateGraph(ALGraph &G)
{
int i, j, k;
ArcNode *p, *p1, *p2;
//输入总顶点数和边数
scanf("%d%d", &G.vexNum, &G.arcNum);
//输入顶点值,初始化表头结点的指针域
for (i = 0; i < G.vexNum; i++)
{
getchar();
scanf("%c", &G.vertices[i].data);
G.vertices[i].firstArc = NULL;
}
//输入各边 (Vi,Vj)中的下标i,j
for (k = 0; k < G.arcNum; k++)
{
scanf("%d%d", &i, &j); //一个边依附的两个顶点
p1 = (ArcNode *)malloc(sizeof(ArcNode)); //生成一个新的边结点*p1
p1->adjvex = j; //邻接点序号为j
p1->nextArc = G.vertices[i].firstArc;
G.vertices[i].firstArc = p1; //将新结点*p1插入顶点vi的边表头部
//无向图需要生成对称的边结点*p2,有向图不需要
p2 = (ArcNode *)malloc(sizeof(ArcNode)); //生成一个新的边结点*p2
p2->adjvex = i; //邻接点序号为i
p2->nextArc = G.vertices[j].firstArc;
G.vertices[j].firstArc = p2; //将新结点*p2插入顶点vj的边表头部
}
//打印邻接表
for (i = 0; i < G.vexNum; i++)
{
p = G.vertices[i].firstArc;
while (p)
{
printf("(%c,%c)", G.vertices[i].data, G.vertices[p->adjvex].data);
p = p->nextArc;
}
printf("\n");
}
}
int main()
{
ALGraph G;
CreateGraph(G);
}