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