源代碼發上。
一、最短路徑算法
例子:
二、源代碼
- /******************************
- * date:2011-3-31
- * filename:dijkstra_main.c
- * by:Jelline
- * ****************************/
- #include <stdio.h>
- #define MAX_WEIGHT 0X7FFFFFFF
- int dijkstra(int n, int adjMatrix[][n], int startV, int endV, int prev[]);
- void printShortestPath(int n, int adjMatrix[][n], int startV, int endV, const char **vertexStr);
- int main()
- {
- //char vertex[] = {'a', '1', '2', '3', '4', '5', '6', 'b'};
- const char *vertexStr[8] = {"a", "v1", "v2", "v3", "v4", "v5", "v6", "b"};
- int adjMatrix[8][8] = {
- {MAX_WEIGHT, 2, 8, 1, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT},
- {2, MAX_WEIGHT, 6, MAX_WEIGHT, 1, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT},
- {8, 6, MAX_WEIGHT, 7, 4, 2, 2, MAX_WEIGHT},
- {1, 7, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, 9, MAX_WEIGHT},
- {MAX_WEIGHT, 1, 4, MAX_WEIGHT, MAX_WEIGHT, 3, MAX_WEIGHT, 9},
- {MAX_WEIGHT, 2, MAX_WEIGHT, MAX_WEIGHT, 3, MAX_WEIGHT, 4, 6},
- {MAX_WEIGHT, MAX_WEIGHT, 2, 9, MAX_WEIGHT, 4, MAX_WEIGHT, 2},
- {MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, 9, 6, 2, MAX_WEIGHT}
- };
- /*
- int adjMatrix[8][8] = {
- //{0, 1, 2, 3, 4, 5, 6, 7}
- {0, 2, 8, 1, 0, 0, 0, 0},
- {2, 0, 6, 0, 1, 0, 0, 0},
- {8, 6, 0, 7, 4, 2, 2, 0},
- {1, 7, 0, 0, 0, 0, 9, 0},
- {0, 1, 4, 0, 0, 3, 0, 9},
- {0, 2, 0, 0, 3, 0, 4, 6},
- {0, 0, 2, 9, 0, 4, 0, 2},
- {0, 0, 0, 0, 9, 6, 2, 0}
- };
- */
- /*
- int prev[8];
- int shortestPath = dijkstra(8, adjMatrix, 0, 7, prev);
- printf("the sum of shortest weight is %d\n", shortestPath);
- */
- printShortestPath(8, adjMatrix, 0, 7, vertexStr);
- return 0;
- }
- /******************************************************
- *Fuction:
- * 求圖最短路徑長度,並存儲跡
- * Input:
- * n--頂點個數
- * adjMatrix[n][n]--圖的鄰接矩陣
- * startV--源點
- * endV--結束點
- * prev[i]記錄從源到頂點的最短路徑上i的前一個頂點
- *Out:
- * 輸出最短路徑長度
- * ******************************************************/
- int dijkstra(int n, int adjMatrix[][n], int startV, int endV, int prev[n])
- {
- int dist[n]; //dist[i]表示從源到頂點i的最短特殊路徑長度
- int mask[n]; //mask[i]標記頂點i是否加入集合 -1表示已加入集合
- int shortestPath = 0;
- int minWeight = MAX_WEIGHT;
- int minID;
- int i;
- int j;
- int tmp = 0;
- for (i=0; i<n; i++)
- {
- mask[i] = 0; //初始化集合為空集,即沒有元素加入
- dist[i] = adjMatrix[startV][i]; //初始化dist[j]
- prev[i] = -1;
- prev[i] = (adjMatrix[startV][i] != MAX_WEIGHT) ? startV : -1;
- }
- //prev[0] = startV;
- // dist[startV] = -1; //起點標記為-1 不被更新
- mask[startV] = -1; //標記源點已加入
- for (i=1; i<n; i++) //最多再加入n-1個頂點
- {
- minWeight = MAX_WEIGHT;
- //尋找下一個待加入的頂點
- for (j=0; j<n; j++)
- {
- if (mask[j]!=-1 && dist[j]<minWeight)
- {
- minWeight = dist[j];
- minID = j;
- }
- }
-
- mask[minID] = -1; //加入頂點
- if (minID == endV) //最後一個節點已加入
- {
- return dist[endV];
- }
- //更新dist[i]
- for (j=0; j<n; j++)
- {
- if (minWeight==MAX_WEIGHT || adjMatrix[minID][j]==MAX_WEIGHT)
- continue;
- tmp = minWeight + adjMatrix[minID][j];
- if(j!=startV && tmp<dist[j]) //起點無須更新
- {
- dist[j] = tmp;
- prev[j] = minID;
- }
- }
- }
-
- }
- //print path
- void printShortestPath(int n, int adjMatrix[][n], int startV, int endV, const char **vertexStr)
- {
- int prev[n];
- int shortestPath = dijkstra(n, adjMatrix, startV, endV, prev);
- printf("the shortest path is: %d= ", shortestPath);
- int tmp = endV;
- do
- {
- printf("%s <--- ", vertexStr[tmp]);
- tmp = prev[tmp];
- }while(tmp != startV);
- printf("%s\n", vertexStr[startV]);
- }
三、測試結果
the shortest path is: 11= b <--- v6 <--- v2 <--- v4 <--- v1 <--- a