一步一步学数据结构之n--n(图--邻接矩阵法实现)

来源:互联网 发布:农村淘宝新版下载安装 编辑:程序博客网 时间:2024/05/16 18:46

 

今天我和大家一起来学习图,首先说下图的定义:

 

图分为有向图和无向图

 

在这里,来一起了解下度和权的概念:

 

这里介绍图的常用操作:

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;}


 

原创粉丝点击