C++數據結構之圖——鄰接矩陣實現

C++數據結構之圖——鄰接矩陣實現

一、圖的鄰接矩陣實現

1.實現了以頂點數組、鄰接矩陣為存儲結構的圖;

2.實現了圖的創建(包含有向/無向圖、有向/無向網)、頂點/邊的增刪操作、深度/廣度優先遍歷的算法;

3.採用頂點對象列表、邊(弧)對象列表的方式,對圖的創建進行初始化;引用 "ObjArrayList.h"頭文件,頭文件可參看之前博文“數據結構之順序列表(支持對象元素)”代碼;

4.採用將頂點數組空位的下標索引入隊列的方式,解決頂點在數組(靜態)中因增刪操作造成的不連續存儲的問題;引用 “LinkQueue.h”頭文件,頭文件可參看之前博文“數據結構之隊列(循環隊列、鏈隊列的類模板實現)”代碼;

5.深度優先遍歷採用遞歸算法;廣度優先遍歷採用隊列方式實現;

6.測試代碼中以有向網的所有帶權邊作為邊的初始化數據,選擇圖類型(DG, UDG, DN, UDN)可創建成不同類型的圖。二、測試代碼中的圖結構圖

C++數據結構之圖——鄰接矩陣實現

深度優先遍歷序列(從 v1 頂點開始):

1.無向圖/網:v1-v2-v3-v5-v4-v6-v7

2.有向圖/網:v1-v2-v5-v3-v4-v6-v7

廣度優先遍歷序列(從 v2 頂點開始):

1.無向圖/網:v2-v1-v3-v5-v4-v6-v7

2.有向圖/網:v2-v5 後序無法遍歷

注:有向圖的遍歷 是遵循出度方向遍歷的,若無出度方向,則遍歷終止。

C++數據結構之圖——鄰接矩陣實現

C++數據結構之圖——鄰接矩陣實現

