• 16-数据结构-图的存储结构


    简介:主要为图的顺序存储和链式存储。其中顺序存储即邻接矩阵的画法以及代码,邻接矩阵又分为有权图和无权图,区别就是有数据的地方填权值,无数据的地方可以填0或者∞,而有权图和无权图,又细分为有向图和无向图。无向图为对称矩阵,因为没有方向可言,出度入度一样。而有向图则有区分,对了,邻接矩阵横着看,是出度,竖着看是入度。链式存储中则包含邻接表、十字链表和邻接多重表,其中邻接表,有向图和无向图都可以,而十字链表是其邻接表有向图的优化,可以同时计算入度和出度,而邻接多重表,是邻接表无向图的优化,可以节约一半的边数空间,由原来的顶点数+2*总边数,变为了顶点数+总边数。

    目录

    一、顺序存储-邻接矩阵

    1.1-简介

    1.2-代码

    1.3-运行结果

    二、链式存储-邻接表

    2.1邻接表

    2.1.1.代码

    2.2十字链表

    2.2.1代码

    2.3邻接多重表

    2.3.1代码:


    一、顺序存储-邻接矩阵

    1.1-简介

    图嘛,自然是包括了顶点和边。而邻接矩阵则是通过数组的形式,表示图。

    其中需要一个一维数组,用来存储顶点的信息——顶点即一个单位像学生1,学生2之类的。

    还需要一个二维数组,就是邻接矩阵,来存储顶点之间的关系;其次,则是记录,图中顶点数和边的总数。

    我代码的思路,是自己想的,从创建到可以运行,如果遇到简单的,我后期再来改。

    思路:

    1. 先初始化图,给图输入想要的顶点数和边数。其次初始化一维数组和二维数组。
    2. 创建以及输入数据,先给顶点的信息,输入顶点数组中。随后是进行判断,看是有向图还是无向图。(这里面默认是无权图)(有权图,只不过又多了一组需要手动输入的数字)。
    3. 无向图,是对称矩阵,输入想要的边的关系,即1与2,则邻接矩阵对应的直接改为1,表示两个点之间相连,同时更新对称位置也为1.
    4. 有向图。则是更新一个就行,另一个不更新。

    1.2-代码

    1. #include <stdio.h>
    2. #define Max 10
    3. #include <string.h>
    4. //图的顺序存储_邻接矩阵
    5. typedef struct
    6. {
    7. char vertex[Max]; //存放顶点的一维数组
    8. int edge[Max][Max]; //表示顶点之间关系的二维数组;
    9. int vertex_num; //顶点数
    10. int edge_num; //边数
    11. }MGragh;
    12. //初始化邻接矩阵
    13. void InitMGragh(MGragh *a)
    14. {
    15. printf("添加几个顶点\n");
    16. int x;
    17. scanf("%d",&x);
    18. //赋值
    19. a->vertex_num=x;
    20. printf("有多少条边\n");
    21. int c;
    22. scanf("%d",&c);
    23. //赋值
    24. a->edge_num=c;
    25. //初始化邻接矩阵存储边信息的二维数组
    26. a->edge[Max][Max];
    27. int p,q;
    28. for(p=0;p<a->vertex_num;p++)
    29. {
    30. for(q=0;q<a->vertex_num;q++)
    31. {
    32. a->edge[p][q]=0;
    33. }
    34. }
    35. //初始化,顶点数组
    36. a->vertex[a->vertex_num]='0';
    37. }
    38. //打印邻接矩阵
    39. void PrintMGragh(MGragh *a)
    40. {
    41. int p,q;
    42. for(p=0;p<a->vertex_num;p++)
    43. {
    44. for(q=0;q<a->vertex_num;q++)
    45. {
    46. printf("%d ",a->edge[p][q]);
    47. }
    48. printf("\n");
    49. }
    50. }
    51. void Creat_MGragh(MGragh *a)
    52. {
    53. printf("图的顶点数%d\n",a->vertex_num);
    54. int i=0;
    55. printf("请加顶点到顶点数组\n");
    56. for(i=0;i<a->vertex_num;i++)
    57. { printf("i=%d\n",i);
    58. char x;
    59. x=getchar();
    60. char k;//由于单个字符输入,回车也在输入序列中,因此还需要一个变量,来吃掉回车
    61. k=getchar();
    62. a->vertex[i]=x;
    63. }
    64. printf("您想弄成无向图还是有向图,1为无向图,2为有向图\n");
    65. int text;
    66. scanf("%d",&text);
    67. if(text == 1)
    68. {
    69. printf("请添加顶点间关系\n");
    70. int w=0;
    71. while(w!=2)
    72. {
    73. printf("哪个顶点和哪个顶点之间有联系\n");
    74. int d1,d2;
    75. scanf("%d %d",&d1,&d2);
    76. a->edge[d1-1][d2-1]=1;
    77. a->edge[d2-1][d1-1]=1;
    78. printf("是否还需要继续添加,是填1,否填2\n");
    79. scanf("%d",&w);
    80. }
    81. }
    82. else
    83. {
    84. printf("请添加顶点间关系\n");
    85. int w=0;
    86. while(w!=2)
    87. {
    88. int d1,d2;
    89. printf("从哪个顶点到哪个顶点\n");
    90. scanf("%d %d",&d1,&d2);
    91. a->edge[d1-1][d2-1]=1;
    92. printf("是否还需要继续添加,是填1,否填2\n");
    93. scanf("%d",&w);
    94. }
    95. }
    96. }
    97. int main()
    98. {
    99. MGragh a;
    100. //初始化图
    101. InitMGragh(&a);
    102. //创建邻接矩阵图
    103. Creat_MGragh(&a);
    104. //打印邻接矩阵
    105. PrintMGragh(&a);
    106. return 0;
    107. }

    1.3-运行结果

    二、链式存储-邻接表

    2.1邻接表

            简介:邻接表,实际上主要为一个顶点表后面串着相应的边表。在记录总的边数和顶点数。

    为链式存储。它适用于稀疏图,方便计算出度,只需要找到相应的顶点,然后通过该顶点的单链表,往后遍历串就行。但入度则需要遍历每个顶点单链表。

    无向图,有向图都可以有向图,每个顶点传一个方向的,要么都弄出度,要么都弄入度。所以它所需要的空间为O(顶点数+总边数);而无向图,则是与该顶点相连的,都穿起来,因此所需要的存储空间为O(顶点数+2*总边数)。

    2.1.1.代码

            边表ArcNode:包括该点下标和下一个指针域。

    1. //边表
    2. typedef struct ArcNode
    3. {
    4. int NodeName;
    5. struct ArcNode *next;
    6. }ArcNode;

             顶点表:存储图的各个顶点,每个顶点后面实际上是对应的从他出发的出度的单链表。

    1. //顶点表
    2. typedef struct
    3. {
    4. int data;//顶点内容
    5. ArcNode* first; //顶点标的链的头指针
    6. }VNode;

            邻接表:最后才是邻接表,即只需要通过顶点表,就可访问其各个顶点的出度。

    1. //创建邻接表,包含顶点表和边表,以及边数和顶点数的记录
    2. typedef struct
    3. {
    4. VNode vertice[vertice_num];//顶点表,每个顶点标中的数据,串成一个对应的链
    5. int vexnum;//顶点数
    6. int edgenum;//边数
    7. }ALGragh;

           由于实现的话,以我目前的水平,感觉有点麻烦,需要遍历每个顶点,每个顶点还需要创建边表结点,还需要给每个顶点单链表,形成,目前没思路,写到中间卡壳了,以后熟练了,再来补实现        

    2.2十字链表

            简介:十字链表仅适用于有向图,为了弥补邻接表中有向图只能计算单向的度。

    多了一些入度的信息。先给邻接表的形式,出度画出来。随后再找顶点表中各个顶点的入度,入0的入度,从0出发,看边表中,哪个终点为0,则连起来,没有则置为空。

            十字链表仍然是通过顶点表,即可遍历相应顶点的出度链和入度链,即可直到相应顶点的出度和入度。

    2.2.1代码
    1. //边表
    2. typedef struct ArcNode
    3. {
    4. int tailvex,headvex;//弧尾tail弧头head 弧尾(起点)->弧头(终点)
    5. struct ArcNode *hlink,*tlink;//指针域,即出度指针域为弧头,入读指针域为弧尾,先连接弧头指针域,出度、再连接弧尾指针域
    6. char info;//存储信息的指针
    7. }ArcNode;
    8. //顶点表
    9. typedef struct VNode
    10. {
    11. AreNode *firstin,*firstout;//出度入读头指针
    12. int data;//顶点信息
    13. }VNode;
    14. //十字链表
    15. typedef struct GLGraph
    16. {
    17. VNode xlist[vertice_num];//顶点表
    18. int vexnum,edgenum;//顶点数和边数
    19. }GLGraph;

    2.3邻接多重表

    简介:邻接多重表仅适用于无向图,是邻接表中无向图,的优化,邻接表中无向图,会重复多连,2*总边数,而邻接多重表节约,为E。

    画法:先画出顶点表和边表,边表中为与最左边顶点表中顶点相关的顶点,即边,为边的起点和边的终点,并有两个相关的指针域。第一步,先标记好相应的数值,自上而下画,下方顶点,若有重复的边,则不画。

    //强连通机构的例题——不想自己画了,偷个懒

    第二步,串链,由左边顶点表中的顶点出发,找右边边表中,与该顶点相同的指针域,连接上即可,如b的下标是2,从b出发,找右边边表中2的指针域。2的指针域第一行有一个,第二行有两个,给这三个串上即可。

    2.3.1代码:
    1. //邻接多重表-无向图
    2. //边表
    3. typedef struct AreNode
    4. {
    5. int mark; //标记是否串过
    6. int ivex,jvex;//表示弧的两个顶点
    7. struct AreNode *ilink,*jlink;
    8. char info;//其他信息
    9. }AreNode;
    10. //顶点表
    11. typedef struct VNode
    12. {
    13. int data;//顶点信息
    14. AreNode *first;//指向边表中第一个挨着该顶点的结点
    15. }VNode;
    16. //邻接多重表
    17. typedef struct AMLGraph
    18. {
    19. VNode xlist[vertice_num];//顶点表
    20. int vexnum,edgenum;//总边数和总结点数
    21. }AMLGraph;

  • 相关阅读:
    Selenium自动化测试之学会元素定位
    PIC16C程序调用汇编程序的问题
    [Linux]----进程间通信之管道通信
    Maven项目创建步骤详解_smart tomcat使用介绍_Servlet项目初识(Servlet_1)
    Redis高级数据类型-HyperLogLog&Bitmap以及使用两种数据类型完成网站数据统计
    经验分享丨中小企业如何低成本开发APP
    Git 常用命令
    【技术积累】Java中的JVM【一】
    Antv G6入门之旅--combo图
    C#医学检验室(LIS)信息管理系统源码
  • 原文地址:https://blog.csdn.net/m0_59844149/article/details/132678679