1 #include <iostream> 2 #include <algorithm> 3 4 using namespace std; 5 const int MaxNum = 100; 6 const int INF = 99999; 7 typedef struct srcNode { 8 int Vem; 9 struct srcNode * next; 10 } srcNode; 11 12 typedef struct vNode { 13 char data; 14 srcNode *src; 15 } vNode; 16 17 typedef struct GNode { 18 int vNum, srcNum; 19 vNode vNodeList[MaxNum]; 20 } Graph, GNode; 21 22 23 /** 24 *BFS 25 */ 26 void BFS(Graph *G) { 27 // 广度优先遍历需要维护一个队列 28 int v[MaxNum*MaxNum]; 29 int front = -1, rear = -1; 30 bool visited[MaxNum]; 31 for(int i=0; i<G->vNum; ++i) { 32 visited[i] = false; 33 } 34 v[++rear] = 0; 35 while(rear!=front) { 36 int vnow = v[++front]; 37 if(!visited[vnow]) { 38 // 访问 39 cout<<G->vNodeList[vnow].data<<endl; 40 visited[vnow] = true; 41 srcNode *p = G->vNodeList[vnow].src; 42 while(p) { 43 v[++rear] = p->Vem; 44 p = p->next; 45 } 46 47 } 48 } 49 } 50 51 /** 52 *DFS 53 */ 54 void DFS(Graph *G) { 55 int stack[MaxNum*MaxNum]; 56 int top = -1; 57 bool visited[G->vNum]; 58 for(int i=0; i<G->vNum; ++i) { 59 visited[i] = false; 60 } 61 62 stack[++top] = 0; 63 while(top!=-1) { 64 int vnow = stack[top--]; 65 if(!visited[vnow]) { 66 cout<<G->vNodeList[vnow].data<<endl; 67 visited[vnow] = true; 68 srcNode *p = G->vNodeList[vnow].src; 69 while(p) { 70 stack[++top] = p->Vem; 71 p = p->next; 72 } 73 } 74 } 75 } 76 77 /** 78 *DFS递归遍历 79 */ 80 bool isvisited[MaxNum*MaxNum]= {0}; 81 void DFS(Graph *G, int v) { 82 cout<<G->vNodeList[v].data<<endl; 83 isvisited[v] = true; 84 85 srcNode *p = G->vNodeList[v].src; 86 while(p) { 87 if(!isvisited[p->Vem]) { 88 DFS(G, p->Vem); 89 } 90 p = p->next; 91 } 92 } 93 94 /** 95 *构造图的邻接链表 96 */ 97 Graph *createGraph(char v[], int src[][6], int n) { 98 Graph *G = new Graph(); 99 G->srcNum = 7; 100 G->vNum = 6; 101 for(int i=0; i<n; i++) { 102 G->vNodeList[i].data = v[i]; 103 G->vNodeList[i].src = NULL; 104 105 for(int j=0; j<n; j++) { 106 if(src[i][j] != INF) { 107 srcNode *srcNow = new srcNode(); 108 srcNow->Vem = j; 109 srcNow->next = G->vNodeList[i].src; 110 G->vNodeList[i].src = srcNow; 111 } 112 } 113 } 114 return G; 115 } 116 117 118 /** 119 *最小生成树 120 */ 121 void prime(Graph *G, int src[][6]) { 122 // 维护两个数组 123 bool isVisited[G->vNum]; 124 // 就是结果集 125 int parents[G->vNum]; 126 127 // 初始化数组 128 for(int i=0; i<G->vNum; i++) { 129 isVisited[i] = false; 130 parents[i] = -1; 131 } 132 133 isVisited[0] = true; 134 int n=1; 135 while(n<G->vNum) { 136 int minL = INF; 137 //未访问的节点和已经访问的节点,这两点构成的边 138 int unvisited, visited; 139 for(int i=0; i<G->vNum; ++i) { 140 if(isVisited[i]) { 141 visited = i; 142 for(int j=0; j<G->vNum; ++j) { 143 if(!isVisited[j] && src[i][j] < minL) { 144 minL = src[i][j]; 145 unvisited = j; 146 } 147 } 148 } 149 150 } 151 152 isVisited[unvisited] = true; 153 parents[unvisited] = visited; 154 n++; 155 } 156 157 // 输出树 158 for(int i=0; i<G->vNum; i++) { 159 cout<<i<<":"<<parents[i]<<endl; 160 } 161 162 } 163 164 /** 165 *Kruskal 166 */ 167 //点边对 168 typedef struct VS { 169 int x, y; 170 int length; 171 } VS; 172 int com(VS vs1, VS vs2) { 173 return vs1.length>vs2.length; 174 } 175 //讲边按照长度进行排序 176 int VSsort(VS vsarray[], int src[][6], int vNum) { 177 int top = -1; 178 // 将所有节点封装成点边对,装入数组 179 for(int i=0; i<vNum; ++i) { 180 for(int j=0; j<vNum; ++j) { 181 if(src[i][j] != INF) { 182 VS vsnode; 183 vsnode.x = i; 184 vsnode.y = j; 185 vsnode.length = src[i][j]; 186 vsarray[++top] = vsnode; 187 } 188 } 189 } 190 sort(vsarray, vsarray+top+1, com); 191 return top; 192 } 193 194 int findRoot(int v, int parents[]) { 195 if(parents[v] == -1) { 196 return v; 197 } 198 return findRoot(parents[v], parents); 199 } 200 201 bool unionV(int v1, int v2, int parents[]) { 202 int v1root = findRoot(v1, parents); 203 int v2root = findRoot(v2, parents); 204 if(v1root == v2root) { 205 return false; 206 } 207 parents[v1root] = v2root; 208 return true; 209 } 210 211 void Kruskal(int src[][6], int vNum) { 212 VS vsArray[MaxNum]; 213 int top = VSsort(vsArray, src, vNum); 214 //并查集 ,并非结果集 215 int parents[vNum]; 216 int result[vNum]; 217 for(int i=0; i<vNum; ++i) { 218 parents[i] = -1; 219 result[i] = -1; 220 } 221 222 int n=0; 223 while(n < vNum-1) { 224 VS vsnode = vsArray[top--]; 225 if(unionV(vsnode.x, vsnode.y, parents)) { 226 result[vsnode.x] = vsnode.y; 227 n++; 228 } 229 } 230 231 // 输出树 232 for(int i=0; i<vNum; i++) { 233 cout<<i<<":"<<result[i]<<endl; 234 } 235 } 236 /** 237 *多源最短路径 238 */ 239 void flyoed(int src[][6], int origition, int destination) { 240 int length[6][6]; 241 int parents[6][6]; 242 // 备份路径长度,不能在原来上边更改 243 for(int i=0; i<6; i++) { 244 for(int j=0; j<6; ++j) { 245 length[i][j] = src[i][j]; 246 parents[i][j] = j; 247 } 248 249 } 250 251 for(int i=0; i<6; i++) { 252 for(int j=0; j<6; j++) { 253 for(int k=0; k<6; k++) { 254 if((length[j][i] + length[i][k]) < length[j][k]) { 255 length[j][k] = (length[j][i] + length[i][k]); 256 parents[j][k] = parents[j][i]; 257 } 258 } 259 } 260 } 261 cout<<length[origition][destination]<<endl; 262 cout<<origition<<" "; 263 int ori = origition; 264 while(ori != destination) { 265 cout<<parents[ori][destination]<<" "; 266 ori = parents[ori][destination]; 267 } 268 269 } 270 /** 271 *单源最短路径 272 */ 273 void Dijkstra(int src[][6], int origition, int destination) { 274 int path[6]; 275 // 表示到目标点距离 276 int length[6]; 277 bool isvisited[6]; 278 for(int i=0; i<6; i++) { 279 path[i] = -1; 280 length[i] = src[i][destination]; 281 isvisited[i] = false; 282 } 283 isvisited[destination] = true; 284 for(int i=0; i<6; i++) { 285 int nowShortestNode = destination; 286 // 从未收录的点中找一个到目标点距离最小的 287 for(int j=0; j<6; j++){ 288 if(!isvisited[j] && length[j] < length[nowShortestNode]){ 289 nowShortestNode = j; 290 } 291 } 292 isvisited[nowShortestNode] = true; 293 // 刷新其他顶点经过这个最小的点,到目标顶点的距离 294 for(int j=0; j<6; j++){ 295 if(!isvisited[j] && (src[j][nowShortestNode] +length[nowShortestNode])< length[j]){ 296 length[j] = src[j][nowShortestNode] +length[nowShortestNode]; 297 path[j] = nowShortestNode; 298 } 299 } 300 301 } 302 303 // 输出路径 304 cout<<length[origition]<<endl; 305 int p = origition; 306 cout<<p<<" "; 307 while(path[p] != -1){ 308 cout<<path[p]<<" "; 309 p = path[p]; 310 } 311 cout<<destination; 312 313 } 314 void show(Graph *G) { 315 for(int i=0; i<G->vNum; i++) { 316 srcNode *p = G->vNodeList[i].src; 317 while(p) { 318 cout<<G->vNodeList[p->Vem].data<<" "; 319 p = p->next; 320 } 321 cout<<endl; 322 } 323 } 324 325 int main() { 326 char v[]= {'a', 'b', 'c', 'd', 'e', 'f'}; 327 int src[6][6] = { 328 329 { INF, 6,INF,INF, 7,INF}, 330 { 6,INF, 2, 3,INF, 5 }, 331 { INF, 2,INF,INF, 1, 5 }, 332 { INF, 3,INF,INF,INF, 4 }, 333 { 7,INF, 1,INF,INF,INF}, 334 { INF, 5, 5, 4,INF,INF}, 335 }; 336 337 Graph *G = createGraph(v, src, 6); 338 // prime(G, src); 339 // Kruskal(src, 6); 340 // show(G); 341 // BFS(G); 342 // DFS(G); 343 // cout<<"**********************"<<endl; 344 // DFS(G, 0); 345 flyoed(src,5, 4); 346 cout<<endl; 347 Dijkstra(src, 5, 4); 348 }