图的邻接链表的建立以及简单操作(一)

图一般有两种,有向图和无向图,对于它的编码方式也各有两种,邻接矩阵和邻接链表,顾名思义,邻接矩阵是顺序结构,而邻接链表就是链式结构了。


简单说一下邻接矩阵,如果一个图有N个节点,那么就建立一个N*N的数组并初始化为0(有些书籍是初始化为无穷大∞),如果两个节点之间有联系,就赋值为1,(如果有权值的话,就直接赋值为权值)

那么链接链表图是怎样的呢?定义一个图的数组,其每一个元素(图的顶点)都是一个链表的头结点,链表里的元素是其顶点的弧。

那么,下面贴上我的代码:

  1. /*
  2. TIME:2019/10/27
  3. 图的创建及遍历
  4. */
  5. #include <iostream>
  6. #include <cstdio>
  7. #include <cstdlib>
  8. using namespace std;
  9. const int MAX_NUM = 20;
  10. const int Y = 1; //有向图
  11. const int N = 0; //无向图
  12. /************定义图(定义结构体)*******************/
  13. /*
  14. 就是感觉变量有点多,起名字有点烦。
  15. 所以尽量象征意义的背下来
  16. */
  17. typedef struct arcNode{
  18. int vertexIndex; //弧指向的顶点信息
  19. struct arcNode *nextarc; //定义下一条弧
  20. double price; //权重(可以是距离,价格等)
  21. }arcNode;
  22. typedef struct Vertex{
  23. int data;
  24. arcNode *firstarc;
  25. }Vertex;
  26. typedef struct Graph{
  27. Vertex *vertex[MAX_NUM]; //每个元素都为指向邻接表的指针,可以不定义成指针类型
  28. int verNum;
  29. int arcNum;
  30. int kind;
  31. }Graph;
  32. /***********建立图(初始化图)并且指定图的类型(有向还是无向)************/
  33. void createGraph(Graph *&G,int kind){ //Graph* createGraph(Graph *G,int kind){...return Graph;}
  34. G = (Graph*)malloc(sizeof(Graph));
  35. if(G==NULL){
  36. return;
  37. }
  38. for(int i = 0;i<MAX_NUM;i++){ //邻接表数组每一个元素相当于是一个链表的头结点,所以要初始化为NULL
  39. G->vertex[i] = NULL;
  40. }
  41. G->arcNum = 0;
  42. G->verNum = 0;
  43. G->kind = kind; //这里是图的类型,可以是有向图,可以是无向图
  44. }
  45. /*********释放图结构(删除图)*************/
  46. void destory(Graph *&G){
  47. arcNode *cur,*next;
  48. if(G==NULL){
  49. return;
  50. }
  51. for(int i = 0;i<G->verNum;i++){
  52. if(G->vertex[i]==NULL) continue;
  53. cur = next = G->vertex[i]->firstarc;
  54. while(cur!=NULL){
  55. cur = next;
  56. next = next->nextarc;
  57. free(cur);
  58. cur = next;
  59. }
  60. G->vertex[i]->firstarc = NULL;
  61. }
  62. free(G);
  63. G = NULL;
  64. }
  65. /**************增加顶点***********/
  66. void addvertex(Graph *&G,int data){
  67. if(G->verNum == MAX_NUM){
  68. cout<<"不能再添加新的顶点了!"<<endl;
  69. return;
  70. }
  71. for(int i =0;i<G->verNum;i++){
  72. if(G->vertex[i] == NULL)
  73. continue;
  74. if(G->vertex[i]->data == data){
  75. cout<<"已经存在相同的顶点,不允许再添加"<<endl;
  76. return;
  77. }
  78. }
  79. Vertex *p = (Vertex*)malloc(sizeof(Vertex));
  80. p->data = data;
  81. p->firstarc = NULL;
  82. G->vertex[G->verNum] = p;
  83. G->verNum++;
  84. }
  85. /******删除指定节点**********/
  86. void delVertexFromGraph(Graph *&G,int data){
  87. arcNode *cur,*next;
  88. arcNode *pre,temp;
  89. Vertex *othervertex;
  90. bool haveThisVertex = false;
  91. if(G==NULL || G->vexNum<=0){
  92. return;
  93. }
  94. for(int i = 0;i<G->verNum;i++){
  95. if(G->vertex[i] == NULL){
  96. continue;
  97. }
  98. if(G->vertex[i]->data == data){
  99. haveThisVertex = true;
  100. cur = next = G->vertex[i]->firstarc;
  101. if(G->kind == Y){ //如果是有向图,,稍微简单些
  102. while(cur){
  103. next = next->nextarc;
  104. free(cur);
  105. cur = next;
  106. }
  107. G->vertex[i]->firstarc = NULL;
  108. }
  109. else if(G->kind ==N ){ //如果是无向图,那么稍微麻烦些
  110. while(cur!=NULL){
  111. othervertex = G->vertex[cur->vertexIndex]; //这里就是找到另一个顶点,因为是无向图,两个地方都应该断掉关系
  112. pre = NULL;
  113. while(temp){
  114. if(temp->vertexIndex == i){
  115. if(pre == NULL){
  116. othervertex->firstarc = temp->nextarc;
  117. free(temp);
  118. }
  119. else{
  120. pre->nextarc = temp->nextarc;
  121. free(temp);
  122. }
  123. break;
  124. }
  125. pre = temp;
  126. temp = temp->nextarc;
  127. }
  128. next = cur->nextarc;
  129. free(cur);
  130. G->arcNum--;
  131. cur = next;
  132. }
  133. G->vertex[i] = NULL;
  134. }
  135. for(int j = i;j<G->verNum-1;++j){
  136. G->vertex[j] = G->vertex[j+1];
  137. }
  138. G->vertex[j] = NULL;
  139. G->vexNum--;
  140. break;
  141. }
  142. }
  143. if(haveThisVertex == false){
  144. cout<<"It doesn't have this vertex"<<endl;
  145. }
  146. }
点赞(0)
 

9.9 分

2 人评分

 

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

评论列表 共有 0 条评论

暂无评论