六讲贯通C++图的应用之一基本储存方法

  图的应用恐怕是C++所有数据结构中最宽泛的了,但这也注定了在讲“数据结构的图”的时候没什么好讲的——关于图的最重要的是算法,而且相当的一部分都是很专业的,一般的人几乎不会接触到;相对而言,结构就显得分量很轻。你可以看到关于图中元素的操作很少,远没有单链表那里列出的一大堆“接口”。——一个结构如果复杂,那么能确切定义的操作就很有限。

成都做网站、网站制作,成都做网站公司-创新互联已向近1000家企业提供了,网站设计,网站制作,网络营销等服务!设计与技术结合,多年网站推广经验,合理的价格为您打造企业品质网站。

  笔者从基本储存方法DFS和BFS无向图最小生成树最短路径以及活动网络(AOV、AOE)六个方面详细介绍图的应用。本文是这次系列文章的***篇,主要介绍图的基本存储方法。

  基本储存方法

  不管怎么说,还是先得把图存起来。不要看书上列出了好多方法,根本只有一个——邻接矩阵。如果矩阵是稀疏的,那就可以用十字链表来储存矩阵(见C++数据结构学习之稀疏矩阵)。如果我们只关系行的关系,那么就是邻接表(出边表);反之,只关心列的关系,就是逆邻接表(入边表)。

  下面给出两种储存方法的实现。

 
 
 
  1. #ifndef Graphmem_H  
  2. #define Graphmem_H  
  3.  
  4. #include   
  5. #include   
  6. using namespace std;  
  7.  
  8. template  class Network;  
  9.  
  10. const int maxV = 20;//***节点数  
  11. template   
  12. class AdjMatrix  
  13. {  
  14. friend class Network  >;  
  15. public:  
  16. AdjMatrix() : vNum(0), eNum(0)  
  17. {  
  18. vertex = new name[maxV]; edge = new dist*[maxV];  
  19. for (int i = 0; i < maxV; i++) edge[i] = new dist[maxV];  
  20. }  
  21. ~AdjMatrix()  
  22. {  
  23. for (int i = 0; i < maxV; i++) delete []edge[i];  
  24. delete []edge; delete []vertex;  
  25. }  
  26. bool insertV(name v)  
  27. {  
  28. if (find(v)) return false;  
  29. vertex[vNum] = v;  
  30. for (int i = 0; i < maxV; i++) edge[vNum][i] = NoEdge;  
  31. vNum++; return true;  
  32. }  
  33. bool insertE(name v1, name v2, dist cost)  
  34. {  
  35. int i, j;  
  36. if (v1 == v2 || !find(v1, i) || !find(v2, j)) return false;  
  37. if (edge[i][j] != NoEdge) return false;  
  38. edge[i][j] = cost; eNum++; return true;  
  39. }  
  40. name& getV(int n) { return vertex[n]; } //没有越界检查  
  41. int nextV(int m, int n)//返回m号顶点的第n号顶点后***个邻接顶点号,无返回-1  
  42. {  
  43. for (int i = n + 1; i < vNum; i++) if (edge[m][i] != NoEdge) return i;  
  44. return -1;  
  45. }  
  46. private:  
  47. int vNum, eNum;  
  48. dist NoEdge, **edge; name *vertex;  
  49. bool find(const name& v)  
  50. {  
  51. for (int i = 0; i < vNum; i++) if (v == vertex[i]) return true;  
  52. return false;  
  53. }  
  54. bool find(const name& v, int& i)  
  55. {  
  56. for (i = 0; i < vNum; i++) if (v == vertex[i]) return true;  
  57. return false;  
  58. }  
  59. };  
  60.  
  61. template   
  62. class LinkedList  
  63. {  
  64. friend class Network  >;  
  65. public:  
  66. LinkedList() : vNum(0), eNum(0) {}  
  67. ~LinkedList()  
  68. {  
  69. for (int i = 0; i < vNum; i++) delete vertices[i].e;  
  70. }  
  71. bool insertV(name v)  
  72. {  
  73. if (find(v)) return false;  
  74. vertices.push_back(vertex(v, new list ));  
  75. vNum++; return true;  
  76. }  
  77. bool insertE(const name& v1, const name& v2, const dist& cost)  
  78. {  
  79. int i, j;  
  80. if (v1 == v2 || !find(v1, i) || !find(v2, j)) return false;  
  81. for (list ::iterator iter = vertices[i].e->begin();  
  82. iter != vertices[i].e->end() && iter->vID < j; iter++);  
  83. if (iter == vertices[i].e->end())  
  84. {  
  85. vertices[i].e->push_back(edge(j, cost)); eNum++; return true;  
  86. }  
  87. if (iter->vID == j) return false;  
  88. vertices[i].e->insert(iter, edge(j, cost)); eNum++; return true;  
  89. }  
  90. name& getV(int n) { return vertices[n].v; } //没有越界检查  
  91. int nextV(int m, int n)//返回m号顶点的第n号顶点后***个邻接顶点号,无返回-1  
  92. {  
  93. for (list ::iterator iter = vertices[m].e->begin();  
  94. iter != vertices[m].e->end(); iter++) if (iter->vID > n) return iter->vID;  
  95. return -1;  
  96. }  
  97.  
  98. private:  
  99. bool find(const name& v)  
  100. {  
  101. for (int i = 0; i < vNum; i++) if (v == vertices[i].v) return true;  
  102. return false;  
  103. }  
  104. bool find(const name& v, int& i)  
  105. {  
  106. for (i = 0; i < vNum; i++) if (v == vertices[i].v) return true;  
  107. return false;  
  108. }  
  109. struct edge  
  110. {  
  111. edge() {}  
  112. edge(int vID, dist cost) : vID(vID), cost(cost) {}  
  113. int vID;  
  114. dist cost;  
  115. };  
  116. struct vertex  
  117. {  
  118. vertex() {}  
  119. vertex(name v, list * e) : v(v), e(e) {}  
  120. name v;  
  121. list * e;  
  122. };  
  123. int vNum, eNum;  
  124. vector  vertices;  
  125. };  
  126.  
  127. #endif 

  这个实现是很简陋的,但应该能满足后面的讲解了。现在这个还什么都不能做,不要急,在下篇将讲述图的DFS和BFS。

【编辑推荐】

  1. 经典四讲贯通C++排序之一 插入排序
  2. c++编程常用工具
  3. 给C++初学者的50个忠告
  4. c++最基础的20条规则
  5. 程序员必看 c++笔试题汇总

分享文章:六讲贯通C++图的应用之一基本储存方法
转载源于:http://www.mswzjz.cn/qtweb/news5/62705.html

攀枝花网站建设、攀枝花网站运维推广公司-贝锐智能,是专注品牌与效果的网络营销公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 贝锐智能