图的存储结构及实现
邻接矩阵的存储结构定义
图的邻接矩阵(adjacency matrix)存储也被称为数组表示法,是一个用一维数组存储图中顶点、二维数组存储图中的边(即各顶点之间的邻接关系),存储邻接关系的二维数组被称为邻接矩阵。邻接矩阵又可以分为两种情况:无向图和有向图。
- 对于无向图,顶点i的度等于邻接矩阵中第i行或第i列非零元素的个数
- 判断顶点i和j之间是否存在边,只需要测试邻接矩阵中相应位置的元素edge[i][j],判断取值是否为1
- 找到顶点i的所有邻接点,可依次判别顶点i和其他顶点之间是否有边
C语言代码:
#include<iostream> //邻接矩阵和DFS、BFS
using namespace std;
#define MaxSize 10 //定义最多顶点数量
typedef char DataType; //数据类型
typedef struct { //定义邻接矩阵存储结构
DataType vertex[MaxSize]; //存放顶点的一维数组
int edge[MaxSize][MaxSize]; //存放边的二维矩阵
int vertexNum, edgeNum; //定义图的顶点数和边的数目
}MGraph;
int visited[MaxSize] = {0};
void CreateGraph(MGraph * G, DataType a[], int n, int e) {
int i, j ,k;
G->edgeNum = e; //参数e表示边的数目 边的数目和顶点数目不一样?
G->vertexNum = n; //参数n表示顶点数目
for(int i = 0; i < G->vertexNum; i++) { //存储顶点信息
G->vertex[i] = a[i];
}
for(int i = 0; i < G->vertexNum; i++) { //初始化(邻接矩阵)边缘矩阵
for(int j = 0; j < G->vertexNum; j++) {
G->edge[i][j] = 0;
}
}
printf("请输入存在连通的边缘信息,以像素坐标的形式输入。(0,0)->(5,5)\n 例如0 0表示(0,0)位置设置为连通边缘: \n");
for(int k = 0; k < G->edgeNum; k++) {
scanf("%d %d", &i, &j); //通过键盘输入,设置哪条边是连通的 ; 同时注意这里是无向图,因此是对称矩阵
G->edge[i][j] = 1;
G->edge[j][i] = 1;
}
}
void DFSTraverse(MGraph * G, int v) {
printf("%c ", G->vertex[v]);
visited[v] = 1;
for(int i = 0; i < G->vertexNum; i++) {
if(G->edge[v][i] == 1 && visited[i] == 0) {
DFSTraverse(G, i);
}
}
}
void BFSTraverse(MGraph * G, int v) { //全局变量visited[n]已初始化为0
int i, j, Q[MaxSize]; //采用顺序存储结构,存储顶点编号
int front = -1; //初始化顺序队列
int rear = -1;
printf("%c ", G->edge[v]);
visited[v] = 1;
Q[++rear] = v;
while(front != rear) { //当队列非空时
i = Q[++front]; //将队头元素出队并送到v中
for(int j = 0; j <G->vertexNum; j++) {
if(G->edge[i][j] == 1 && visited[j] == 0) {
printf("%c ", G->vertex[j]);
visited[j] = 1;
Q[++rear] = j;
}
}
}
}
int main() {
int i;
char ch[] = {'A', 'B', 'C', 'D', 'E'};
MGraph MG;
CreateGraph(&MG, ch, 5, 6); //创建无向图,有5个顶点和6条边,这是在ch矩阵中设置的
for(int i = 0; i < MaxSize; i++) {
visited[i] = 0;
}
printf("深度优先遍历DFS结果为: ");
DFSTraverse(&MG, 0);
for(int i = 0; i < MaxSize; i++) {
visited[i] = 0;
}
cout<<endl;
printf("广度优先遍历BFS结果为: ");
BFSTraverse(&MG, 0);
system("pause");
return 0;
}
邻接表的存储结构定义
C语言代码:
#include<iostream> //有向图邻接表 adjacency list
using namespace std;
#define MaxSize 10
typedef char DataType; //定义数据类型
typedef struct EdgeNode { //定义顶点表节点
int adjvex;
struct EdgeNode * next;
}EdgeNode;
typedef struct { //定义邻接表存储结构
DataType vertex;
EdgeNode * first;
}VertexNode;
typedef struct {
VertexNode adjlist[MaxSize]; //存放顶点表的数组
int vertexNum, edgeNum; //图的顶点数和边数
}ALGraph;
int visited[MaxSize] = {0};
void CreateGraph(ALGraph * G, DataType a[], int n, int e) {
int i, j, k;
EdgeNode * s = NULL;
G->vertexNum = n;
G->edgeNum = e;
for(int i = 0; i < G->vertexNum; i++) {
G->adjlist[i].vertex = a[i]; //存储顶点的信息
G->adjlist[i].first = NULL; //初始化边表的头指针
}
for(int k = 0; k < G->edgeNum; k++) {
scanf("%d %d", &i, &j); //输入边所依附的顶点编号
s = (EdgeNode *)malloc(sizeof(EdgeNode));
s->adjvex = j;
s->next = G->adjlist[i].first; //将s插入到第i个边表的表头
G->adjlist[i].first = s;
}
}
void DestroyGraph(ALGraph * G) {
EdgeNode * p = NULL,
* q = NULL;
for(int i = 0; i < G->vertexNum; i++) {
p = q = G->adjlist[i].first;
while(p != NULL) {
p = p->next;
free(q);
q = p;
}
}
}
void DFSTraverse(ALGraph * G, int v) {
EdgeNode * p = NULL;
int j;
printf("%c ", G->adjlist[v].vertex);
visited[v] = 1;
p = G->adjlist[v].first; //工作指针p指向顶点v的边表
while(p != NULL) { //依次搜索顶点v的邻接点j
j = p->adjvex;
if(visited[j] == 0) {
DFSTraverse(G, j);
}
p = p->next;
}
}
void BFSTraverse(ALGraph * G, int v) {
EdgeNode * p = NULL;
int Q[MaxSize], front = -1, rear = -1, j; //队列采用顺序存储
printf("%c ", G->adjlist[v].vertex);
visited[v] = 1;
Q[++rear] = v;
while(front != rear) { //当队列非空时
v = Q[++front];
p = G->adjlist[v].first; //工作指针p指向顶点v的边表
while(p != NULL) {
j = p->adjvex; //j为顶点v的邻接点
if(visited[j] == 0) {
printf("%c ", G->adjlist[j].vertex);
visited[j] = 1;
Q[++rear] = j;
}
p = p->next;
}
}
}
int main() {
char ch[] = {'A', 'B', 'C', 'D', 'E'};
int i;
ALGraph ALG;
CreateGraph(&ALG, ch, 5, 6); //建立具有5个顶点6条边的有向图
for(int i = 0; i < MaxSize; i++) {
visited[i] = 0;
}
printf("深度优先遍历DFS结果为: ");
DFSTraverse(&ALG, 0); //从顶点0开始进行深度优先搜索
for(int i = 0; i < MaxSize; i++) {
visited[i] = 0;
}
cout<<endl;
printf("广度优先遍历BFS结果为: ");
BFSTraverse(&ALG, 0); //从顶点0开始进行广度优先搜索
DestroyGraph(&ALG); //销毁表,回收内存
system("pause");
return 0;
}