邻接矩阵
概念 :图的邻接矩阵存储方式是用两个数组来表示图,一个一维数组存储图中顶点信息,一个二维数组(称为邻接矩阵)存储图中的边或弧的信息。
无向邻接矩阵的结构定义
#include<stdio.h>
typedef char VertexType; //顶点类型
typedef int EdgeType; //边的权值类型
#define MAXVEX 100
#define INFINITY 65535 //表示无穷大
typedef struct {
VertexType vexts[MAXVEX]; //顶点表
EdgeType arc[MAXVEX][MAXVEX]; //邻接矩阵
int numNodes, numEdges; //图当前顶点数与边数
}MGraph;
建立无向网图的邻接矩阵
LocateVex()函数用来查找顶点
/* 建立无向网图的邻接矩阵 */
void CreateMGraph(MGraph* G)
{
int weight; //表示权值
scanf("%d%d", &G->numNodes, &G->numEdges); //输入顶点数与边数
for (int i = 0; i < G->numNodes; i++) //读入顶点数据,建立顶点表
scanf(" %c", &G->vexts[i]);
for (int i = 0; i < G->numNodes; i++)
for (int j = 0; j < G->numNodes; j++)
G->arc[i][j] = INFINITY; //邻接矩阵初始化
//构造
for (int k = 0; k < G->numEdges; k++)
{
VertexType v1, v2;
int i, j; //用来返回下标
scanf(" %c %c %d", &v1, &v2, &weight);
i = LocateVex(*G, v1);
j = LocateVex(*G, v2);
G->arc[i][j] = weight; //边<v1, v2>的权值
G->arc[j][i] = G->arc[i][j]; //边<v1, v2>的对称边同样为weight
}
}
/* 查找顶点,返回下标 */
int LocateVex(MGraph G, VertexType e)
{
for (int i = 0; i < G.numNodes; i++)
if (e == G.vexts[i])
return i;
return -1;
}
邻接表
概念 :
邻接表,存储方法跟树的孩子链表示法相类似,是一种顺序分配和链式分配相结合的存储结构。如这个表头结点所对应的顶点存在相邻顶点,则把相邻顶点依次存放于表头结点所指向的单向链表中。
简单来说:给图中的各个结点独自建立一个链表,用链表存储该结点所有的邻接点以及权值,用数组与链表相结合的存储结构称为邻接表。
无向图的邻接表结构定义
#include<stdio.h>
#include<stdlib.h>
typedef char VertexType; //顶点类型
typedef int EdgeType; //边上权值
#define MAXVEX 100 // 最大顶点数
typedef struct EdgeNode { //边表结点
int adjvex; //领接点域,存储对应下标
EdgeType info; //存储权值,如果是非网图可以省略
struct EdgeNode* next; //指向下一个邻接点
}EdgeNode;
typedef struct VertexNode { //顶点结点
VertexType data; //顶点域
EdgeNode* firstedge; //边表头指针
}VertexNode;
typedef struct VertexNode AdjList[MAXVEX]; //邻接表类型
typedef struct {
AdjList adjList;
int numNodes, numEdges; //图当前顶点数与边数
}GraphAdjList;
建立无向图的邻接表
LocateVex()函数用来查找顶点
/* 建立图的邻接表结构 */
void CreateALGRAph(GraphAdjList* G)
{
scanf("%d%d", &G->numNodes, &G->numEdges); //输入顶点数与边数
for (int i = 0; i < G->numNodes; i++) //建立顶点表
{
scanf(" %c", &G->adjList[i].data);
G->adjList[i].firstedge = NULL; //边表置为空
}
for (int k = 0; k < G->numEdges; k++) //建立边表
{
VertexType v1, v2;
int i, j; //用来返回下标
scanf(" %c %c", &v1, &v2); //输入一条边依附的两个顶点
i = LocateVex(*G, v1);
j = LocateVex(*G, v2);
EdgeNode* e1 = (EdgeNode*)malloc(sizeof(EdgeNode)); //生成边表结点(指针e指向生成的内存空间)
e1->adjvex = j; //邻接序号
/* 头插法 */
e1->next = G->adjList[i].firstedge; //e指向当前顶点指向结点
G->adjList[i].firstedge = e1; //当前顶点指向e
EdgeNode* e2 = (EdgeNode*)malloc(sizeof(EdgeNode)); //生成边表结点
e2->adjvex = i; //邻接序号
/* 头插法 */
e2->next = G->adjList[j].firstedge; //e指向当前顶点指向结点
G->adjList[j].firstedge = e2; //当前顶点指向e
//对于无向图,一条边对应两顶点,所以上面一次对 i 和 j 插入
}
}
/* 查找顶点 */
int LocateVex(GraphAdjList G, VertexType v)
{
for (int i = 0; i < G.numNodes; i++)
if (v == G.adjList[i].data)
return i;
return -1;
}