数据结构(图--邻接矩阵法实现)

本文介绍了图的基本概念,包括有向图和无向图,并详细解释了度和权的概念。通过使用邻接矩阵的方式实现了图的各种操作,如创建、销毁图、添加和删除边等。此外,还提供了完整的代码示例,帮助读者更好地理解和掌握图的相关操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

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

 

图分为有向图和无向图

 

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

 

这里介绍图的常用操作:

l 创建图

l 销毁图

l 清空图的边

l 在图中两个顶点连接起来,并带权

l 删除两个顶点的边,把权返回

l 返回图中某两个顶点之间边的权值

l 返回图中某个顶点的度

l 返回图中顶点数

l 返回图中的边数

l 输出图

代码总分为三个文件:

       MGraph.h , MGraph.c , Main.c  

整体结构图为:

    

简单说下邻接矩阵:

        这里就不再详细介绍图的一些操作细节,因为是用邻接矩阵实现的,也就是用一个二维数组实现的,所以大部分操作都类似于二维数组操作,只要细细阅读代码就会理解的。

OK! 上代码:

MGraph.h , 

[cpp]  view plain  copy
  1. #ifndef _MGRAPH_H_  
  2. #define _MGRAPH_H_  
  3.   
  4. typedef void MGraph;  
  5. typedef void MVertex;  
  6. typedef void (MGraph_Printf)(MVertex*);  
  7.   
  8. /* 创建并返回有n个顶点的图 */  
  9. MGraph* MGraph_Create(MVertex** v, int n);  
  10.   
  11. /* 销毁graph所指向的图 */  
  12. void MGraph_Destory(MGraph* graph);  
  13.   
  14. /* 将graph所指图的边集合清空 */  
  15. void MGraph_Clear(MGraph* graph);  
  16.   
  17. /* 在graph所指图中的v1和v2之间加上边,且边的权为w */  
  18. int MGraph_AddEdge(MGraph* graph, int v1, int v2, int w);  
  19.   
  20. /* 将graph所指图中v1和v2之间的边删除,返回权值 */  
  21. int MGraph_RemoveEdge(MGraph* graph, int v1, int v2);  
  22.   
  23. /* 将graph所指图中v1和v2之间的边的权值返回 */  
  24. int MGraph_GetEdge(MGraph* graph, int v1, int v2);  
  25.   
  26. /* 将graph所指图中v顶点的度数 */  
  27. int MGraph_TD(MGraph* graph, int v);  
  28.   
  29. /* 将graph所指图中的顶点数返回 */  
  30. int MGraph_VertexCount(MGraph* graph);  
  31.   
  32. /* 将graph所指图中的边数返回 */  
  33. int MGraph_EdgeCount(MGraph* graph);  
  34.   
  35. /* 将graph所指图输出 */  
  36. void MGraph_Display(MGraph* graph, MGraph_Printf* pFunc);  
  37.   
  38. #endif  


 

MGraph.c , 

