图的相关操作

  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 }
View Code

 

posted @ 2019-10-29 20:43  nefuer  阅读(187)  评论(0编辑  收藏  举报