今天我和大家一起来学习图,首先说下图的定义:
图分为有向图和无向图
在这里,来一起了解下度和权的概念:
这里介绍图的常用操作:
l 创建图
l 销毁图
l 清空图的边
l 在图中两个顶点连接起来,并带权
l 删除两个顶点的边,把权返回
l 返回图中某两个顶点之间边的权值
l 返回图中某个顶点的度
l 返回图中顶点数
l 返回图中的边数
l 输出图
代码总分为三个文件:
MGraph.h , MGraph.c , Main.c
整体结构图为:
简单说下邻接矩阵:
这里就不再详细介绍图的一些操作细节,因为是用邻接矩阵实现的,也就是用一个二维数组实现的,所以大部分操作都类似于二维数组操作,只要细细阅读代码就会理解的。
OK! 上代码:
MGraph.h ,
- #ifndef _MGRAPH_H_
- #define _MGRAPH_H_
- typedef void MGraph;
- typedef void MVertex;
- typedef void (MGraph_Printf)(MVertex*);
- /* 创建并返回有n个顶点的图 */
- MGraph* MGraph_Create(MVertex** v, int n);
- /* 销毁graph所指向的图 */
- void MGraph_Destory(MGraph* graph);
- /* 将graph所指图的边集合清空 */
- void MGraph_Clear(MGraph* graph);
- /* 在graph所指图中的v1和v2之间加上边,且边的权为w */
- int MGraph_AddEdge(MGraph* graph, int v1, int v2, int w);
- /* 将graph所指图中v1和v2之间的边删除,返回权值 */
- int MGraph_RemoveEdge(MGraph* graph, int v1, int v2);
- /* 将graph所指图中v1和v2之间的边的权值返回 */
- int MGraph_GetEdge(MGraph* graph, int v1, int v2);
- /* 将graph所指图中v顶点的度数 */
- int MGraph_TD(MGraph* graph, int v);
- /* 将graph所指图中的顶点数返回 */
- int MGraph_VertexCount(MGraph* graph);
- /* 将graph所指图中的边数返回 */
- int MGraph_EdgeCount(MGraph* graph);
- /* 将graph所指图输出 */
- void MGraph_Display(MGraph* graph, MGraph_Printf* pFunc);
- #endif
MGraph.c ,
- #include <malloc.h>
- #include <stdio.h>
- #include "MGraph.h"
- typedef struct _tag_MGraph//定义图
- {
- int count;
- MVertex** v;
- int** matrix;
- }TMGraph;
- MGraph* MGraph_Create(MVertex** v, int n)
- {
- TMGraph* ret = NULL;
- if((NULL!=v) && (0<n))
- {
- ret = (TMGraph*)malloc(sizeof(TMGraph));
- if(NULL != ret)
- {
- int* p = NULL;
- ret->count = n;
- //通过二级指针动态申请一维指针数组
- ret->v = (MVertex**)malloc(sizeof(MVertex*) * n);
- ret->matrix = (int**)malloc(sizeof(int*) * n);
- //通过一级指针申请数据空间
- //calloc函数把申请的数据空间全清0
- p = (int*)calloc(n * n, sizeof(int));
- if((NULL!=ret->v) && (NULL!=ret->matrix) && (NULL!=p))
- {
- int i = 0;
- for(i=0; i<n; i++)
- {//把指针数组和数据空间连接起来
- ret->v[i] = v[i];
- ret->matrix[i] = p + i* n;
- }
- }
- else
- {
- free(ret->v);
- free(ret->matrix);
- free(p);
- free(ret);
- ret = NULL;
- }
- }
- }
- return ret;
- }
- void MGraph_Destory(MGraph* graph)
- {
- TMGraph* tGraph = (TMGraph*)graph;
- if(NULL != tGraph)
- {
- free(tGraph->v);
- //销毁通过一级指针申请的数据空间
- free(tGraph->matrix[0]);
- //销毁通过二级指针申请的一维指针空间
- free(tGraph->matrix);
- free(tGraph);
- }
- }
- void MGraph_Clear(MGraph* graph)
- {
- TMGraph* tGraph = (TMGraph*)graph;
- if(NULL != tGraph)
- {
- int i = 0;
- int j = 0;
- for(i=0; i<tGraph->count; i++)
- {
- for(j=0; j<tGraph->count; j++)
- {//清楚边的信息 保存顶点的信息
- tGraph->matrix[i][j] = 0;
- }
- }
- }
- }
- int MGraph_AddEdge(MGraph* graph, int v1, int v2, int w)
- {
- TMGraph* tGraph = (TMGraph*)graph;
- int ret = (NULL!=tGraph);
- ret = ret && (0 <= v1) && (v1 < tGraph->count);
- ret = ret && (0 <= v2) && (v2 < tGraph->count);
- ret = ret && (0 <= w);
- if(ret)
- {//增加连线也就是给描述边的数组相应位置赋值
- tGraph->matrix[v1][v2] = w;
- }
- return ret;
- }
- int MGraph_RemoveEdge(MGraph* graph, int v1, int v2)
- {
- int ret = MGraph_GetEdge(graph, v1, v2);
- if(0 != ret)
- {//相应的,删除边的信息也就是给相应位置赋空
- ((TMGraph*)graph)->matrix[v1][v2] = 0;
- }
- return ret;
- }
- int MGraph_GetEdge(MGraph* graph, int v1, int v2)
- {
- TMGraph* tGraph = (TMGraph*)graph;
- int ret = 0;
- int condition = (NULL != tGraph);
- condition = condition && (0 <= v1) && (v1 < tGraph->count);
- condition = condition && (0 <= v2) && (v2 < tGraph->count);
- if(condition)
- {//从二维数组相应位置取权值
- ret = tGraph->matrix[v1][v2];
- }
- return ret;
- }
- int MGraph_TD(MGraph* graph, int v)
- {
- TMGraph* tGraph = (TMGraph*)graph;
- int ret = 0;
- if((NULL != tGraph) && (0 <= v) && (v < tGraph->count))
- {
- int i = 0;
- int j = 0;
- for(i=0; i<tGraph->count; i++)
- {//直接返回V所在的行和列顶点的总数也就是 出度+入度
- if(0 != tGraph->matrix[i][v])
- {
- ret++;
- }
- if(0 != tGraph->matrix[v][i])
- {
- ret++;
- }
- }
- }
- return ret;
- }
- int MGraph_VertexCount(MGraph* graph)
- {
- TMGraph* tGraph = (TMGraph*)graph;
- int ret = 0;
- if(NULL != tGraph)
- {
- ret = tGraph->count;
- }
- return ret;
- }
- int MGraph_EdgeCount(MGraph* graph)
- {
- TMGraph* tGraph = (TMGraph*)graph;
- int ret = 0;
- if(NULL != tGraph)
- {
- int i = 0;
- int j = 0;
- for(i=0; i<tGraph->count; i++)
- {
- for(j=0; j<tGraph->count; j++)
- {//返回总边数,也就是判断描述边信息的数组的非0值个数
- if(0 != tGraph->matrix[i][j])
- {
- ret++;
- }
- }
- }
- }
- return ret;
- }
- void MGraph_Display(MGraph* graph, MGraph_Printf* pFunc)
- {
- TMGraph* tGraph = (TMGraph*)graph;
- if((NULL != tGraph) && (NULL != pFunc))
- {
- int i = 0;
- int j = 0;
- for(i=0; i<tGraph->count; i++)
- {//输出顶点信息
- printf("%d: ", i+1);
- pFunc(tGraph->v[i]);
- printf(" \n");
- }
- printf("\n");
- for(i=0; i<tGraph->count; i++)
- {
- for(j=0; j<tGraph->count; j++)
- {
- if(0 != tGraph->matrix[i][j])
- {//输出边信息
- printf("<");
- pFunc(tGraph->v[i]);
- printf(", ");
- pFunc(tGraph->v[j]);
- printf(": %d", tGraph->matrix[i][j]);
- printf(" > \n");
- }
- }
- }
- printf("\n");
- }
- }
Main.c
- #include <stdio.h>
- #include "MGraph.h"
- void print_data(MVertex* v)
- {
- if(NULL != v)
- {
- printf("%s", (char*)v);
- }
- }
- int main(void)
- {
- MVertex* v[] = {"A", "B", "C", "D", "E", "F"};
- MGraph* graph = MGraph_Create(v, 6);
- MGraph_AddEdge(graph, 0, 1, 1);
- MGraph_AddEdge(graph, 0, 2, 1);
- MGraph_AddEdge(graph, 0, 3, 1);
- MGraph_AddEdge(graph, 1, 5, 1);
- MGraph_AddEdge(graph, 1, 4, 1);
- MGraph_AddEdge(graph, 2, 1, 1);
- MGraph_AddEdge(graph, 3, 4, 1);
- MGraph_AddEdge(graph, 4, 2, 1);
- MGraph_Display(graph, print_data);
- printf("2 TD : %d\n", MGraph_TD(graph, 2));
- printf("Vertex: %d\n", MGraph_VertexCount(graph));
- printf("Edge : %d\n", MGraph_EdgeCount(graph));
- MGraph_Destory(graph);
- return 0;
- }