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

开发 后端
图的应用恐怕是C++所有数据结构中最宽泛的了,本次六讲笔者从基本储存方法、DFS和BFS、无向图、最小生成树、最短路径以及活动网络(AOV、AOE)六个方面详细介绍图的应用。本文是这次系列文章的第一篇,主要介绍图的基本存储方法。

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

  笔者从基本储存方法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 name, class dist, class mem> class Network;  
  9.  
  10. const int maxV = 20;//***节点数  
  11. template <class name, class dist>  
  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 <class name, class dist>  
  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++笔试题汇总
责任编辑:韩亚珊 来源: 天极网
相关推荐

2011-04-11 16:43:51

AOVAOE活动网络

2011-04-11 16:10:55

无向图C++

2011-04-11 16:32:28

路径C++

2011-04-11 16:19:56

C++

2011-04-11 15:57:22

DFSBFSC++

2011-04-11 13:41:34

插入排序排序C++

2011-04-11 14:52:18

选择排序排序C++

2011-04-11 14:21:43

希尔排序排序C++

2011-04-11 14:29:44

交换排序冒泡排序排序

2010-02-06 17:27:03

C++ replace

2011-02-28 13:19:50

SQL Server SQL死锁

2011-05-17 17:12:39

2010-02-02 14:45:35

C++ typeof

2010-02-02 14:36:08

C++ Cstring

2021-02-08 20:25:12

C 语言C++Linux

2011-04-25 11:18:39

Ajax

2010-01-15 19:49:04

C++类库

2010-01-15 19:49:04

C++类库

2010-02-06 16:16:01

C++冒泡排序

2010-01-14 09:27:44

C++语言
点赞
收藏

51CTO技术栈公众号