三、代碼


  1. //文件名:"GraphAdjMat.h"
  2. #pragma once
  3. #ifndef GRAPHADJMAT_H_
  4. #define GRAPHADJMAT_H_
  5. #include
  6. #include
  7. #include "ObjArrayList.h"
  8. #include "LinkQueue.h"
  9. using namespace std;
  10. /*
  11. .圖(鄰接矩陣實現) Graph Adjacency Matrix
  12. .相關術語:
  13. .頂點 Vertex ; 邊 Arc ;權 Weight ;
  14. .有向圖 Digraph ;無向圖 Undigraph ;
  15. .有向網 Directed Network ;無向網 Undirected Network ;
  16. */
  17. class GraphAdjMat
  18. {
  19. /*
  20. .邊(弧) 單元,注:鄰接矩陣單元
  21. */
  22. struct ArcCell
  23. {
  24. int adj;//鄰接頂點關係。圖:0|不相鄰 1|相鄰 ;網:無窮(INT_MAX)|不相鄰 權值(W)|相鄰
  25. char * info;//邊(弧)信息
  26. };
  27. public:
  28. /*
  29. .圖 種類
  30. */
  31. enum GraphType
  32. {
  33. DG,//有向圖,默認 0
  34. UDG,//無向圖,默認 1
  35. DN,//有向網,默認 2
  36. UDN//無向網,默認 3
  37. };
  38. /*
  39. .邊(弧)數據,注:供外部初始化邊數據使用
  40. */
  41. struct ArcData
  42. {
  43. string Tail;//弧尾
  44. string Head;//弧頭
  45. int Weight;//權重
  46. };
  47. private:
  48. const int _INFINITY = INT_MAX;//無窮大 注:包含於頭文件
  49. static const int _MAX_VERTEX_NUM = 10;//支持最大頂點數
  50. //靜態存儲結構
  51. string vexs[_MAX_VERTEX_NUM];//頂點表
  52. ArcCell arcs[_MAX_VERTEX_NUM][_MAX_VERTEX_NUM];//邊(弧)矩陣
  53. int vexNum;//頂點數
  54. int arcNum;//邊數
  55. int type;//圖種類
  56. int nonAdjInt;//不相鄰 int 值:0|無權 無窮|有權
  57. LinkQueue *vexs_null_index_queue = new LinkQueue();//頂點數組中空頂點位置索引隊列 (需要銷燬)
  58. bool vexs_visited[_MAX_VERTEX_NUM];//頂點訪問標記數組:0|未訪問 1|已訪問
  59. void _CreateDG(ObjArrayList * arcsList);//創建有向圖
  60. void _CreateUDG(ObjArrayList * arcsList);//創建無向圖
  61. void _CreateDN(ObjArrayList * arcsList);//創建有向網
  62. void _CreateUDN(ObjArrayList * arcsList);//創建無向網
  63. int _Locate(string vertex);//定位頂點元素位置
  64. void _DFS_R(int index);//深度優先遍歷 遞歸
  65. public:
  66. GraphAdjMat(int type);//構造函數:初始化圖類型
  67. ~GraphAdjMat();//析構函數:銷燬圖存儲空間
  68. void Init(ObjArrayList * vexs, ObjArrayList * arcsList);//初始化頂點、邊數據為 圖|網
  69. void Display();//顯示 圖|網
  70. void InsertVertex(string *vertex);//插入一個新頂點
  71. void DeleteVertex(string *vertex);//刪除一個頂點
  72. void InsertArc(ArcData *arc);//插入一條新邊(弧)
  73. void DeleteArc(ArcData *arc);//刪除一條邊(弧)
  74. void Display_DFS(string *vertex);//從指定頂點開始,深度優先遍歷
  75. void Display_BFS(string *vertex);//從指定頂點開始,廣度優先遍歷
  76. };
  77. GraphAdjMat::GraphAdjMat(int type)
  78. {
  79. /*
  80. .構造函數:初始化圖類型
  81. */
  82. this->type = type;
  83. this->vexNum = 0;
  84. this->arcNum = 0;
  85. if (this->type == DG || this->type == UDG)
  86. {
  87. //圖的不相鄰 int 值 0
  88. this->nonAdjInt = 0;
  89. }
  90. else
  91. {
  92. //網的不相鄰 int 值 無窮大
  93. this->nonAdjInt = this->_INFINITY;
  94. }
  95. }
  96. GraphAdjMat::~GraphAdjMat()
  97. {
  98. /*
  99. .析構函數:銷燬圖
  100. */
  101. //1.釋放頂點空位置索引隊列
  102. int * e;
  103. while (vexs_null_index_queue->GetHead() != NULL)
  104. {
  105. e = vexs_null_index_queue->DeQueue();
  106. delete e;
  107. }
  108. delete vexs_null_index_queue;
  109. }
  110. void GraphAdjMat::Init(ObjArrayList * vexs, ObjArrayList * arcsList)
  111. {
  112. /*
  113. .初始化頂點、邊數據,並構建 圖|網
  114. .入參:
  115. .vexs: 頂點 列表
  116. .arcsList: 邊數據 列表
  117. */
  118. //1.初始化頂點數據
  119. if (vexs->Length() > this->_MAX_VERTEX_NUM)
  120. {
  121. return;
  122. }
  123. for (int i = 0; i < vexs->Length(); i++)
  124. {
  125. this->vexs[i] = *vexs->Get(i);
  126. }
  127. this->vexNum = vexs->Length();
  128. //1.1.初始化頂點數組空頂點位置索引隊列
  129. for (int i = vexs->Length(); i < _MAX_VERTEX_NUM; i++)
  130. {
  131. vexs_null_index_queue->EnQueue(new int(i));
  132. }
  133. //2.根據初始化的圖類型,創建指定的圖
  134. switch (this->type)
  135. {
  136. case DG:
  137. _CreateDG(arcsList); break;
  138. case UDG:
  139. _CreateUDG(arcsList); break;
  140. case DN:
  141. _CreateDN(arcsList); break;
  142. case UDN:
  143. _CreateUDN(arcsList); break;
  144. default:
  145. break;
  146. }
  147. }
  148. void GraphAdjMat::_CreateDG(ObjArrayList * arcsList)
  149. {
  150. /*
  151. .創建有向圖
  152. .頂點相鄰關係:0|不相鄰 1|相鄰
  153. .鄰接矩陣為 非對稱矩陣
  154. */
  155. //初始化臨時 邊對象
  156. ArcData * arcData = NULL;
  157. //初始化 矩陣二維座標
  158. int m = 0, n = 0;
  159. //初始化邊的鄰接矩陣
  160. for (int i = 0; i < _MAX_VERTEX_NUM; i++)
  161. {
  162. for (int j = 0; j < _MAX_VERTEX_NUM; j++)
  163. {
  164. this->arcs[i][j].adj = 0;
  165. this->arcs[i][j].info = NULL;
  166. }
  167. }
  168. //遍歷邊數據列表
  169. for (int i = 0; i < arcsList->Length(); i++)
  170. {
  171. //按序獲取邊(弧)
  172. arcData = arcsList->Get(i);
  173. //定位(或設置)邊的兩端頂點位置
  174. m = _Locate(arcData->Tail);
  175. n = _Locate(arcData->Head);
  176. //設置頂點相鄰 為 1 (無向)
  177. if (this->arcs[m][n].adj == 1)
  178. {
  179. //去除重複邊
  180. continue;
  181. }
  182. this->arcs[m][n].adj = 1;
  183. //邊 計數
  184. this->arcNum++;
  185. }
  186. }
  187. void GraphAdjMat::_CreateUDG(ObjArrayList * arcsList)
  188. {
  189. /*
  190. .創建無向圖
  191. .頂點相鄰關係:0|不相鄰 1|相鄰
  192. .鄰接矩陣為 對稱矩陣
  193. */
  194. //初始化臨時 邊對象
  195. ArcData * arcData = NULL;
  196. //初始化 矩陣二維座標
  197. int m = 0, n = 0;
  198. //初始化邊的鄰接矩陣
  199. for (int i = 0; i < _MAX_VERTEX_NUM; i++)
  200. {
  201. for (int j = 0; j < _MAX_VERTEX_NUM; j++)
  202. {
  203. this->arcs[i][j].adj = 0;
  204. this->arcs[i][j].info = NULL;
  205. }
  206. }
  207. //遍歷邊數據列表
  208. for (int i = 0; i < arcsList->Length(); i++)
  209. {
  210. //按序獲取邊(弧)
  211. arcData = arcsList->Get(i);
  212. //定位(或設置)邊的兩端頂點位置
  213. m = _Locate(arcData->Tail);
  214. n = _Locate(arcData->Head);
  215. //設置頂點相鄰 為 1 (有向)
  216. if (this->arcs[m][n].adj == 1 || this->arcs[n][m].adj == 1)
  217. {
  218. //去除重複邊
  219. continue;
  220. }
  221. this->arcs[m][n].adj = 1;
  222. this->arcs[n][m].adj = 1;
  223. //邊 計數
  224. this->arcNum++;
  225. }
  226. }
  227. void GraphAdjMat::_CreateDN(ObjArrayList * arcsList)
  228. {
  229. /*
  230. .創建有向網
  231. .頂點相鄰關係:infinity|不相鄰 w|相鄰
  232. .鄰接矩陣為 非對稱矩陣
  233. */
  234. //初始化臨時 邊對象
  235. ArcData * arcData = NULL;
  236. //初始化 矩陣二維座標
  237. int m = 0, n = 0;
  238. //初始化邊的鄰接矩陣
  239. for (int i = 0; i < _MAX_VERTEX_NUM; i++)
  240. {
  241. for (int j = 0; j < _MAX_VERTEX_NUM; j++)
  242. {
  243. this->arcs[i][j].adj = this->_INFINITY;//無窮大
  244. this->arcs[i][j].info = NULL;
  245. }
  246. }
  247. //遍歷邊數據列表
  248. for (int i = 0; i < arcsList->Length(); i++)
  249. {
  250. //按序獲取邊(弧)
  251. arcData = arcsList->Get(i);
  252. //定位(或設置)邊的兩端頂點位置
  253. m = _Locate(arcData->Tail);
  254. n = _Locate(arcData->Head);
  255. //設置頂點相鄰 為 weight 權重
  256. if (this->arcs[m][n].adj != this->_INFINITY)
  257. {
  258. //去除重複邊
  259. continue;
  260. }
  261. this->arcs[m][n].adj = arcData->Weight;
  262. //邊 計數
  263. this->arcNum++;
  264. }
  265. }
  266. void GraphAdjMat::_CreateUDN(ObjArrayList * arcsList)
  267. {
  268. /*
  269. .創建無向網
  270. .頂點相鄰關係:infinity|不相鄰 w|相鄰
  271. .鄰接矩陣為 對稱矩陣
  272. */
  273. //初始化臨時 邊對象
  274. ArcData * arcData = NULL;
  275. //初始化 矩陣二維座標
  276. int m = 0, n = 0;
  277. //初始化邊的鄰接矩陣
  278. for (int i = 0; i < _MAX_VERTEX_NUM; i++)
  279. {
  280. for (int j = 0; j < _MAX_VERTEX_NUM; j++)
  281. {
  282. this->arcs[i][j].adj = this->_INFINITY;//無窮大
  283. this->arcs[i][j].info = NULL;
  284. }
  285. }
  286. //遍歷邊數據列表
  287. for (int i = 0; i < arcsList->Length(); i++)
  288. {
  289. //按序獲取邊(弧)
  290. arcData = arcsList->Get(i);
  291. //定位(或設置)邊的兩端頂點位置
  292. m = _Locate(arcData->Tail);
  293. n = _Locate(arcData->Head);
  294. //設置頂點相鄰 為 weight 權重
  295. if (this->arcs[m][n].adj != this->_INFINITY || this->arcs[n][m].adj != this->_INFINITY)
  296. {
  297. //去除重複邊
  298. continue;
  299. }
  300. if (arcData->Weight == this->_INFINITY)
  301. {
  302. //去除權重為 無窮 的邊
  303. continue;
  304. }
  305. this->arcs[m][n].adj = arcData->Weight;
  306. this->arcs[n][m].adj = arcData->Weight;
  307. //邊 計數
  308. this->arcNum++;
  309. }
  310. }
  311. int GraphAdjMat::_Locate(string vertex)
  312. {
  313. /*
  314. .定位頂點元素位置
  315. .後期可改成【字典樹】,頂點數超過100個後定位頂點位置可更快
  316. */
  317. //遍歷定位頂點位置
  318. for (int i = 0; i < this->_MAX_VERTEX_NUM; i++)
  319. {
  320. if (vertex == this->vexs[i])
  321. {
  322. return i;
  323. }
  324. }
  325. cout << endl << "頂點[" << vertex << "]不存在。" << endl;
  326. return -1;
  327. }
  328. void GraphAdjMat::Display()
  329. {
  330. /*
  331. .顯示 圖|網 (輸出頂點數組、鄰接矩陣)
  332. */
  333. //顯示頂點數組
  334. //注:當刪除某個中間序號頂點後,頂點數組就不是連續的
  335. cout << endl << "頂點數組:" << endl;
  336. for (int i = 0, num = 0; i < this->_MAX_VERTEX_NUM && num < this->vexNum; i++)
  337. {
  338. if (this->vexs[i] != "")
  339. {
  340. cout << " (" << i << ")" << this->vexs[i];
  341. num++;
  342. }
  343. }
  344. //顯示邊(鄰接矩陣)
  345. cout << endl << "邊(鄰接矩陣):" << endl;
  346. cout << " ";
  347. for (int i = 0; i < this->_MAX_VERTEX_NUM; i++)
  348. {
  349. cout << "[" << i << "]";
  350. }
  351. cout << endl;
  352. for (int i = 0; i < this->_MAX_VERTEX_NUM; i++)
  353. {
  354. cout << "[" << i << "] ";
  355. for (int j = 0; j < this->_MAX_VERTEX_NUM; j++)
  356. {
  357. if (this->arcs[i][j].adj == this->_INFINITY)
  358. cout << " + ";
  359. else
  360. cout << " " << this->arcs[i][j].adj << " ";
  361. }
  362. cout << endl;
  363. }
  364. }
  365. void GraphAdjMat::InsertVertex(string *vertex)
  366. {
  367. /*
  368. .插入一個新頂點
  369. */
  370. //1.判斷頂點是否已存在
  371. if (_Locate(*vertex) > -1)
  372. {
  373. cout << endl << "該頂點已存在。" << endl;
  374. return;
  375. }
  376. //2.判斷頂點數是否達到上限
  377. if (this->vexNum >= this->_MAX_VERTEX_NUM)
  378. {
  379. cout << endl << "頂點數已達上限。" << endl;
  380. return;
  381. }
  382. //3.插入新頂點,並自增頂點總數
  383. int * index = vexs_null_index_queue->DeQueue();//從空位置索引隊列中取
  384. this->vexs[*index] = *vertex;
  385. this->vexNum++;
  386. //4.新增的頂點在鄰接矩陣中不需要作任何操作(已初始化)
  387. }
  388. void GraphAdjMat::DeleteVertex(string *vertex)
  389. {
  390. /*
  391. .刪除一個頂點
  392. */
  393. //1.判斷頂點是否已存在
  394. int index = _Locate(*vertex);
  395. if (index == -1)
  396. {
  397. cout << endl << "該頂點不存在。" << endl;
  398. return;
  399. }
  400. //2.刪除該頂點,並自減頂點總數
  401. this->vexs[index] = "";
  402. this->vexNum--;
  403. //3.清除鄰接矩陣 index 行列的數據,即將此行列 恢復初始化狀態
  404. if (this->type == DG || this->type == UDG)
  405. {
  406. //圖
  407. for (int i = 0; i < this->_MAX_VERTEX_NUM; i++)
  408. {
  409. this->arcs[i][index].adj = 0;
  410. this->arcs[index][i].adj = 0;
  411. }
  412. }
  413. else
  414. {
  415. //網
  416. for (int i = 0; i < this->_MAX_VERTEX_NUM; i++)
  417. {
  418. this->arcs[i][index].adj = this->_INFINITY;
  419. this->arcs[index][i].adj = this->_INFINITY;
  420. }
  421. }
  422. }
  423. void GraphAdjMat::InsertArc(ArcData *arc)
  424. {
  425. /*
  426. .插入一條新邊(弧)
  427. .若已存在,將對其更新
  428. */
  429. //1.定位頂點位置
  430. int i = _Locate(arc->Tail);
  431. int j = _Locate(arc->Head);
  432. //2.判斷頂點是否存在
  433. if (i == -1 || j == -1)
  434. {
  435. cout << endl << "該邊頂點不存在。" << endl;
  436. return;
  437. }
  438. //3.插入/更新一條邊
  439. if (this->type == DG)
  440. {
  441. //有向無權圖
  442. this->arcs[i][j].adj = 1;
  443. }
  444. else if (this->type == UDG)
  445. {
  446. //無向無權圖
  447. this->arcs[i][j].adj = 1;
  448. this->arcs[j][i].adj = 1;
  449. }
  450. else if (this->type == DN)
  451. {
  452. //有向有權網
  453. this->arcs[i][j].adj = arc->Weight;
  454. }
  455. else
  456. {
  457. //無向有權網
  458. this->arcs[i][j].adj = arc->Weight;
  459. this->arcs[j][i].adj = arc->Weight;
  460. }
  461. }
  462. void GraphAdjMat::DeleteArc(ArcData *arc)
  463. {
  464. /*
  465. .刪除一條邊(弧)
  466. */
  467. //1.定位頂點位置
  468. int i = _Locate(arc->Tail);
  469. int j = _Locate(arc->Head);
  470. //2.判斷頂點是否存在
  471. if (i == -1 || j == -1)
  472. {
  473. cout << endl << "該邊頂點不存在。" << endl;
  474. return;
  475. }
  476. //3.刪除一條邊,即 恢復初始化狀態
  477. if (this->type == DG)
  478. {
  479. //有向無權圖
  480. this->arcs[i][j].adj = 0;
  481. }
  482. else if (this->type == UDG)
  483. {
  484. //無向無權圖
  485. this->arcs[i][j].adj = 0;
  486. this->arcs[j][i].adj = 0;
  487. }
  488. else if (this->type == DN)
  489. {
  490. //有向有權網
  491. this->arcs[i][j].adj = this->_INFINITY;
  492. }
  493. else
  494. {
  495. //無向有權網
  496. this->arcs[i][j].adj = this->_INFINITY;
  497. this->arcs[j][i].adj = this->_INFINITY;
  498. }
  499. }
  500. void GraphAdjMat::Display_DFS(string *vertex)
  501. {
  502. /*
  503. .深度優先遍歷顯示,從指定頂點開始
  504. */
  505. //1.判斷頂點是否存在
  506. int index = _Locate(*vertex);
  507. if (index == -1)
  508. return;
  509. //2.初始化頂點訪問數組
  510. for (int i = 0; i < this->_MAX_VERTEX_NUM; i++)
  511. {
  512. this->vexs_visited[i] = 0;
  513. }
  514. //3.深度優先遍歷 遞歸
  515. cout << "深度優先遍歷:(從頂點" << *vertex << "開始)" << endl;
  516. _DFS_R(index);
  517. }
  518. void GraphAdjMat::_DFS_R(int index)
  519. {
  520. /*
  521. .深度優先遍歷 遞歸
  522. .有向/無向算法是一樣的
  523. .有向圖|網,以當前頂點的出度方向遍歷
  524. .無向圖|網,以當前頂點的相鄰結點方向遍歷(可理解為“出度”,但不是出度)
  525. */
  526. //1.訪問頂點,並標記已訪問
  527. cout << this->vexs[index] << " ";
  528. this->vexs_visited[index] = 1;
  529. //2.訪問其相鄰頂點
  530. for (int i = 0; i < this->_MAX_VERTEX_NUM; i++)
  531. {
  532. //當邊值 不是 不相鄰int值(0|無權 無窮|有權),且未被訪問過時,可訪問
  533. if (this->arcs[index][i].adj != this->nonAdjInt && this->vexs_visited[i] != 1)
  534. {
  535. _DFS_R(i);
  536. }
  537. }
  538. }
  539. void GraphAdjMat::Display_BFS(string *vertex)
  540. {
  541. /*
  542. .廣度優先遍歷顯示,從指定頂點開始
  543. .類似於樹的層次遍歷算法
  544. */
  545. //1.判斷頂點是否存在
  546. int index = _Locate(*vertex);
  547. if (index == -1)
  548. return;
  549. //2.初始化頂點訪問數組
  550. for (int i = 0; i < this->_MAX_VERTEX_NUM; i++)
  551. {
  552. this->vexs_visited[i] = 0;
  553. }
  554. //3.廣度優先遍歷
  555. cout << "廣度優先遍歷:(從頂點" << *vertex << "開始)" << endl;
  556. //3.1.初始化隊列
  557. LinkQueue * vexQ = new LinkQueue();
  558. //3.2.訪問開始頂點,並標記訪問、入隊
  559. cout << this->vexs[index] << " ";
  560. this->vexs_visited[index] = 1;
  561. vexQ->EnQueue(new int(index));
  562. //3.3.出隊,並遍歷鄰接頂點(下一層次),訪問後入隊
  563. while (vexQ->GetHead() != NULL)
  564. {
  565. index = * vexQ->DeQueue();
  566. for (int j = 0; j < _MAX_VERTEX_NUM; j++)
  567. {
  568. //未訪問過的鄰接頂點
  569. if (this->arcs[index][j].adj != this->nonAdjInt && this->vexs_visited[j] != 1)
  570. {
  571. //訪問頂點,並標記訪問、入隊
  572. cout << this->vexs[j] << " ";
  573. this->vexs_visited[j] = 1;
  574. vexQ->EnQueue(new int(j));
  575. }
  576. }
  577. }
  578. //4.釋放隊列
  579. int * e;
  580. while (vexQ->GetHead() != NULL)
  581. {
  582. e = vexQ->DeQueue();
  583. delete e;
  584. }
  585. delete vexQ;
  586. }
  587. #endif // !GRAPHADJMAT_H_
  588. //文件名:"GraphAdjMat_Test.cpp"
  589. #include "stdafx.h"
  590. #include
  591. #include "GraphAdjMat.h"
  592. #include "ObjArrayList.h"
  593. using namespace std;
  594. int main()
  595. {
  596. //初始化頂點數據
  597. string * v1 = new string("v1");
  598. string * v2 = new string("v2");
  599. string * v3 = new string("v3");
  600. string * v4 = new string("v4");
  601. string * v5 = new string("v5");
  602. string * v6 = new string("v6");
  603. string * v7 = new string("v7");
  604. ObjArrayList * vexs = new ObjArrayList();
  605. vexs->Add(v1);
  606. vexs->Add(v2);
  607. vexs->Add(v3);
  608. vexs->Add(v4);
  609. vexs->Add(v5);
  610. vexs->Add(v6);
  611. vexs->Add(v7);
  612. //初始化邊(弧)數據
  613. GraphAdjMat::ArcData * arc1 = new GraphAdjMat::ArcData{ "v1", "v2", 2 };
  614. GraphAdjMat::ArcData * arc2 = new GraphAdjMat::ArcData{ "v1", "v3", 3 };
  615. GraphAdjMat::ArcData * arc3 = new GraphAdjMat::ArcData{ "v1", "v4", 4 };
  616. GraphAdjMat::ArcData * arc4 = new GraphAdjMat::ArcData{ "v3", "v1", 5 };
  617. GraphAdjMat::ArcData * arc5 = new GraphAdjMat::ArcData{ "v3", "v2", 6 };
  618. GraphAdjMat::ArcData * arc6 = new GraphAdjMat::ArcData{ "v3", "v5", 7 };
  619. GraphAdjMat::ArcData * arc7 = new GraphAdjMat::ArcData{ "v2", "v5", 8 };
  620. GraphAdjMat::ArcData * arc8 = new GraphAdjMat::ArcData{ "v4", "v6", 9 };
  621. GraphAdjMat::ArcData * arc9 = new GraphAdjMat::ArcData{ "v4", "v7", 9 };
  622. GraphAdjMat::ArcData * arc10 = new GraphAdjMat::ArcData{ "v6", "v7", 9 };
  623. ObjArrayList<:arcdata> * arcsList = new ObjArrayList<:arcdata>();
  624. arcsList->Add(arc1);
  625. arcsList->Add(arc2);
  626. arcsList->Add(arc3);
  627. arcsList->Add(arc4);
  628. arcsList->Add(arc5);
  629. arcsList->Add(arc6);
  630. arcsList->Add(arc7);
  631. arcsList->Add(arc8);
  632. arcsList->Add(arc9);
  633. arcsList->Add(arc10);
  634. //測試1:無向圖
  635. cout << endl << "無向圖初始化:" << endl;
  636. GraphAdjMat * udg = new GraphAdjMat(GraphAdjMat::UDG);
  637. udg->Init(vexs, arcsList);
  638. udg->Display();
  639. //1.1.深度優先遍歷
  640. cout << endl << "無向圖深度優先遍歷序列:" << endl;
  641. udg->Display_DFS(v1);
  642. //1.2.廣度優先遍歷
  643. cout << endl << "無向圖廣度優先遍歷序列:" << endl;
  644. udg->Display_BFS(v2);
  645. //1.3.插入新頂點、新邊
  646. cout << endl << "無向圖插入新頂點、新邊:" << endl;
  647. udg->InsertVertex(new string("v8"));
  648. udg->InsertArc(new GraphAdjMat::ArcData{ "v8", "v1", 8 });
  649. udg->Display();
  650. //1.4.刪除頂點、邊
  651. cout << endl << "無向圖刪除頂點v1、邊arc9:" << endl;
  652. udg->DeleteVertex(v1);
  653. udg->DeleteArc(arc9);
  654. udg->Display();
  655. //測試2:有向圖
  656. cout << endl << "有向圖:" << endl;
  657. GraphAdjMat * dg = new GraphAdjMat(GraphAdjMat::DG);
  658. dg->Init(vexs, arcsList);
  659. dg->Display();
  660. //2.1.深度優先遍歷
  661. cout << endl << "有向圖深度優先遍歷序列:" << endl;
  662. dg->Display_DFS(v1);
  663. //2.2.廣度優先遍歷
  664. cout << endl << "有向圖廣度優先遍歷序列:" << endl;
  665. dg->Display_BFS(v2);
  666. //測試:無向網
  667. cout << endl << "無向網:" << endl;
  668. GraphAdjMat * udn = new GraphAdjMat(GraphAdjMat::UDN);
  669. udn->Init(vexs, arcsList);
  670. udn->Display();
  671. //測試:有向網
  672. cout << endl << "有向網:" << endl;
  673. GraphAdjMat * dn = new GraphAdjMat(GraphAdjMat::DN);
  674. dn->Init(vexs, arcsList);
  675. dn->Display();
  676. return 0;
  677. }


分享到:


相關文章: