数据结构:图(2)

一、最小生成树

1.普利姆算法:稠密图

图的存贮结构采用邻接矩阵.此方法是按各个顶点连通的步骤进行,需要用一个顶点集合,开始为空集,以后将以连通的顶点陆续加入到集合中,全部顶点加入集合后就得到所需的最小生成树。

算法理解:

Prim

2.克鲁斯卡尔算法:稀疏图

图的存贮结构采用边集数组,且权值相等的边在数组中排列次序可以是任意的.该方法对于边相对比较多的不是很实用,浪费时间

算法理解:

Kruskal

二、最短路径

1.Dijkstra 算法

算法解决的是有向图中单个源点到其他顶点的最短路径问题。举例来说,如果图中的顶点表示城市,而边上的权重表示城市间开车行经的距离,Dijkstra 算法可以用来找到两个城市之间的最短路径。

算法理解:

Dijkstra

2.Floyd算法

是解决任意两点间的最短路径的一种算法,可以正確處理有向圖或负权的最短路径問題,同时也被用于计算有向图的传递闭包。

算法理解:

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

 


3/12/2015 2:12:53 PM

posted @ 2015-03-12 15:01  J·A  阅读(185)  评论(0编辑  收藏  举报