数据结构:图(2)
一、最小生成树
1.普利姆算法:稠密图
图的存贮结构采用邻接矩阵.此方法是按各个顶点连通的步骤进行,需要用一个顶点集合,开始为空集,以后将以连通的顶点陆续加入到集合中,全部顶点加入集合后就得到所需的最小生成树。
算法理解:
2.克鲁斯卡尔算法:稀疏图
图的存贮结构采用边集数组,且权值相等的边在数组中排列次序可以是任意的.该方法对于边相对比较多的不是很实用,浪费时间
算法理解:
二、最短路径
1.Dijkstra 算法
算法解决的是有向图中单个源点到其他顶点的最短路径问题。举例来说,如果图中的顶点表示城市,而边上的权重表示城市间开车行经的距离,Dijkstra 算法可以用来找到两个城市之间的最短路径。
算法理解:
2.Floyd算法
是解决任意两点间的最短路径的一种算法,可以正確處理有向圖或负权的最短路径問題,同时也被用于计算有向图的传递闭包。
算法理解:
代码示例:
1 ///Name:Tree 2 ///Author:JA 3 ///Date:2015-3-11 4 5 6 7 /* 8 * 最短路径,迪杰斯特拉算法和弗洛伊德算法(采用邻接矩阵存储) 9 * 10 */ 11 12 #include<stdio.h> 13 14 #define MAX_VERTEX_NUM 20 15 #define INFINITE 10000 //当做无穷大 16 //图的定义 17 typedef struct 18 { 19 int vertexNum; 20 char vertex[MAX_VERTEX_NUM]; 21 int arc[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; 22 }Graph, *PGraph; 23 24 //辅助数组中的元素定义 25 typedef struct 26 { 27 int distance; 28 int path[MAX_VERTEX_NUM]; 29 }ArrayNode; 30 31 32 //构造有向网 33 void createdGraph(PGraph g) 34 { 35 int i, j; 36 g->vertexNum = 6; 37 for (i = 0; i<g->vertexNum; i++) 38 g->vertex[i] = 'A' + i; 39 for (i = 0; i<g->vertexNum; i++) 40 for (j = 0; j<g->vertexNum; j++) 41 g->arc[i][j] = 0; 42 g->arc[0][2] = 10; 43 g->arc[0][4] = 30; 44 g->arc[0][5] = 100; 45 g->arc[1][2] = 5; 46 g->arc[2][3] = 50; 47 g->arc[3][5] = 10; 48 g->arc[4][3] = 20; 49 g->arc[4][5] = 60; 50 } 51 52 //迪杰斯特拉算法 53 void Dijkstra(PGraph g, int from, int to) 54 { 55 int i, j, index = -1; 56 int n = 1;//记录已经求出的两个点之间的最短距离的个数 57 ArrayNode shortestPath[MAX_VERTEX_NUM]; 58 int flag[MAX_VERTEX_NUM] = { 0 };//标记,为1表示到这个顶点的最短距离已求出 59 60 //1.求from到各个顶点的直接距离,即初始化shortestPath数组 61 for (i = 0; i<g->vertexNum; i++){ 62 if (from == i){ 63 shortestPath[i].distance = 0; 64 shortestPath[i].path[0] = i; 65 flag[from] = 1; 66 } 67 else if (g->arc[from][i]>0){ 68 shortestPath[i].path[0] = from; 69 shortestPath[i].path[1] = i; 70 shortestPath[i].distance = g->arc[from][i]; 71 } 72 else 73 shortestPath[i].distance = INFINITE; 74 } 75 //2.每次求一个最短路径 76 while (n<g->vertexNum){ 77 //选择shortestPath中距离最小的,求出from到这个顶点的最短路径 78 index = -1; 79 for (i = 0; i<g->vertexNum; i++){ 80 if (i == from) 81 continue; 82 if (flag[i] == 0 && index == -1 && shortestPath[i].distance != INFINITE) 83 index = i; 84 if (flag[i] == 0 && index != -1 && shortestPath[i].distance<shortestPath[index].distance) 85 index = i; 86 } 87 flag[index] = 1; 88 //修改到各个顶点的最短路径 89 for (i = 0; i<g->vertexNum; i++){ 90 if (i == from) 91 continue; 92 if (g->arc[index][i]>0 && g->arc[index][i] + shortestPath[index].distance<shortestPath[i].distance){ 93 shortestPath[i].distance = g->arc[index][i] + shortestPath[index].distance; 94 //修改路径 95 j = 0; 96 while (1){ 97 shortestPath[i].path[j] = shortestPath[index].path[j]; 98 if (shortestPath[index].path[j] == index) 99 break; 100 j++; 101 } 102 shortestPath[i].path[j + 1] = i; 103 } 104 } 105 n++; 106 } 107 //输出from到to的最短路径及长度 108 if (shortestPath[to].distance == INFINITE){ 109 printf("%c到%c没有路径\n", from + 'A', to + 'A'); 110 return; 111 } 112 printf("%c到%c的最短路径长度是:%d\n", from + 'A', to + 'A', shortestPath[to].distance); 113 printf("经过的顶点: "); 114 i = 0; 115 while (1){ 116 printf("%-3c", shortestPath[to].path[i] + 'A'); 117 if (shortestPath[to].path[i] == to) 118 break; 119 i++; 120 } 121 printf("\n"); 122 } 123 124 //弗洛伊德算法 125 void Floyd(PGraph g, int from, int to) 126 { 127 int i, j, k; 128 int shortestPath[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//存储最短路径的数组 129 //初始化shortestPath 130 for (i = 0; i<g->vertexNum; i++) 131 for (j = 0; j<g->vertexNum; j++){ 132 if (i == j){ 133 shortestPath[i][j] = 0; 134 continue; 135 } 136 if (g->arc[i][j]>0) 137 shortestPath[i][j] = g->arc[i][j]; 138 else 139 shortestPath[i][j] = INFINITE; 140 } 141 //将各个顶点顺次加入,并修改最短路径 142 for (k = 0; k<g->vertexNum; k++){ 143 //在i,j之间加入k 144 for (i = 0; i<g->vertexNum; i++){ 145 for (j = 0; j<g->vertexNum; j++){ 146 if (shortestPath[i][k] + shortestPath[k][j]<shortestPath[i][j]) 147 shortestPath[i][j] = shortestPath[i][k] + shortestPath[k][j]; 148 } 149 } 150 } 151 //输出最短路径 152 if (shortestPath[from][to] == INFINITE){ 153 printf("%c到%c没有路径\n", from + 'A', to + 'A'); 154 return; 155 } 156 printf("%c到%c的最短路径长度是:%d\n", from + 'A', to + 'A', shortestPath[from][to]); 157 printf("\n"); 158 } 159 160 void main() 161 { 162 Graph graph; 163 char from, to; 164 createdGraph(&graph); 165 printf("请输入起点终点(如AF,中间不要有空格)\n"); 166 scanf("%c%c", &from, &to); 167 printf("\n迪杰斯特拉算法:\n"); 168 Dijkstra(&graph, from - 'A', to - 'A'); 169 printf("\n弗洛伊德算法:\n"); 170 Floyd(&graph, from - 'A', to - 'A'); 171 }
3/12/2015 2:12:53 PM