数据结构-图的实现以及基础算法-C语言实现
Posted OpenAll_Zzz
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构-图的实现以及基础算法-C语言实现相关的知识,希望对你有一定的参考价值。
文章目录
0. 必要的说明
- 由于是用C语言编写并且图这一章中代码复用性很强,所以在写的时候都是建立工程分文件来写的,考虑一部分同学的特殊需要,笔者重新组织了所有的源文件(xxx.c)和头文件(xxx.h),并成为一个源文件,方便大家利用。最后考虑到在进行编译源文件和链接到相关的函数、变量以及声明时的顺序被无意打乱,程序可能跑不过,这种情况按下面红字操作。
- 有需要查看工程文件的伙伴可以点击这里进入代码仓库下载。
- 如果你的编译器是VS2019或者以往版本,那么你只需要复制一份代码到你的VS2019上再按下Fn + F5即可;如果你的编译器是CodeBlocks或者Dev C++等等其他的,那么你需要将每一个程序的第一行代码
#define _CRT_SECURE_NO_WARNINGS 1
删除后再将代码复制到你的编译器上运行。 - 你的支持和鼓励是我创作的最大动力😉!
1. 图的实现
1.1 图的邻接矩阵实现
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
// 图的结点的数据类型为Char
typedef char VertexDataType;
// 边的权值类型为Int
typedef int EdgeWeightDataType;
typedef struct
VertexDataType* setsOfVertex; // 一维数组存储顶点的值
EdgeWeightDataType** AdjacencyMatrix; // 二维数组表示邻接矩阵
int numsOfVertex; // 顶点的个数
int numsOfEdge; // 边的条数
int MaxSizeCnt; // 限制顶点的最大个数
MatrixGraph; // 邻接矩阵表示图的结构
void InitGraph(MatrixGraph* Graph, int n); // 初始化图的结构
void InsertVertex(MatrixGraph* Graph, VertexDataType vertex); // 在图中插入顶点
void InsertEdge(MatrixGraph* Graph, int v1, int v2, EdgeWeightDataType weight); // 添加顶点间的联系
void ShowMatrix(MatrixGraph* Graph); // 显示图的邻接矩阵表示
int main()
MatrixGraph graph;
InitGraph(&graph, 5);
// 添加顶点
InsertVertex(&graph, 'A'); // index 0
InsertVertex(&graph, 'B'); // index 1
InsertVertex(&graph, 'C'); // index 2
InsertVertex(&graph, 'D'); // index 3
InsertVertex(&graph, 'E'); // index 4
// 添加顶点间的关系
InsertEdge(&graph, 0, 1, 1);
InsertEdge(&graph, 0, 3, 1);
InsertEdge(&graph, 1, 2, 1);
InsertEdge(&graph, 1, 4, 1);
InsertEdge(&graph, 2, 3, 1);
InsertEdge(&graph, 2, 4, 1);
// 展示无向图的邻接矩阵
ShowMatrix(&graph);
return 0;
// 初始化图的结构
void InitGraph(MatrixGraph* Graph, int n)
Graph->setsOfVertex = (VertexDataType*)malloc(sizeof(VertexDataType) * n);
Graph->AdjacencyMatrix = (EdgeWeightDataType**)malloc(sizeof(int*) * n);
for (int i = 0; i < n; i++)
Graph->AdjacencyMatrix[i] = (EdgeWeightDataType*)malloc(sizeof(EdgeWeightDataType) * n);
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
Graph->AdjacencyMatrix[i][j] = 0;
Graph->numsOfEdge = 0;
Graph->numsOfVertex = 0;
Graph->MaxSizeCnt = n;
// 在图中插入顶点
void InsertVertex(MatrixGraph* Graph, VertexDataType vertex)
if (Graph->numsOfVertex <= Graph->MaxSizeCnt)
Graph->setsOfVertex[Graph->numsOfEdge] = vertex;
Graph->numsOfVertex++;
// 添加顶点间的联系
void InsertEdge(MatrixGraph* Graph, int v1, int v2, EdgeWeightDataType weight)
Graph->AdjacencyMatrix[v1][v2] = weight;
Graph->AdjacencyMatrix[v2][v1] = weight;
Graph->numsOfEdge++;
// 显示图的邻接矩阵表示
void ShowMatrix(MatrixGraph* Graph)
printf("\\n\\n\\n");
for (int i = 0; i < Graph->numsOfVertex; i++)
printf(" [ ");
for (int j = 0; j < Graph->numsOfVertex; j++)
if (j != Graph->numsOfVertex - 1)
printf("%d ", Graph->AdjacencyMatrix[i][j]);
else
printf("%d ", Graph->AdjacencyMatrix[i][j]);
printf("]");
printf("\\n");
1.2 图的邻接表实现
#define _CRT_SECURE_NO_WARNINGS 1
#define MAX_VERTEXNUMS 70 // 最大顶点个数
#include <stdio.h>
#include <stdlib.h>
typedef char VertexDataType; // 顶点所储存数据的类型
typedef int EdgeWeightDataType; // 边的权值类型
// 边结点(的结构)
typedef struct GraphEdgeNode
int adjVertexIndex; // 邻接结点的索引
struct GraphEdgeNode* p_nextEdge; // 下一条边的地址
EdgeWeightDataType infoOfEdge; // 边的信息
EdgeNode;
// 顶点(的结构)
typedef struct GraphVertexNode
VertexDataType val;
EdgeNode* p_firstAdjEdge; // 指向第一条邻接该顶点的边
VertexNode;
// 邻接表所表示的图所包含的信息
typedef struct
VertexNode* setsOfVertex; // 每个顶点所表示的关系表
int vertexNums; // 图中顶点数
int edgeNums; // 图中所存在的关系(边)的个数
ALGraph;
void BuildALGraph(ALGraph* graph); // 采用邻接表法构建无向图
int SearchVertexRetIndex(ALGraph* graph, VertexDataType val); // 在图中寻找值为val的顶点的索引
void showALGraph(ALGraph* graph); // 显示邻接表中的信息
#define _CRT_SECURE_NO_WARNINGS 1
#include "GraphOperationsStatement.h"
int main()
ALGraph graph;
BuildALGraph(&graph);
showALGraph(&graph);
return 0;
// 采用邻接表法构建无向图
void BuildALGraph(ALGraph* graph)
graph->setsOfVertex = (VertexNode*)malloc(sizeof(VertexNode) * MAX_VERTEXNUMS);
int vertexNums = 0;
int edgeNums = 0;
printf("分别输入顶点和边的个数(num1 num2):\\n");
scanf("%d %d", &vertexNums, &edgeNums);
getchar();
graph->vertexNums = vertexNums;
graph->edgeNums = edgeNums;
// 输入图中各个顶点的信息
for (int i = 0; i < graph->vertexNums; i++)
printf("输入第%d个顶点的信息:\\n", i + 1);
scanf("%c", &(graph->setsOfVertex[i].val));
getchar();
graph->setsOfVertex[i].p_firstAdjEdge = NULL;
// 输入各个边,构建邻接表
VertexDataType v1 = 0;
VertexDataType v2 = 0;
int v1Index = 0;
int v2Index = 0;
for (int i = 0; i < graph->edgeNums; i++)
printf("输入第%d条边所依附的两个结点:\\n", i + 1);
scanf("%c", &v1);
getchar();
scanf("%c", &v2);
getchar();
v1Index = SearchVertexRetIndex(graph, v1);
v2Index = SearchVertexRetIndex(graph, v2);
EdgeNode* newEdgeNode0 = (EdgeNode*)malloc(sizeof(EdgeNode));
newEdgeNode0->adjVertexIndex = v2Index;
newEdgeNode0->p_nextEdge = graph->setsOfVertex[v1Index].p_firstAdjEdge;
graph->setsOfVertex[v1Index].p_firstAdjEdge = newEdgeNode0;
EdgeNode* newEdgeNode1 = (EdgeNode*)malloc(sizeof(EdgeNode));
newEdgeNode1->adjVertexIndex = v1Index;
newEdgeNode1->p_nextEdge = graph->setsOfVertex[v2Index].p_firstAdjEdge;
graph->setsOfVertex[v2Index].p_firstAdjEdge = newEdgeNode1;
// 在图中寻找值为val的顶点的索引
int SearchVertexRetIndex(ALGraph* graph, VertexDataType val)
for (int i = 0; i < graph->vertexNums; i++)
if (graph->setsOfVertex[i].val == val)
return i;
return -1;
// 显示邻接表中的信息
void showALGraph(ALGraph* graph)
EdgeNode* cur = NULL;
printf("\\n");
for (int i = 0; i < graph->vertexNums; i++)
printf("%c->", graph->setsOfVertex[i].val);
cur = graph->setsOfVertex[i].p_firstAdjEdge;
while (cur != NULL)
printf("%d->", cur->adjVertexIndex);
cur = cur->p_nextEdge;
printf("NULL\\n");
2. 图的基础算法
2.1 图的深度优先遍历
#define _CRT_SECURE_NO_WARNINGS 1
#define MAX_SIZEOFVERTEX 70
#include <stdio.h>
#include <stdlib.h>
typedef int VertexDataType; // 顶点所储存数据的类型
typedef int EdgeWeightDataType; // 边的权值类型
// 边结点(的结构)
typedef struct GraphEdgeNode
int adjVertexIndex; // 邻接结点的索引
struct GraphEdgeNode* p_nextEdge; // 下一条边的地址
EdgeWeightDataType infoOfEdge; // 边的信息
EdgeNode;
// 顶点(的结构)
typedef struct GraphVertexNode
VertexDataType val;
EdgeNode* p_firstAdjEdge; // 指向第一条邻接该顶点的边
VertexNode;
// 邻接表所表示的图所包含的信息
typedef struct
VertexNode* setsOfVertex; // 每个顶点所表示的关系表
int vertexNums; // 图中顶点数
int edgeNums; // 图中所存在的关系(边)的个数
int* visited; // 图中顶点是否被访问过的的标志数组
ALGraph;
void InitALGraph(ALGraph* graph); // 初始化无向图
void InsertVertex(ALGraph* graph, VertexDataType val); // 插入值为val的顶点
void InsertEdge(ALGraph* graph, VertexDataType val_1, VertexDataType val_2); // 插入依附顶点val1和val2的边
int SearchVertexRetIndex(ALGraph* graph, VertexDataType val); // 在图中寻找值为val的顶点的索引
void showALGraph(ALGraph* graph); // 显示邻接表中的信息
void DFS_AL(ALGraph* graph, int StartVertexIndex); // 对无向图进行深度优先遍历
int main()
ALGraph graph;
InitALGraph(&graph);
InsertVertex(&graph, 1);
InsertVertex(&graph, 2);
InsertVertex(&graph, 3);
InsertVertex(&graph, 4);
InsertVertex(&graph, 5);
InsertVertex(&graph, 6);
InsertVertex(&graph, 7);
InsertEdge(&graph, 1, 3);
InsertEdge(&graph, 1, 2);
InsertEdge(&graph, 3, 2);
InsertEdge(&graph, 2, 5);
InsertEdge(&graph, 2, 4);
InsertEdge(&graph, 5, 7);
InsertEdge(&graph, 5, 6);
showALGraph(&graph);
printf("无向连通图的优先深度遍历结果:\\n");
DFS_AL(&graph, 0);
return 0;
// 初始化无向图
void InitALGraph(ALGraph* graph)
graph->setsOfVertex = (VertexNode*)malloc(sizeof(VertexNode) * MAX_SIZEOFVERTEX );
graph->edgeNums = 0;
graph->vertexNums = 0;
graph->visited = (int*)malloc(sizeof(int) * MAX_SIZEOFVERTEX );
// 插入值为val的顶点
void InsertVertex(ALGraph* graph, VertexDataType val)
graph->setsOfVertex[graph->vertexNums].val = val;
graph->setsOfVertex[graph->vertexNums].p_firstAdjEdge = NULL;
graph->visited[graph->vertexNums] = 0;// 初始化插入时的结点未被访问
graph->vertexNums++;
// 插入依附顶点val1和val2的边
void InsertEdge(ALGraph* graph, VertexDataType val_1, VertexDataType val_2)
int v1Index = 0;
int v2Index = 0;
v1Index = SearchVertexRetIndex(graph, val_1);
v2Index = SearchVertexRetIndex(graph, val_2);
// 无向图需要关联到一条边所依附的两个顶点,即联系X->Y的同时,也需要联系Y->X
// 头插结点来构建每个顶点的邻接关系
// X->Y
EdgeNode* newEdgeNode0 = (EdgeNode*)malloc(sizeof(EdgeNode));
if (newEdgeNode0 == NULL)
exit(0);
newEdgeNode0->adjVertexIndex = v2Index;
newEdgeNode0->p_nextEdge = graph->setsOfVertex[v1Index].p_firstAdjEdge;
graph->setsOfVertex[v1Index].p_firstAdjEdge = newEdgeNode0;
// Y->X
EdgeNode* newEdgeNode1 = (EdgeNode*)malloc(sizeof(EdgeNode));
if (newEdgeNode1 == NULL)
exit(0);
newEdgeNode1->adjVertexIndex = v1Index;
newEdgeNode1->p_nextEdge = graph->setsOfVertex[v2Index].p_firstAdjEdge;
graph->setsOfVertex[v2Index].p_firstAdjEdge = newEdgeNode1;
graph->edgeNums++;
以上是关于数据结构-图的实现以及基础算法-C语言实现的主要内容,如果未能解决你的问题,请参考以下文章
数据结构C语言版 图的遍历 DFS和BFS算法,用邻接矩阵储存 急阿在线等 求大神指点
求算法,用邻接矩阵和邻接表创建一个图,实现深度和广度搜索,菜单形式,c语言的代码。无向无权的图。