c/c++ 图相关的函数(二维数组法)

  • 遍历图
  • 插入顶点
  • 添加顶点间的线
  • 删除顶点
  • 删除顶点间的线
  • 摧毁图
  • 取得与v顶点有连线的第一个顶点
  • 取得与v1顶点,v1顶点之后的v2顶点的之后的有连线的第一个顶点

graph_mtx.h

  1. #ifndef __graph_mtx__
  2. #define __graph_mtx__
  3. #include <stdio.h>
  4. #include <malloc.h>
  5. #include <assert.h>
  6. #include <memory.h>
  7. #define Default_vertex_size 10
  8. #define T char//dai biao ding dian de lei xing
  9. typedef struct GraphMtx{
  10. int MaxVertices;//zui da ding dian shu liang]
  11. int NumVertices;//shi ji ding dian shu liang
  12. int NumEdges;//bian de shu lian
  13. T* VerticesList;//ding dian list
  14. int** Edge;//bian de lian jie xin xi, bu shi 0 jiu shi 1
  15. }GraphMtx;
  16. //chu shi hua tu
  17. void init_graph(GraphMtx* gm);
  18. //打印二维数组
  19. void show_graph(GraphMtx* gm);
  20. //插入顶点
  21. void insert_vertex(GraphMtx* gm, T v);
  22. //添加顶点间的线
  23. void insert_edge(GraphMtx* gm, T v1, T v2);
  24. //删除顶点
  25. void remove_vertex(GraphMtx* gm, T v);
  26. //删除顶点间的线
  27. void remove_edge(GraphMtx* gm, T v1, T v2);
  28. //摧毁图
  29. void destroy_graph(GraphMtx* gm);
  30. //取得与v顶点有连线的第一个顶点
  31. int getNeighbor(GraphMtx* gm, T v);
  32. //取得与v1顶点,v1顶点之后的v2顶点的之后的有连线的第一个顶点
  33. int getNextNeighbor(GraphMtx* gm, T v1, T v2);
  34. #endif

