图的最短路径(Dijkstra)(Floyd),拓扑排序,生成树代码
使用邻接矩阵存储加权图,无穷大使用常数MAXLEN代表,然后使用Dijkstra方法求取最短路径
1 #include <stdio.h> 2 3 #define MAXLEN 1000 4 int cost[7][7]; 5 int dist[7]; 6 7 void creategraph(int* node,int num) 8 { 9 int from; 10 int to; 11 int i; 12 for(i = 0;i < num; i++) 13 { 14 from = node[i*3]; 15 to = node[i*3+1]; 16 cost[from][to] = node[i*3+2]; 17 } 18 } 19 20 void shortestpath(int begin,int num) 21 { 22 int selected[7]; 23 int min; 24 int s; 25 int i,j; 26 27 for(i = 2;i <= num;i++) 28 { 29 selected[i] = 0; 30 dist[i] = cost[begin][i]; 31 } 32 selected[begin] = 1; 33 dist[begin] = 0; 34 printf("顶点1 2 3 4 5 6\n"); 35 for(j = 1;j <= num;j++) 36 printf(" %4d ",dist[j]); 37 printf("\n"); 38 for(i = 1;i <= num - 1;i++) 39 { 40 min = MAXLEN; 41 for(j = 1;j <= num;j++) 42 if(min > dist[j] && selected[j] == 0) 43 { 44 s = j; 45 min = dist[j]; 46 } 47 selected[s] = 1; 48 for(j = 1;j <= num;j++) 49 { 50 if(selected[j] == 0 && 51 dist[s] + cost[s][j] < dist[j]) 52 dist[j] = dist[s] + cost[s][j]; 53 printf(" %4d ",dist[j]); 54 } 55 printf("\n"); 56 } 57 } 58 59 int main() 60 { 61 int node[7][3] = { 62 { 1, 2, 35}, 63 { 2, 3, 45}, 64 { 2, 4, 30}, 65 { 3, 5, 25}, 66 { 4, 5, 45}, 67 { 4, 6, 130}, 68 { 5, 6, 100}, 69 }; 70 int i,j; 71 72 for(i = 1;i <= 6;i++) 73 for(j = 1;j <= 6;j++) 74 cost[i][j] = MAXLEN; 75 creategraph(node,7); 76 printf("加权图的邻接矩阵内容:\n"); 77 for(i = 1;i <= 6;i++) 78 { 79 for(j = 1;j <= 6;j++) 80 printf(" %4d ",cost[i][j]); 81 printf("\n"); 82 } 83 printf("\n从顶点1到各顶点最近距离计算过程:\n"); 84 shortestpath(1,6); 85 }
改用Floyd方法计算各顶点到其他各顶点的最短距离
1 #include <stdio.h> 2 3 #define MAXLEN 1000 4 int cost[7][7]; 5 int dist[7][7]; 6 7 void creategraph(int* node,int num) 8 { 9 int from; 10 int to; 11 int i; 12 for(i = 0;i < num; i++) 13 { 14 from = node[i*3]; 15 to = node[i*3+1]; 16 cost[from][to] = node[i*3+2]; 17 cost[to][from] = node[i*3+2]; 18 } 19 } 20 21 void shortestpath(int num) 22 { 23 int i,j,k; 24 for(i = 1;i <= num;i++) 25 for(j = 1;j <= num;j++) 26 if(i != j) 27 dist[i][j] = cost[i][j]; 28 else 29 dist[i][j] = 0; 30 for(k = 1;k <= num;k++) 31 for(i = 1;i <= num;i++) 32 for(j = 1;j <= num;j++) 33 if(dist[i][k] + dist[k][j] < dist[i][j]) 34 dist[i][j] = dist[i][k] + dist[k][j]; 35 } 36 37 int main() 38 { 39 int node[7][3] = { 40 { 1, 2, 35}, 41 { 2, 3, 45}, 42 { 2, 4, 30}, 43 { 3, 5, 25}, 44 { 4, 5, 45}, 45 { 4, 6, 130}, 46 { 5, 6, 100}, 47 }; 48 int i,j; 49 50 for(i = 1;i <= 6;i++) 51 for(j = 1;j <= 6;j++) 52 cost[i][j] = MAXLEN; 53 creategraph(node,7); 54 printf("加权图的邻接矩阵内容:\n"); 55 for(i = 1;i <= 6;i++) 56 { 57 for(j = 1;j <= 6;j++) 58 printf(" %4d ",cost[i][j]); 59 printf("\n"); 60 } 61 shortestpath(6); 62 printf("\n从各顶点到各顶点最近距离:\n"); 63 printf("顶点1 2 3 4 5 6\n"); 64 for(i = 1;i <= 6;i++) 65 { 66 for(j = 1;j <= 6;j++) 67 printf(" %4d ",dist[i][j]); 68 printf("\n"); 69 } 70 71 }
导入一个包含回路和不包含回路的图,然后将拓扑排序的内容输出来
1 #include <stdlib.h> 2 #include <stdio.h> 3 4 #define MAXQUEUE 20 5 6 struct node 7 { 8 int vertex; 9 struct node* nextnode; 10 }; 11 12 typedef struct node* graph; 13 struct node head1[8]; 14 struct node head2[8]; 15 16 int queue[MAXQUEUE]; 17 int front = -1; 18 int rear = -1; 19 20 void creategraph(graph head,int* node,int num) 21 { 22 graph newnode; 23 graph ptr; 24 int from; 25 int to; 26 int i; 27 28 for(i = 0;i < num;i++) 29 { 30 from = node[i*2]; 31 to = node[i*2+1]; 32 head[to].vertex += 1; 33 newnode = (graph)malloc(sizeof(struct node)); 34 newnode->vertex = to; 35 newnode->nextnode = NULL; 36 ptr = &(head[from]); 37 while(ptr->nextnode != NULL) 38 ptr = ptr->nextnode; 39 ptr->nextnode = newnode; 40 } 41 } 42 43 int enqueue(int value) 44 { 45 if(rear + 1 == front || 46 (rear == (MAXQUEUE - 1) && front <= 0)) 47 return -1; 48 rear++; 49 if(rear == MAXQUEUE) 50 rear = 0; 51 queue[rear] = value; 52 } 53 54 int dequeue() 55 { 56 if(front == rear) 57 return -1; 58 front++; 59 if(front == MAXQUEUE) 60 front = 0; 61 return queue[front]; 62 } 63 64 int toposort(graph head,int num) 65 { 66 graph ptr; 67 int i; 68 69 for(i = 1;i <= num;i++) 70 if(head[i].vertex == 0) 71 enqueue(i); 72 while((i = dequeue()) != -1) 73 { 74 printf(" %d ",i); 75 ptr = head[i].nextnode; 76 while(ptr != NULL) 77 { 78 i = ptr->vertex; 79 head[i].vertex --; 80 if(head[i].vertex == 0) 81 enqueue(i); 82 ptr = ptr->nextnode; 83 } 84 } 85 printf("\n"); 86 for(i = 1;i <= num;i++) 87 if(head[i].vertex != 0) 88 return 1; 89 return 0; 90 } 91 92 int main() 93 { 94 graph ptr; 95 int node[10][2] = { 96 { 3, 2}, 97 { 2, 1}, 98 { 2, 5}, 99 { 2, 6}, 100 { 1, 4}, 101 { 5, 4}, 102 { 7, 4}, 103 { 6, 7}, 104 { 5, 6}, 105 { 7, 5} 106 }; 107 int i; 108 for(i = 1;i <= 7;i++) 109 { 110 head1[i].vertex = 0; 111 head1[i].nextnode = NULL; 112 head2[i].vertex = 0; 113 head2[i].nextnode = NULL; 114 } 115 creategraph(head1,node,8); 116 creategraph(head2,node,10); 117 printf("图1 - 含入度的邻接表内容:\n"); 118 for(i = 1;i <= 7;i++) 119 { 120 printf("顶点%d(%d) =>",i,head1[i].vertex); 121 ptr = head1[i].nextnode; 122 while(ptr != NULL) 123 { 124 printf(" %d ",ptr->vertex); 125 ptr = ptr->nextnode; 126 } 127 printf("\n"); 128 } 129 printf("图1 - 拓扑排序的内容:\n"); 130 if(toposort(head1,7)) 131 printf("图有回路\n"); 132 else 133 printf("图没有回路\n"); 134 front = rear = -1; 135 printf("\n图2 - 含入度的邻接表内容:\n"); 136 for(i = 1;i <= 7;i++) 137 { 138 printf("顶点%d(%d) =>",i,head2[i].vertex); 139 ptr = head2[i].nextnode; 140 while(ptr != NULL) 141 { 142 printf(" %d ",ptr->vertex); 143 ptr = ptr->nextnode; 144 } 145 printf("\n"); 146 } 147 printf("图2 - 拓扑排序的内容:\n"); 148 if(toposort(head2,7)) 149 printf("图有回路\n"); 150 else 151 printf("图没有回路\n"); 152 return 0; 153 }
图的最小生成树
1 #include <stdlib.h> 2 #include <stdio.h> 3 4 struct edge 5 { 6 int from; 7 int to; 8 int weight; 9 struct edge* nextedge; 10 }; 11 12 typedef struct edge* edgelist; 13 edgelist list = NULL; 14 int node[6]; 15 16 edgelist createedgelist(edgelist list,int* edges,int num) 17 { 18 edgelist newnode; 19 edgelist last; 20 int i; 21 22 for(i = 0;i < num;i++) 23 { 24 newnode = (edgelist)malloc(sizeof(struct edge)); 25 newnode->from = edges[3*i]; 26 newnode->to = edges[3*i+1]; 27 newnode->weight = edges[3*i+2]; 28 newnode->nextedge = NULL; 29 if(list == NULL) 30 { 31 list = newnode; 32 last = list; 33 } 34 else 35 { 36 last->nextedge = newnode; 37 last = newnode; 38 } 39 } 40 return list; 41 } 42 43 int uniongroup(int from,int to) 44 { 45 int to_root; 46 to_root = to; 47 while(node[to_root] > 0) 48 to_root = node[to_root]; 49 node[to_root] = from; 50 } 51 52 int samegroup(int from,int to) 53 { 54 int from_root; 55 int to_root; 56 57 from_root = from; 58 while(node[from_root] > 0) 59 from_root = node[from_root]; 60 to_root = to; 61 while(node[to_root] > 0) 62 to_root = node[to_root]; 63 if(from_root == to_root) 64 return 1; 65 else 66 return 0; 67 } 68 69 void minspantree() 70 { 71 edgelist ptr; 72 73 ptr = list; 74 while(ptr != NULL) 75 { 76 if(!samegroup(ptr->from,ptr->to)) 77 { 78 printf("从顶点: %d 到: %d 权值: %d\n",ptr->from, 79 ptr->to,ptr->weight); 80 uniongroup(ptr->from,ptr->to); 81 } 82 ptr = ptr->nextedge; 83 } 84 } 85 86 int main() 87 { 88 int edges[8][3] = { 89 { 1, 2, 2}, 90 { 2, 4, 3}, 91 { 1, 4, 4}, 92 { 3, 5, 5}, 93 { 2, 5, 6}, 94 { 2, 3, 8}, 95 { 3, 4, 10}, 96 { 4, 5, 15} 97 }; 98 int i; 99 list = createedgelist(list,edges,8); 100 for(i = 1;i <= 5;i++) 101 node[i] = -1; 102 printf("图的最小生成树:\n"); 103 minspantree(); 104 printf("顶点数组内容:\n"); 105 for(i = 1;i <= 5;i++) 106 printf("[%d]",node[i]); 107 printf("\n"); 108 return 0; 109 }