图的代码实现(邻接矩阵)
不知上期各位读者思考得怎么样了,这期的文章是接上一期的。
本文的主要内容为:图的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 }
以上就是图的邻接矩阵的具体的实现方法。
有不懂之处,欢迎各位读者留言评论交流。
有不足之处,希望各位读者多多包涵,也希望读者们能留言评论指出我的不足,十分感谢!
下期预告:利用图实现:拓扑排序算法,最小路径算法,最小生成树算法,敬请期待。
赞 (0)