graph_mtx.c

  1. #include "graph_mtx.h"
  2. void init_graph(GraphMtx* gm){
  3. gm->MaxVertices = Default_vertex_size;
  4. gm->NumEdges = gm->NumVertices = 0;
  5. //kai pi ding dian de nei cun kong jian
  6. gm->VerticesList = (T*)malloc(sizeof(T) * (gm->MaxVertices));
  7. assert(NULL != gm->VerticesList);
  8. //创建二维数组
  9. //让一个int的二级指针,指向一个有8个int一级指针的数组
  10. //开辟一个能存放gm->MaxVertices个int一级指针的内存空间
  11. gm->Edge = (int**)malloc(sizeof(int*) * (gm->MaxVertices));
  12. assert(NULL != gm->Edge);
  13. //开辟gm->MaxVertices组,能存放gm->MaxVertices个int的内存空间
  14. for(int i = 0; i < gm->MaxVertices; ++i){
  15. gm->Edge[i] = (int*)malloc(sizeof(int) * gm->MaxVertices);
  16. }
  17. //初始化二维数组
  18. //让每个顶点之间的边的关系都为不相连的
  19. for(int i = 0; i < gm->MaxVertices; ++i){
  20. for(int j = 0; j < gm->MaxVertices; ++j){
  21. gm->Edge[i][j] = 0;
  22. }
  23. }
  24. }
  25. //打印二维数组
  26. void show_graph(GraphMtx* gm){
  27. printf(" ");
  28. for(int i = 0; i < gm->NumVertices; ++i){
  29. printf("%c ", gm->VerticesList[i]);
  30. }
  31. printf("\n");
  32. for(int i = 0; i < gm->NumVertices; ++i){
  33. //在行首,打印出顶点的名字
  34. printf("%c:", gm->VerticesList[i]);
  35. for(int j = 0; j < gm->NumVertices; ++j){
  36. printf("%d ", gm->Edge[i][j]);
  37. }
  38. printf("\n");
  39. }
  40. printf("\n");
  41. }
  42. //插入顶点
  43. void insert_vertex(GraphMtx* gm, T v){
  44. //顶点空间已满,不能再插入顶点了
  45. if(gm->NumVertices >= gm->MaxVertices){
  46. return;
  47. }
  48. gm->VerticesList[gm->NumVertices++] = v;
  49. }
  50. int getVertexIndex(GraphMtx* gm, T v){
  51. for(int i = 0; i < gm->NumVertices; ++i){
  52. if(gm->VerticesList[i] == v)return i;
  53. }
  54. return -1;
  55. }
  56. //添加顶点间的线
  57. void insert_edge(GraphMtx* gm, T v1, T v2){
  58. if(v1 == v2)return;
  59. //查找2个顶点的下标
  60. int j = getVertexIndex(gm, v1);
  61. int k = getVertexIndex(gm, v2);
  62. //说明找到顶点了,并且点之间还没有线
  63. if(j != -1 && k != -1 && gm->Edge[j][k] != 1){
  64. //因为是无方向,所以更新2个值
  65. gm->Edge[j][k] = gm->Edge[k][j] = 1;
  66. //边数加一
  67. gm->NumEdges++;
  68. }
  69. }
  70. //删除顶点间的线
  71. void remove_edge(GraphMtx* gm, T v1, T v2){
  72. if(v1 == v2)return;
  73. //查找2个顶点的下标
  74. int j = getVertexIndex(gm, v1);
  75. int k = getVertexIndex(gm, v2);
  76. //说明找到顶点了,并且点之间还有线
  77. if(j != -1 && k != -1 && gm->Edge[j][k] == 1){
  78. //因为是无方向,所以更新2个值
  79. gm->Edge[j][k] = gm->Edge[k][j] = 0;
  80. //边数减一
  81. gm->NumEdges--;
  82. }
  83. }
  84. //删除顶点
  85. void remove_vertex(GraphMtx* gm, T v){
  86. int k = getVertexIndex(gm, v);
  87. if(-1 == k)return;
  88. //算出和要删除节点相关的边的数量,并减少。
  89. for(int i = 0; i < gm->NumVertices; ++i){
  90. if(gm->Edge[k][i] == 1){
  91. gm->NumEdges--;
  92. }
  93. }
  94. //如果要删除的顶点不是最后一个顶点
  95. if(k != gm->NumVertices - 1){
  96. //把每一列向左移动一列
  97. for(int i = 0; i < gm->NumVertices; ++i){
  98. //把后面内存里的内容移动到前面,并把最后一个元素设置成0
  99. memmove(&(gm->Edge[i][k]), &(gm->Edge[i][k+1]), sizeof(int) * (gm->NumVertices-1-k));
  100. gm->Edge[i][gm->NumVertices - 1] = 0;
  101. }
  102. //把每一行向上移动一行
  103. for(int i = k; i < gm->NumVertices - 1; ++i){
  104. memmove(gm->Edge[i], gm->Edge[i+1], sizeof(int) * (gm->NumVertices-1));
  105. }
  106. memset(gm->Edge[gm->NumVertices - 1], 0, sizeof(int) * (gm->NumVertices - 1));
  107. //memmove(&(gm->Edge[k]), &(gm->Edge[k+1]), sizeof(int*) * (gm->NumVertices-1-k));
  108. //memset(gm->Edge[gm->NumVertices - 1], 0, sizeof(int) * (gm->NumVertices - 1));
  109. //删除点
  110. memmove(&(gm->VerticesList[k]), &(gm->VerticesList[k+1]), sizeof(T) * (gm->NumVertices-1-k));
  111. }
  112. //如果要删除的顶点是最后一个顶点
  113. else{
  114. for(int i = 0; i < gm->NumVertices; ++i){
  115. gm->Edge[i][k] = gm->Edge[k][i] = 0;
  116. }
  117. }
  118. //节点数目减1
  119. gm->NumVertices--;
  120. }
  121. //摧毁图
  122. void destroy_graph(GraphMtx* gm){
  123. free(gm->VerticesList);
  124. for(int i = 0; i < gm->NumVertices; ++i){
  125. free(gm->Edge[i]);
  126. }
  127. free(gm->Edge);
  128. gm->Edge = NULL;
  129. gm->VerticesList = NULL;
  130. gm->MaxVertices = gm->NumVertices = gm->NumEdges = 0;
  131. }
  132. //取得与某顶点有连线的第一个顶点
  133. int getNeighbor(GraphMtx* gm, T v){
  134. int p = getVertexIndex(gm, v);
  135. if(-1 == p)return -1;
  136. for(int i = 0; i < gm->NumVertices; ++i){
  137. if(gm->Edge[p][i] == 1)
  138. return i;
  139. }
  140. return -1;
  141. }
  142. //取得与v1顶点,v1顶点之后的v2顶点的之后的有连线的第一个顶点
  143. int getNextNeighbor(GraphMtx* gm, T v1, T v2){
  144. if(v1 == v2)return -1;
  145. int p1 = getVertexIndex(gm, v1);
  146. int p2 = getVertexIndex(gm, v2);
  147. if(p1 == -1 || p2 == -1)return -1;
  148. for(int i = p2 + 1; i < gm->NumVertices; ++i){
  149. if(gm->Edge[p1][i] == 1)
  150. return i;
  151. }
  152. return -1;
  153. }

