C++ 实现无向图的最小生成树Kruskal算法(完整代码)
生活随笔
收集整理的這篇文章主要介紹了
C++ 实现无向图的最小生成树Kruskal算法(完整代码)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
按照Kruskal思想,n個結點的生成樹有n-1條邊,故反復上述過程,直到選取了n-1條邊為止,就構成了一棵最小生成樹。
實現Kruskal算法的關鍵問題是:
當一條邊加入T的邊集中后,如何判斷是否構成回路。
一種解決方法是定義一個一維數組f[n],存放T中每一個頂點所處連通分量的編號。
開始令f[i]=i,即圖中每個頂點自成一個連通分量。
如果要往T的邊集中增加一條邊(vi, vj),首先檢查f[i]和f[j]是否相同,若相同,則表明vi和vj處在同一連通分量中,加入此邊必然形成回路;
若不相同,則不會形成回路,此時可以把此邊加入生成樹的邊集中。
當加入一條新邊后,必然將兩個不同的連通分量連通,此時就需將兩個連通分量合并,合并方法是將一個連通分量的編號換成另一個連通分量的編號。
下面以圖的邊表結構(用一個結構體存儲圖的頂點數、邊數、頂點信息、邊的信息)來存儲一個帶權的連通圖,實現Kruskal算法如下:
#include <iostream> #include <algorithm> using namespace std; const int MaxcertexNum = 30; const int MaxEdge = 100; typedef int VertexType;class ENode {friend bool cmp(ENode a, ENode b);friend class ELGraph; private:int vertex1;int vertex2;int weight; };class ELGraph { public:ELGraph() {};void CreateGraph();void Kruskal(ENode TE[]); private:void Sort(ENode *a);int vertexnum;int edgenum;VertexType vertexs[MaxcertexNum];ENode edges[MaxcertexNum];int f[MaxcertexNum];int Find(int x){if (f[x] != x) return Find(f[x]);else return x;};void Union(int x, int y){f[Find(y)] = Find(x);} };bool cmp(ENode a, ENode b) {return a.weight < b.weight; }void ELGraph::Sort(ENode *a) {sort(a, a + edgenum, cmp); }void ELGraph::CreateGraph() {cout << "請輸入頂點數和邊數" << endl;cin >> vertexnum >> edgenum;cout << "請依次輸入按序號0到n頂點的信息" << endl;for (int i = 0; i < vertexnum; i++){cin >> vertexs[i];}cout << "下面輸入邊表信息" << endl;for (int i = 0; i < edgenum; i++){int v1, v2, w;cout << "輸入邊<i,j>對應的頂點序號i,j,再輸入該邊的權值" << endl;cin >> v1 >> v2 >> w;edges[i].vertex1 = v1;edges[i].vertex2 = v2;edges[i].weight = w;} }void ELGraph::Kruskal(ENode TE[]) {for (int i = 0; i < vertexnum; i++) f[i] = i;Sort(edges);int k = 0;int j = 0;while (k < vertexnum - 1){int s1 = edges[j].vertex1;int s2 = edges[j].vertex2;if (Find(s1)!=Find(s2)){TE[k].vertex1 = s1;TE[k].vertex2 = s2;TE[k].weight = edges[k].weight;k++;Union(s1, s2);}j++;}for (int i = 0; i < vertexnum - 1; i++){cout << TE[i].vertex1 << "->" << TE[i].vertex2 << " " << TE[i].weight << endl;} }int main() {ELGraph g;g.CreateGraph();ENode TE[50];g.Kruskal(TE);return 0; }測試結果:
總結
以上是生活随笔為你收集整理的C++ 实现无向图的最小生成树Kruskal算法(完整代码)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python 取模是什么意思_编程语言中
- 下一篇: C++ 实现带权有向图的单源点最短路径D