[cpp]  view plain  copy
  1. #include <malloc.h>  
  2. #include <stdio.h>  
  3. #include "MGraph.h"  
  4.   
  5. typedef struct _tag_MGraph//定义图   
  6. {  
  7.     int count;  
  8.     MVertex** v;  
  9.     int** matrix;  
  10. }TMGraph;  
  11.   
  12. MGraph* MGraph_Create(MVertex** v, int n)  
  13. {  
  14.     TMGraph* ret = NULL;  
  15.       
  16.     if((NULL!=v) && (0<n))  
  17.     {  
  18.         ret = (TMGraph*)malloc(sizeof(TMGraph));  
  19.           
  20.         if(NULL != ret)  
  21.         {  
  22.             int* p = NULL;  
  23.               
  24.             ret->count = n;  
  25.             //通过二级指针动态申请一维指针数组   
  26.             ret->v = (MVertex**)malloc(sizeof(MVertex*) * n);  
  27.             ret->matrix = (int**)malloc(sizeof(int*) * n);  
  28.               
  29.             //通过一级指针申请数据空间  
  30.             //calloc函数把申请的数据空间全清0   
  31.             p = (int*)calloc(n * n, sizeof(int));  
  32.               
  33.             if((NULL!=ret->v) && (NULL!=ret->matrix) && (NULL!=p))  
  34.             {  
  35.                 int i = 0;  
  36.                   
  37.                 for(i=0; i<n; i++)  
  38.                 {//把指针数组和数据空间连接起来   
  39.                     ret->v[i] = v[i];  
  40.                     ret->matrix[i] = p + i* n;  
  41.                 }     
  42.             }  
  43.             else  
  44.             {  
  45.                 free(ret->v);  
  46.                 free(ret->matrix);  
  47.                 free(p);  
  48.                 free(ret);  
  49.                   
  50.                 ret = NULL;   
  51.             }     
  52.         }  
  53.     }  
  54.       
  55.     return ret;  
  56. }  
  57.   
  58. void MGraph_Destory(MGraph* graph)  
  59. {  
  60.     TMGraph* tGraph = (TMGraph*)graph;  
  61.       
  62.     if(NULL != tGraph)  
  63.     {  
  64.         free(tGraph->v);  
  65.         //销毁通过一级指针申请的数据空间   
  66.         free(tGraph->matrix[0]);  
  67.         //销毁通过二级指针申请的一维指针空间   
  68.         free(tGraph->matrix);  
  69.         free(tGraph);  
  70.     }  
  71. }  
  72.   
  73. void MGraph_Clear(MGraph* graph)  
  74. {  
  75.     TMGraph* tGraph = (TMGraph*)graph;  
  76.       
  77.     if(NULL != tGraph)  
  78.     {  
  79.         int i = 0;  
  80.         int j = 0;  
  81.           
  82.         for(i=0; i<tGraph->count; i++)  
  83.         {  
  84.             for(j=0; j<tGraph->count; j++)  
  85.             {//清楚边的信息  保存顶点的信息   
  86.                 tGraph->matrix[i][j] = 0;  
  87.             }  
  88.         }  
  89.     }  
  90. }  
  91.   
  92. int MGraph_AddEdge(MGraph* graph, int v1, int v2, int w)  
  93. {  
  94.     TMGraph* tGraph = (TMGraph*)graph;  
  95.       
  96.     int ret = (NULL!=tGraph);  
  97.     ret = ret && (0 <= v1) && (v1 < tGraph->count);  
  98.     ret = ret && (0 <= v2) && (v2 < tGraph->count);  
  99.     ret = ret && (0 <= w);  
  100.       
  101.     if(ret)  
  102.     {//增加连线也就是给描述边的数组相应位置赋值   
  103.         tGraph->matrix[v1][v2] = w;  
  104.     }  
  105.       
  106.     return ret;  
  107. }  
  108.   
  109. int MGraph_RemoveEdge(MGraph* graph, int v1, int v2)  
  110. {  
  111.     int ret = MGraph_GetEdge(graph, v1, v2);  
  112.       
  113.     if(0 != ret)  
  114.     {//相应的,删除边的信息也就是给相应位置赋空   
  115.         ((TMGraph*)graph)->matrix[v1][v2] = 0;  
  116.     }  
  117.       
  118.     return ret;  
  119. }  
  120.   
  121. int MGraph_GetEdge(MGraph* graph, int v1, int v2)  
  122. {  
  123.     TMGraph* tGraph = (TMGraph*)graph;  
  124.       
  125.     int ret = 0;  
  126.       
  127.     int condition = (NULL != tGraph);  
  128.     condition = condition && (0 <= v1) && (v1 < tGraph->count);  
  129.     condition = condition && (0 <= v2) && (v2 < tGraph->count);  
  130.       
  131.     if(condition)  
  132.     {//从二维数组相应位置取权值   
  133.         ret = tGraph->matrix[v1][v2];  
  134.     }  
  135.       
  136.     return ret;  
  137. }  
  138.   
  139. int MGraph_TD(MGraph* graph, int v)  
  140. {  
  141.     TMGraph* tGraph = (TMGraph*)graph;  
  142.       
  143.     int ret = 0;  
  144.       
  145.     if((NULL != tGraph) && (0 <= v) && (v < tGraph->count))  
  146.     {  
  147.         int i = 0;  
  148.         int j = 0;  
  149.           
  150.         for(i=0; i<tGraph->count; i++)  
  151.         {//直接返回V所在的行和列顶点的总数也就是  出度+入度   
  152.             if(0 != tGraph->matrix[i][v])  
  153.             {  
  154.                 ret++;  
  155.             }  
  156.             if(0 != tGraph->matrix[v][i])  
  157.             {  
  158.                 ret++;  
  159.             }  
  160.         }  
  161.     }  
  162.       
  163.     return ret;  
  164. }  
  165.   
  166. int MGraph_VertexCount(MGraph* graph)  
  167. {  
  168.     TMGraph* tGraph = (TMGraph*)graph;  
  169.       
  170.     int ret = 0;  
  171.       
  172.     if(NULL != tGraph)  
  173.     {  
  174.         ret = tGraph->count;  
  175.     }  
  176.       
  177.     return ret;  
  178. }  
  179.   
  180. int MGraph_EdgeCount(MGraph* graph)  
  181. {  
  182.     TMGraph* tGraph = (TMGraph*)graph;  
  183.       
  184.     int ret = 0;  
  185.       
  186.     if(NULL != tGraph)  
  187.     {  
  188.         int i = 0;  
  189.         int j = 0;  
  190.           
  191.         for(i=0; i<tGraph->count; i++)  
  192.         {  
  193.             for(j=0; j<tGraph->count; j++)  
  194.             {//返回总边数,也就是判断描述边信息的数组的非0值个数   
  195.                 if(0 != tGraph->matrix[i][j])  
  196.                 {  
  197.                     ret++;  
  198.                 }  
  199.             }  
  200.         }  
  201.     }  
  202.       
  203.     return ret;  
  204. }  
  205.   
  206. void MGraph_Display(MGraph* graph, MGraph_Printf* pFunc)  
  207. {  
  208.     TMGraph* tGraph = (TMGraph*)graph;  
  209.       
  210.     if((NULL != tGraph) && (NULL != pFunc))  
  211.     {  
  212.         int i = 0;  
  213.         int j = 0;  
  214.           
  215.         for(i=0; i<tGraph->count; i++)  
  216.         {//输出顶点信息   
  217.             printf("%d: ", i+1);  
  218.             pFunc(tGraph->v[i]);  
  219.             printf(" \n");  
  220.         }  
  221.         printf("\n");  
  222.           
  223.         for(i=0; i<tGraph->count; i++)  
  224.         {  
  225.             for(j=0; j<tGraph->count; j++)  
  226.             {  
  227.                 if(0 != tGraph->matrix[i][j])  
  228.                 {//输出边信息   
  229.                     printf("<");  
  230.                     pFunc(tGraph->v[i]);  
  231.                     printf(", ");  
  232.                     pFunc(tGraph->v[j]);  
  233.                     printf(":  %d", tGraph->matrix[i][j]);  
  234.                     printf(" > \n");  
  235.                 }  
  236.             }  
  237.         }  
  238.         printf("\n");  
  239.     }  
  240. }  


 