graph_mtxmain.c

  1. #include "graph_mtx.h"
  2. int main(){
  3. GraphMtx gm;
  4. //初始化图
  5. init_graph(&gm);
  6. //插入顶点
  7. insert_vertex(&gm, 'A');
  8. insert_vertex(&gm, 'B');
  9. insert_vertex(&gm, 'C');
  10. insert_vertex(&gm, 'D');
  11. insert_vertex(&gm, 'E');
  12. //添加连线
  13. insert_edge(&gm, 'A', 'B');
  14. insert_edge(&gm, 'A', 'D');
  15. insert_edge(&gm, 'B', 'C');
  16. insert_edge(&gm, 'B', 'E');
  17. insert_edge(&gm, 'C', 'E');
  18. insert_edge(&gm, 'C', 'D');
  19. //打印图
  20. show_graph(&gm);
  21. //删除连线
  22. //remove_edge(&gm, 'A', 'B');
  23. //打印图
  24. //show_graph(&gm);
  25. //删除顶点
  26. remove_vertex(&gm, 'A');
  27. //打印图
  28. show_graph(&gm);
  29. //添加顶点
  30. insert_vertex(&gm, 'F');
  31. //添加线
  32. insert_edge(&gm, 'F', 'B');
  33. insert_edge(&gm, 'F', 'C');
  34. insert_edge(&gm, 'F', 'D');
  35. //打印图
  36. show_graph(&gm);
  37. //删除顶点
  38. remove_vertex(&gm, 'D');
  39. //删除线
  40. remove_edge(&gm, 'F', 'B');
  41. //打印图
  42. show_graph(&gm);
  43. //取得与某顶点有连线的第一个顶点
  44. int p = getNeighbor(&gm, 'F');
  45. printf("%d\n", p);
  46. //取得与v1顶点,v1顶点之后的v2顶点的之后的有连线的第一个顶点
  47. int p1 = getNextNeighbor(&gm, 'E', 'B');
  48. printf("%d\n", p1);
  49. //摧毁图
  50. destroy_graph(&gm);
  51. }

