数据结构之Dijkstra算法
基本思想
通過Dijkstra計算圖G中的最短路徑時,需要指定起點s(即從頂點s開始計算)。
此外,引進兩個集合S和U。S的作用是記錄已求出最短路徑的頂點(以及相應的最短路徑長度),而U則是記錄還未求出最短路徑的頂點(以及該頂點到起點s的距離)。
初始時,S中只有起點s;U中是除s之外的頂點,并且U中頂點的路徑是”起點s到該頂點的路徑”。然后,從U中找出路徑最短的頂點,并將其加入到S中;接著,更新U中的頂點和頂點對應的路徑。 然后,再從U中找出路徑最短的頂點,并將其加入到S中;接著,更新U中的頂點和頂點對應的路徑。 … 重復該操作,直到遍歷完所有頂點
操作步驟
(1) 初始時,S只包含起點s;U包含除s外的其他頂點,且U中頂點的距離為”起點s到該頂點的距離”[例如,U中頂點v的距離為(s,v)的長度,然后s和v不相鄰,則v的距離為∞]。
(2) 從U中選出”距離最短的頂點k”,并將頂點k加入到S中;同時,從U中移除頂點k。
(3) 更新U中各個頂點到起點s的距離。之所以更新U中頂點的距離,是由于上一步中確定了k是求出最短路徑的頂點,從而可以利用k來更新其它頂點的距離;例如,(s,v)的距離可能大于(s,k)+(k,v)的距離。
(4) 重復步驟(2)和(3),直到遍歷完所有頂點。
實現
// 鄰接矩陣 typedef struct _graph {char vexs[MAX]; // 頂點集合int vexnum; // 頂點數int edgnum; // 邊數int matrix[MAX][MAX]; // 鄰接矩陣 }Graph, *PGraph;// 邊的結構體 typedef struct _EdgeData {char start; // 邊的起點char end; // 邊的終點int weight; // 邊的權重 }EData;Graph是鄰接矩陣對應的結構體。
vexs用于保存頂點,vexnum是頂點數,edgnum是邊數;matrix則是用于保存矩陣信息的二維數組。例如,matrix[i][j]=1,則表示”頂點i(即vexs[i])”和”頂點j(即vexs[j])”是鄰接點;matrix[i][j]=0,則表示它們不是鄰接點。
EData是鄰接矩陣邊對應的結構體。
迪杰斯特拉算法
/** Dijkstra最短路徑。* 即,統計圖(G)中"頂點vs"到其它各個頂點的最短路徑。** 參數說明:* G -- 圖* vs -- 起始頂點(start vertex)。即計算"頂點vs"到其它頂點的最短路徑。* prev -- 前驅頂點數組。即,prev[i]的值是"頂點vs"到"頂點i"的最短路徑所經歷的全部頂點中,位于"頂點i"之前的那個頂點。* dist -- 長度數組。即,dist[i]是"頂點vs"到"頂點i"的最短路徑的長度。*/ void dijkstra(Graph G, int vs, int prev[], int dist[]) {int i,j,k;int min;int tmp;int flag[MAX]; // flag[i]=1表示"頂點vs"到"頂點i"的最短路徑已成功獲取。// 初始化for (i = 0; i < G.vexnum; i++){flag[i] = 0; // 頂點i的最短路徑還沒獲取到。prev[i] = 0; // 頂點i的前驅頂點為0。dist[i] = G.matrix[vs][i];// 頂點i的最短路徑為"頂點vs"到"頂點i"的權。}// 對"頂點vs"自身進行初始化flag[vs] = 1;dist[vs] = 0;// 遍歷G.vexnum-1次;每次找出一個頂點的最短路徑。for (i = 1; i < G.vexnum; i++){// 尋找當前最小的路徑;// 即,在未獲取最短路徑的頂點中,找到離vs最近的頂點(k)。min = INF;for (j = 0; j < G.vexnum; j++){if (flag[j]==0 && dist[j]<min){min = dist[j];k = j;}}// 標記"頂點k"為已經獲取到最短路徑flag[k] = 1;// 修正當前最短路徑和前驅頂點// 即,當已經"頂點k的最短路徑"之后,更新"未獲取最短路徑的頂點的最短路徑和前驅頂點"。for (j = 0; j < G.vexnum; j++){tmp = (G.matrix[k][j]==INF ? INF : (min + G.matrix[k][j])); // 防止溢出if (flag[j] == 0 && (tmp < dist[j]) ){dist[j] = tmp;prev[j] = k;}}}// 打印dijkstra最短路徑的結果printf("dijkstra(%c): \n", G.vexs[vs]);for (i = 0; i < G.vexnum; i++)printf(" shortest(%c, %c)=%d\n", G.vexs[vs], G.vexs[i], dist[i]); }references
Dijkstra算法(一)之 C語言詳解 - 如果天空不死 - 博客園
總結
以上是生活随笔為你收集整理的数据结构之Dijkstra算法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: epoll精讲
- 下一篇: tensorflow中batch nor