不知上期各位讀者思考得怎么樣了,這期的文章是接上一期的。
本文的主要內容為:圖的C++代碼實現 (鄰接矩陣法),主要為各個類的具體實現
圖的抽象基類
1 // FilenName: Graph.cpp 2 3 #include "Graph.h" 4 5 const int CGraph::UNVISITED = 0; 6 const int CGraph::VISITED = 1; 7 8 CGraph::CGraph(int numVertex) { 9 this->numVertex = numVertex; 10 this->numEdge = 0; 11 this->mark = new int[this->numVertex]; 12 this->inDegree = new int[this->numVertex]; 13 14 for(int i = 0; i < this->numVertex; i++){ 15 this->mark[i] = CGraph::UNVISITED; 16 this->inDegree[i] = 0; 17 } 18 } 19 20 CGraph::~CGraph() { 21 delete[] this->mark; 22 delete[] this->inDegree; 23 } 24 25 int CGraph::GetVerticesNum() { 26 return this->numVertex; 27 } 28 29 int CGraph::GetEdgesNum() { 30 return this->numEdge; 31 } 32 33 int CGraph::GetFromVertex(CEdge oneEdge) { 34 return oneEdge.from; 35 } 36 37 int CGraph::GetToVertex(CEdge oneEdge) { 38 return oneEdge.to; 39 } 40 41 int CGraph::GetWeight(CEdge oneEdge) { 42 return oneEdge.weight; 43 } 44 45 bool CGraph::IsEdge(CEdge oneEdge) { 46 return (oneEdge.from >= 0 && oneEdge.to >=0 && oneEdge.weight >= 0); 47 } 48 49 void CGraph::ResetMark() { 50 for(int i = 0; i < this->numVertex; i++){ 51 this->mark[i] = CGraph::UNVISITED; 52 } 53 }
圖的鄰接矩陣實現類
1 // FileName: GraphAdjacentMatrix.cpp 2 3 #include "GraphAdjacentMatrix.h" 4 #include <queue> 5 using namespace std; 6 7 /********************************************** 8 * 函數功能:構造函數,動態分配鄰接矩陣二維數組, 9 * 調用者無需釋放,析構函數會自動釋放 10 * @param: 11 * numVertex: 圖的頂點數目 12 * @return: 13 * 無 14 *********************************************/ 15 CGraphM::CGraphM(int numVertex) : CGraph(numVertex) { 16 this->matrix = (int**) new int*[this->numVertex]; 17 for(int i = 0; i < numVertex; i++){ 18 this->matrix[i] = new int[this->numVertex]; 19 } 20 21 for(int i = 0; i < numVertex; i++){ 22 for(int j = 0; j < numVertex; j++){ 23 this->matrix[i][j] = 0; 24 } 25 } 26 } 27 28 29 /************************************************ 30 * 函數功能:析構函數,釋放動態分配的鄰接矩陣二維數組 31 * @param: 32 * Null 33 * @return: 34 * 無 35 ***********************************************/ 36 CGraphM::~CGraphM() { 37 for(int i = 0; i < this->numVertex; i++){ 38 delete [] this->matrix[i]; 39 } 40 delete [] this->matrix; 41 } 42 43 44 /********************************************** 45 * 函數功能:刪除邊 46 * @param: 47 * from: 邊的起點 48 * to: 邊的終點 49 * @return: 50 * void 51 *********************************************/ 52 void CGraphM::delEdge(int from, int to) { 53 if(from == to){ 54 this->matrix[from][to] = 0; 55 } 56 else{ 57 this->matrix[from][to] = -1; 58 } 59 this->inDegree[to]--; 60 this->numEdge--; 61 } 62 63 /********************************************** 64 * 函數功能:設置邊 65 * @param: 66 * from: 邊的起點 67 * to: 邊的終點 68 * weight:邊的權值 69 * @return: 70 * void 71 *********************************************/ 72 void CGraphM::SetEdge(int from, int to, int weight) { 73 if(from == to){ 74 this->matrix[from][to] = 0; 75 } 76 else{ 77 this->matrix[from][to] = weight; 78 } 79 this->inDegree[to]++; 80 this->numEdge++; 81 } 82 83 /********************************************** 84 * 函數功能:獲取以參數 oneVertex 為起點的第一條邊 85 * @param: 86 * oneVertex: 邊的起點 87 * @return: 88 * 邊類對象 89 *********************************************/ 90 CEdge CGraphM::FirstEdge(int oneVertex) { 91 CEdge resultEdge; // 函數返回值 92 resultEdge.from = oneVertex; // 起點 93 94 for(int i = 0; i < this->numVertex; i++){ 95 if(this->matrix[resultEdge.from][i] > 0){ 96 resultEdge.to = i; 97 resultEdge.weight = this->matrix[resultEdge.from][i]; 98 break; 99 } 100 } 101 return resultEdge; 102 } 103 104 /********************************************** 105 * 函數功能:獲取和參數 perEdge 同起點的下一條邊 106 * @param: 107 * preEdge: 上一條邊 108 * @return: 109 * 邊類對象 110 *********************************************/ 111 CEdge CGraphM::NextEdge(CEdge preEdge) { 112 CEdge resultEdge; // 函數返回值 113 resultEdge.from = preEdge.from; // 起點 114 if(preEdge.to < this->numVertex - 1){ // 如果上一條邊的終點 小於 頂點的個數減1 則存在下一條邊 115 for(int i = preEdge.to + 1; i < this->numVertex; i++){ 116 if(this->matrix[preEdge.from][i] > 0){ 117 resultEdge.to = i; 118 resultEdge.weight = this->matrix[preEdge.from][i]; 119 break; 120 } 121 } 122 } 123 return resultEdge; 124 } 125 126 /********************************************** 127 * 函數功能:初始化圖 128 * @param: 129 * pWArray2D: 二維鄰接矩陣的一維指針 130 * @return: 131 * void 132 *********************************************/ 133 void CGraphM::InitGraphM(int *pWArray2D) { 134 int N = this->numVertex; 135 int array_i_j = 0; 136 137 for(int i = 0; i < N; i++){ 138 for(int j = 0; j < N; j++){ 139 array_i_j = *(pWArray2D + i * N + j); // 用一維數組的方式訪問二維數組 *(起點地址 + 行數 * 總行數 + 列數) 140 if(array_i_j > 0){ 141 this->SetEdge(i, j, array_i_j); 142 } 143 } 144 } 145 } 146 147 /********************************************** 148 * 函數功能:深度優先搜索 149 * @param: 150 * oneVertex: 開始搜索的起點 151 * @return: 152 * void 153 *********************************************/ 154 void CGraphM::DFS(int oneVertex) { 155 this->mark[oneVertex] = CGraph::VISITED; 156 this->Visit(oneVertex); 157 158 for(CEdge edge = this->FirstEdge(oneVertex); this->IsEdge(edge); edge = this->NextEdge(edge)){ 159 if(this->mark[edge.to] == CGraph::UNVISITED){ 160 this->DFS(edge.to); 161 } 162 } 163 } 164 165 /********************************************** 166 * 函數功能:廣度優先搜索 167 * @param: 168 * oneVertex: 開始搜索的起點 169 * @return: 170 * void 171 *********************************************/ 172 void CGraphM::BFS(int oneVertex) { 173 queue<int> queueEdge; 174 this->Visit(oneVertex); 175 this->mark[oneVertex] = CGraph::VISITED; 176 queueEdge.push(oneVertex); 177 178 while(!queueEdge.empty()){ 179 int u = queueEdge.front(); 180 queueEdge.pop(); 181 for(CEdge edge = this->FirstEdge(oneVertex); this->IsEdge(edge); edge = this->NextEdge(edge)){ 182 if(this->mark[edge.to] == CGraph::UNVISITED){ 183 this->Visit(edge.to); 184 this->mark[edge.to] = CGraph::VISITED; 185 queueEdge.push(edge.to); 186 } 187 } 188 } 189 } 190 191 192 /********************************************** 193 * 函數功能:訪問頂點 194 * @param: 195 * oneVertex: 要訪問的頂點 196 * @return: 197 * void 198 *********************************************/ 199 void CGraphM::Visit(int oneVertex) { 200 cout << "C" << oneVertex << " "; 201 } 202 203 204 /********************************************** 205 * 函數功能:圖的周游接口合並 206 * @param: 207 * startVertex: 開始周游的起點 208 * travelType: 周游類型 209 * travelType = 0: DFS 210 * travelType = 1: BFS 211 * @return: 212 * void 213 *********************************************/ 214 void CGraphM::Travel(int startVertex, int travelType) { 215 for(int i = startVertex, n = 0; n < this->numVertex; i++, n++){ 216 i %= this->numVertex; 217 if(this->mark[i] == CGraph::UNVISITED){ 218 switch(travelType){ 219 case 0: 220 this->DFS(i); 221 break; 222 case 1: 223 this->BFS(i); 224 break; 225 default: 226 cout << "Error: travelType must be in [0, 1]" << endl; 227 break; 228 } 229 } 230 } 231 }
以上就是圖的鄰接矩陣的具體的實現方法。
有不懂之處,歡迎各位讀者留言評論交流。
有不足之處,希望各位讀者多多包涵,也希望讀者們能留言評論指出我的不足,十分感謝!
下期預告:利用圖實現:拓撲排序算法,最小路徑算法,最小生成樹算法,敬請期待。