c/c++ 图相关的函数(二维数组法)的更多相关文章

  1. c/c++ 图的创建(二维数组法)

    c/c++ 图的创建(二维数组法) 图的概念 图由点和线组成 知道了图中有多少个点,和哪些点之间有线,就可以把一张图描绘出来 点之间的线,分有方向和无方向 创建图 创建图,实际就是创建出节点,和节点之 ...

  2. array_column() 函数[二维数组转为一维数组]

    array_column() 函数 输出数组中某个键值的集合[二维数组转为一位数组] <?php // 表示由数据库返回的可能记录集的数组 $a = array( array( 'id' =&g ...

  3. Java基本语法-----java二维数组

    由于word里的样式在csdn上调太麻烦了,所以我再次贴图了,后面二维数组那里是文字的,大家将就看吧. 二维数组常见的操作: 1.遍历二维数组 2.对二维数组求和 class Demo { // 定义 ...

  4. C语言中如何将二维数组作为函数的参数传递

    今天写程序的时候要用到二维数组作参数传给一个函数,我发现将二维数组作参数进行传递还不是想象得那么简单里,但是最后我也解决了遇到的问题,所以这篇文章主要介绍如何处理二维数组当作参数传递的情况,希望大家不 ...

  5. php对二维数组进行相关操作(排序、转换、去空白等)

    php对二维数组进行相关操作(排序.转换.去空白等) 投稿:lijiao 字体:[增加 减小] 类型:转载 时间:2015-11-04   这篇文章主要介绍了php对二维数组进行相关操作,包括php对 ...

  6. C语言学习笔记 (005) - 二维数组作为函数参数传递剖析

    前言 很多文章不外乎告诉你下面这几种标准的形式,你如果按照它们来用,准没错: //对于一个2行13列int元素的二维数组 //函数f的形参形式 f(int daytab[2][13]) {...} / ...

  7. C语言二维数组作为函数参数

    设有整型二维数组a[3][4]如下:0   1   2   34   5   6   78   9  10  11 它的定义为:    int a[3][4]={{0,1,2,3},{4,5,6,7} ...

  8. SDUT OJ 图练习-BFS-从起点到目标点的最短步数 (vector二维数组模拟邻接表+bfs , *【模板】 )

    图练习-BFS-从起点到目标点的最短步数 Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 在古老的魔兽传说中,有两个军团,一个叫天 ...

  9. PHP代码篇(二)-- array_column函数将二维数组格式化成固定格式的一维数组,及优化查询方法

    小白因为经常用到多表查询,比如获取一个会员领取的卡卷list,里面当然包含了1“会员优惠券记录表t_coupon_members”主表,然后2“门店优惠券表t_coupon”,和3“门店信息表t_sh ...

随机推荐

  1. 如何提升JavaScript的任务效率?学会后教给你同事

    本文由云+社区发表 一.概述 JavaScript 语言采用的是单线程模型,也就是说,所有任务只能在一个线程上完成,一次只能做一件事.前面的任务没做完,后面的任务只能等着.随着电脑计算能力的增强,尤其 ...

  2. Http系列目录

    1.Http简史 2.Http协议基本术语 3.Http1.1 4.Http2.0

  3. Mybatis学习(一)—————mybatis入门

    学习了hibernate这个持久层框架之后,在来学习Mybatis简直是无压力,因为Mybatis入门门栏很低,如果学习过了hibernate的话,对于Mybatis的学习很简单了,如果没学习过hib ...

  4. R 脚本读取汇总 Excel 表格数据

    主要用到了 xlsx 和 rJava 包,打开 Excel 文件,读取各表格数据,再写入到汇总表. 下图为处理前的原始数据表格: 下图为处理后的数据: 代码实现 安装&加载包的函数实现.ins ...

  5. dd、split、csplit命令

    在Linux最常用的文件生成和切片工具是dd,它功能比较全面,但无法以行为单位提取文件数据,也无法直接将文件按大小或行数进行均分(除非借助循环).另两款数据分割工具split和csplit能够比较轻松 ...

  6. maven web工程缺少 src/main/java 和 src/test/java 资源文件夹的方法

    右键打开:build path -> configure build path... 在弹出的界面,选择: 编辑后: 点击finish,即可完成

  7. Docker在Windows上运行NetCore系列(一)使用命令控制台运行.NetCore控制台应用

    系列文章:https://www.cnblogs.com/alunchen/p/10121379.html 本篇文章操作系统信息 Windows:Window 10 Visual Studio:201 ...

  8. “笨方法”学习Python笔记(1)-Windows下的准备

    Python入门书籍 来自于开源中国微信公众号推荐的一篇文章 全民Python时代,豆瓣高级工程师告诉你 Python 怎么学 问:请问你目前最好的入门书是那本?有没有和PHP或者其他语言对比讲Pyt ...

  9. VB.NET 使用ADODB連接資料庫滙出到EXCEL

    '導入命名空間 Imports ADODB Imports Microsoft.Office.Interop Private Sub A1() Dim Sql As StringDim Cnn As ...

  10. springbooot2 thymeleaf 配置以及加载资源文件。Cannot find template location: classpath:/templates/ (please add some templates or check your Thymeleaf configuration)

    最近在学习springbooot2 和 thymeleaf 程序文件 application.properties文件配置: #thymeleaf spring.thymeleaf.prefix=cl ...