Main.c  

[cpp]  view plain  copy
  1. #include <stdio.h>  
  2. #include "MGraph.h"  
  3.   
  4. void print_data(MVertex* v)  
  5. {  
  6.     if(NULL != v)  
  7.     {  
  8.         printf("%s", (char*)v);  
  9.     }  
  10. }  
  11.   
  12. int main(void)  
  13. {  
  14.     MVertex* v[] = {"A""B""C""D""E""F"};  
  15.       
  16.     MGraph* graph = MGraph_Create(v, 6);  
  17.       
  18.     MGraph_AddEdge(graph, 0, 1, 1);  
  19.     MGraph_AddEdge(graph, 0, 2, 1);  
  20.     MGraph_AddEdge(graph, 0, 3, 1);  
  21.     MGraph_AddEdge(graph, 1, 5, 1);  
  22.     MGraph_AddEdge(graph, 1, 4, 1);  
  23.     MGraph_AddEdge(graph, 2, 1, 1);  
  24.     MGraph_AddEdge(graph, 3, 4, 1);  
  25.     MGraph_AddEdge(graph, 4, 2, 1);  
  26.       
  27.     MGraph_Display(graph, print_data);  
  28.       
  29.     printf("2 TD  : %d\n", MGraph_TD(graph, 2));  
  30.     printf("Vertex: %d\n", MGraph_VertexCount(graph));  
  31.     printf("Edge  : %d\n", MGraph_EdgeCount(graph));  
  32.       
  33.     MGraph_Destory(graph);  
  34.       
  35.     return 0;  
  36. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值