自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

六講貫通C++圖的應(yīng)用之一 基本儲(chǔ)存方法

開發(fā) 后端
圖的應(yīng)用恐怕是C++所有數(shù)據(jù)結(jié)構(gòu)中最寬泛的了,本次六講筆者從基本儲(chǔ)存方法、DFS和BFS、無向圖、最小生成樹、最短路徑以及活動(dòng)網(wǎng)絡(luò)(AOV、AOE)六個(gè)方面詳細(xì)介紹圖的應(yīng)用。本文是這次系列文章的第一篇,主要介紹圖的基本存儲(chǔ)方法。

  圖的應(yīng)用恐怕是C++所有數(shù)據(jù)結(jié)構(gòu)中最寬泛的了,但這也注定了在講“數(shù)據(jù)結(jié)構(gòu)的圖”的時(shí)候沒什么好講的——關(guān)于圖的最重要的是算法,而且相當(dāng)?shù)囊徊糠侄际呛軐I(yè)的,一般的人幾乎不會(huì)接觸到;相對(duì)而言,結(jié)構(gòu)就顯得分量很輕。你可以看到關(guān)于圖中元素的操作很少,遠(yuǎn)沒有單鏈表那里列出的一大堆“接口”?!粋€(gè)結(jié)構(gòu)如果復(fù)雜,那么能確切定義的操作就很有限。

  筆者從基本儲(chǔ)存方法、DFS和BFS、無向圖最小生成樹、最短路徑以及活動(dòng)網(wǎng)絡(luò)(AOV、AOE)六個(gè)方面詳細(xì)介紹圖的應(yīng)用。本文是這次系列文章的***篇,主要介紹圖的基本存儲(chǔ)方法。

  基本儲(chǔ)存方法

  不管怎么說,還是先得把圖存起來。不要看書上列出了好多方法,根本只有一個(gè)——鄰接矩陣。如果矩陣是稀疏的,那就可以用十字鏈表來儲(chǔ)存矩陣(見C++數(shù)據(jù)結(jié)構(gòu)學(xué)習(xí)之稀疏矩陣)。如果我們只關(guān)系行的關(guān)系,那么就是鄰接表(出邊表);反之,只關(guān)心列的關(guān)系,就是逆鄰接表(入邊表)。

  下面給出兩種儲(chǔ)存方法的實(shí)現(xiàn)。

  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;//***節(jié)點(diǎn)數(shù)  
  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號(hào)頂點(diǎn)的第n號(hào)頂點(diǎn)后***個(gè)鄰接頂點(diǎn)號(hào),無返回-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號(hào)頂點(diǎn)的第n號(hào)頂點(diǎn)后***個(gè)鄰接頂點(diǎn)號(hào),無返回-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 

  這個(gè)實(shí)現(xiàn)是很簡(jiǎn)陋的,但應(yīng)該能滿足后面的講解了?,F(xiàn)在這個(gè)還什么都不能做,不要急,在下篇將講述圖的DFS和BFS。

【編輯推薦】

  1. 經(jīng)典四講貫通C++排序之一 插入排序
  2. c++編程常用工具
  3. 給C++初學(xué)者的50個(gè)忠告
  4. c++最基礎(chǔ)的20條規(guī)則
  5. 程序員必看 c++筆試題匯總
責(zé)任編輯:韓亞珊 來源: 天極網(wǎng)
相關(guān)推薦

2011-04-11 16:43:51

AOVAOE活動(dòng)網(wǎng)絡(luò)

2011-04-11 16:10:55

無向圖C++

2011-04-11 16:32:28

路徑C++

2011-04-11 15:57:22

DFSBFSC++

2011-04-11 16:19:56

C++

2011-04-11 13:41:34

插入排序排序C++

2011-04-11 14:21:43

希爾排序排序C++

2011-04-11 14:52:18

選擇排序排序C++

2011-04-11 14:29:44

交換排序冒泡排序排序

2010-02-06 17:27:03

C++ replace

2011-02-28 13:19:50

SQL Server SQL死鎖

2021-02-08 20:25:12

C 語言C++Linux

2010-02-02 14:36:08

C++ Cstring

2011-04-25 11:18:39

Ajax

2010-02-02 14:45:35

C++ typeof

2011-05-17 17:12:39

2010-01-15 19:49:04

C++類庫

2010-01-15 19:49:04

C++類庫

2010-01-14 09:27:44

C++語言

2010-02-06 16:16:01

C++冒泡排序
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)