1. /*
    2. 使用邻接矩阵构造图
    3. 分析:
    4. 虽然图相比于其它数据结构较复杂,但也是十分易懂的,对于使用邻接矩阵存储的图来说,我们所需要知道的数据有
    5. 图的顶点数、边数、用一个二维数组存储的边与边的联系及其权值,未连接的边我们要使用无穷表示,节点自身用0
    6. 表示,初始时除自身节点外均表示为无穷。另外我们还需要一个一维数组用来存储我们的顶点个数
    7. */
    8. #define _CRT_SECURE_NO_WARNINGS
    9. #define MAXSIZE 100 //数组最大值
    10. #define TYPE int
    11. #include <stdio.h>
    12. #include <stdlib.h>
    13. typedef struct Graph {
    14. TYPE Vertex[MAXSIZE];
    15. int Edge[MAXSIZE][MAXSIZE];
    16. int numV, numE;//顶点、边数量
    17. }adjMatrix;
    18. void createGraph(adjMatrix *G) {
    19. int v, e, vi, vj, w;
    20. printf("请输入创建的图的顶点与边个数(以空格分开):");
    21. scanf("%d %d", &v, &e);
    22. G->numE = e;
    23. G->numV = v;
    24. //初始化图
    25. for (int i = 0; i < v; i++) {
    26. for (int j = 0; j < v; j++) {
    27. i == j ? G->Edge[i][j] = 0 : G->Edge[i][j] = 32767;
    28. }
    29. }
    30. //将顶点存入数组
    31. for (int i = 0; i < G->numV; i++) {
    32. printf("请输入第%d个节点信息:", i + 1);
    33. scanf("\n%c", &G->Vertex[i]);
    34. }
    35. //开始建立边与边的关系
    36. for (int i = 0; i < G->numE; i++) {
    37. printf("请输入边的信息vi vj w(以空格分开)");
    38. scanf("%d %d %d", &vi, &vj, &w);//有权值就写
    39. G->Edge[vi - 1][vj - 1] = w;//①
    40. G->Edge[vj - 1][vi - 1] = w;//② 这代表无向图
    41. }
    42. }
    43. void createGraphFromFile(adjMatrix *G) {
    44. FILE *fp;//创建文件指针
    45. char ev[4] = {};
    46. char numE[3] = { 0 };//边个数信息
    47. char numV[3] = { 0 };//顶点个数信息
    48. char arc[6] = { 0 };//边信息
    49. char *vertex;//顶点信息,名称
    50. fp = fopen("graph.txt", "r");//打开文件
    51. if (fp == NULL) {
    52. printf("该文件无法打开!");
    53. return;
    54. }
    55. fscanf(fp,"%hu %hu", numE, numV);//读取第一行
    56. G->numE = numE[0];
    57. G->numV = numV[0];
    58. //初始化图
    59. for (int i = 0; i < G->numV; i++) {
    60. for (int j = 0; j < G->numV; j++) {
    61. i == j ? G->Edge[i][j] = 0 : G->Edge[i][j] = 32767;
    62. }
    63. }
    64. vertex = (char *)malloc(sizeof(char*)*G->numV);//这是用来存储顶点信息的数组(顶点的名字)
    65. for (int i = 0; i <= G->numE; i++) {//开始获取后面的信息
    66. if (i == 0) {//此时,根据我们文件的结构,第二行是顶点信息
    67. fgets(ev, 4, fp);//获取回车符,上一次fgets后会停在回车符那儿
    68. fgets(vertex, G->numV * 2, fp);//这里获取顶点信息
    69. int w = 0;//用一个计数器,保证adjlist依次存储顶点
    70. for (int j = 0; j < G->numV * 2; j++) {//因为有空格,所以让j<G->numV*2
    71. if (vertex[j] == 32) {//是空格,不进行操作
    72. continue;
    73. }
    74. else {//开始赋值
    75. G->Vertex[w] = vertex[j];
    76. w++;
    77. }
    78. }
    79. }
    80. else {//开始依次存储边信息
    81. fgets(ev, 4, fp);//同样先吃掉换行符
    82. fgets(arc, 6, fp);//读取该行的边信息
    83. G->Edge[(int)arc[0] - 48 - 1][(int)arc[2] - 48 - 1] = (int)arc[4] - 48;
    84. G->Edge[(int)arc[2] - 48 - 1][(int)arc[0] - 48 - 1] = (int)arc[4] - 48;
    85. }
    86. }
    87. fclose(fp);
    88. }
    89. void dispGraph(adjMatrix *G) {
    90. int i, j;
    91. printf("\n输出顶点的信息(字符):\n");
    92. for (i = 0; i < G->numV; i++)
    93. printf("%8c", G->Vertex[i]);
    94. printf("\n输出邻接矩阵:\n");
    95. printf("\t");
    96. for (i = 0; i < G->numV; i++)
    97. printf("%8c", G->Vertex[i]);
    98. for (i = 0; i < G->numV; i++)
    99. {
    100. printf("\n%8c", G->Vertex[i]);
    101. for (j = 0; j < G->numV; j++)
    102. {
    103. if (G->Edge[i][j] == 32767)
    104. //两点之间无连接时权值为默认的32767,
    105. //在无向图中一般用"0"表示,在有向图中一般用"∞",
    106. //这里为了方便统一输出 "∞"
    107. printf("%8s", "∞");
    108. else
    109. printf("%8d", G->Edge[i][j]);
    110. }
    111. printf("\n");
    112. }
    113. }
    114. //int main() {
    115. // adjMatrix G;
    116. // createGraphFromFile(&G);
    117. // dispGraph(&G);
    118. //}