数据结构:点之间的最短距离--Floyd算法
? ? ? ? ? ? ? ? ? ? ? ? ? ?Floyd算法
Floyd算法
? ? Dijkstra算法是用于解決單源最短路徑問題的,Floyd算法則是解決點對之間最短路徑問題的。Floyd算法的設計策略是動態規劃,而Dijkstra採取的是貪心策略。當然,貪心算法就是動態規劃的特例。
算法思想
? ? 點對之間的最短路徑僅僅會有兩種情況:
故當Vv取全然部頂點后,Distance(Vi,Vj)就可以達到最小。Floyd算法的起點就是圖的鄰接矩陣。
題外話:代碼本身不重要。算法思想才是精髓。
思想極難得到,而有了思想,稍加經驗就可以寫出代碼。向思想的開創者致敬。
思想非常難。代碼卻比較簡單。直接上代碼
代碼
類定義 #include<iostream> #include<iomanip> #include<stack> using namespace std; #define MAXWEIGHT 100 #undef INFINITY #define INFINITY 1000 class Graph { private://頂點數 int numV;//邊數 int numE;//鄰接矩陣 int **matrix; public:Graph(int numV);//建圖 void createGraph(int numE);//析構方法 ~Graph();//Floyd算法void Floyd();//打印鄰接矩陣 void printAdjacentMatrix();//檢查輸入 bool check(int, int, int); };類實現 //構造函數,指定頂點數目 Graph::Graph(int numV) {//對輸入的頂點數進行檢測while (numV <= 0){cout << "頂點數有誤!又一次輸入 "; cin >> numV; } this->numV = numV; //構建鄰接矩陣。并初始化 matrix = new int*[numV]; int i, j; for (i = 0; i < numV; i++) matrix[i] = new int[numV]; for (i = 0; i < numV; i++) for (j = 0; j < numV; j++) { if (i == j) matrix[i][i] = 0; else matrix[i][j] = INFINITY; } } void Graph::createGraph(int numE) { /* 對輸入的邊數做檢測 一個numV個頂點的有向圖,最多有numV*(numV - 1)條邊 */ while (numE < 0 || numE > numV*(numV - 1)) { cout << "邊數有問題!又一次輸入 "; cin >> numE; } this->numE = numE; int tail, head, weight, i; i = 0; cout << "輸入每條邊的起點(弧尾)、終點(弧頭)和權值" << endl; while (i < numE) { cin >> tail >> head >> weight; while (!check(tail, head, weight)) { cout << "輸入的邊不對!請又一次輸入 " << endl; cin >> tail >> head >> weight; } matrix[tail][head] = weight; i++; } } Graph::~Graph() { int i; for (i = 0; i < numV; i++) delete[] matrix[i]; delete[]matrix; } /* 弗洛伊德算法 求各頂點對之間的最短距離 及其路徑 */ void Graph::Floyd() { //為了不改動鄰接矩陣,多用一個二維數組 int **Distance = new int*[numV]; int i, j; for (i = 0; i < numV; i++) Distance[i] = new int[numV]; //初始化 for (i = 0; i < numV; i++) for (j = 0; j < numV; j++) Distance[i][j] = matrix[i][j]; //prev數組 int **prev = new int*[numV]; for (i = 0; i < numV; i++) prev[i] = new int[numV]; //初始化prev for (i = 0; i < numV; i++) for (j = 0; j < numV; j++) { if (matrix[i][j] == INFINITY) prev[i][j] = -1; else prev[i][j] = i; } int d, v; for (v = 0; v < numV; v++) for (i = 0; i < numV; i++) for (j = 0; j < numV; j++) { d = Distance[i][v] + Distance[v][j]; if (d < Distance[i][j]) { Distance[i][j] = d; prev[i][j] = v; } } //打印Distance和prev數組 cout << "Distance..." << endl; for (i = 0; i < numV; i++) { for (j = 0; j < numV; j++) cout << setw(3) << Distance[i][j]; cout << endl; } cout << endl << "prev..." << endl; for (i = 0; i < numV; i++) { for (j = 0; j < numV; j++) cout << setw(3) << prev[i][j]; cout << endl; } cout << endl; //打印頂點對最短路徑 stack<int> s; for (i = 0; i < numV; i++) { for (j = 0; j < numV; j++) { if (Distance[i][j] == 0); else if (Distance[i][j] == INFINITY) cout << "頂點 " << i << " 到頂點 " << j << " 無路徑!
" << endl; else { s.push(j); v = j; do{ v = prev[i][v]; s.push(v); } while (v != i); //打印路徑 cout << "頂點 " << i << " 到頂點 " << j << " 的最短路徑長度是 " << Distance[i][j] << " ,其路徑序列是..."; while (!s.empty()) { cout << setw(3) << s.top(); s.pop(); } cout << endl; } } cout << endl; } //釋放空間 for (i = 0; i < numV; i++) { delete[] Distance[i]; delete[] prev[i]; } delete[]Distance; delete[]prev; } //打印鄰接矩陣 void Graph::printAdjacentMatrix() { int i, j; cout.setf(ios::left); cout << setw(7) << " "; for (i = 0; i < numV; i++) cout << setw(7) << i; cout << endl; for (i = 0; i < numV; i++) { cout << setw(7) << i; for (j = 0; j < numV; j++) cout << setw(7) << matrix[i][j]; cout << endl; } } bool Graph::check(int tail, int head, int weight) { if (tail < 0 || tail >= numV || head < 0 || head >= numV || weight <= 0 || weight >= MAXWEIGHT) return false; return true; }
主函數 int main() {cout << "******Floyd***by David***" << endl;int numV, numE;cout << "建圖..." << endl;cout << "輸入頂點數 ";cin >> numV;Graph graph(numV);cout << "輸入邊數 ";cin >> numE;graph.createGraph(numE);cout << endl << "Floyd..." << endl;graph.Floyd();system("pause");return 0; }執行小結
Floyd算法代碼看似非常長,事實上并不難。代碼中非常多都是用于準備工作和輸出。關鍵代碼就是三層for循環。完整代碼下載:Floyd算法
轉載請注明出處,本文地址:http://blog.csdn.net/zhangxiangdavaid/article/details/38366923
若有所幫助,頂一個哦。
專欄文件夾:
- 數據結構與算法文件夾
- c指針
版權聲明:本文博主原創文章。轉載,轉載請注明出處。
轉載于:https://www.cnblogs.com/gcczhongduan/p/4850988.html
總結
以上是生活随笔為你收集整理的数据结构:点之间的最短距离--Floyd算法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: excel下载模版(数据字典)
- 下一篇: 目录-管壳式换热器的分析与计算