Kruskal algorithm

JUAN425發表於2014-08-09

為了執行Kruskal Algorithm的一個採用C++11的演算法。 我下載了code::blocks的的13.12 版本。 安裝在電腦上。 code:::blocks 有一個好處是, 在你安裝的時候, 注意不要解除安裝之前安裝的code::blocks (之前我的是10.05版本), 那麼根據安裝提示, 新的code::blocks IDE 會保留(沿襲)下你已經安裝的code::blocks的所有設定。 這其中包括之前對Compiler 連結庫的設定(例如我對opencv的庫的設定)等等。 甚至是你之前執行的程式也會出現在start page 中。 也就是說所有的這些都會保留, 你不需要擔心要重新設定了。

如下Graph:


Kruskal 演算法如下:

#include <iostream>
#include <vector>
#include <unordered_map>
#include <algorithm>

using namespace std;


struct Edge {
   char vertex1;
   char vertex2;
   int weight; // edges is modeled by 2 vertices and a weight
   Edge(char v1, char v2, int w): vertex1(v1), vertex2(v2), weight(w) {}
};

struct Graph {
   vector<char> vertices; // a vector of vertices
   vector<Edge> edges; // a vector of edges
};


unordered_map<char, char> PARENT;//to record the parental relationship between vertices
unordered_map<char, int> RANK; //RANK is used to record the depth of the tree.
                               // THe purpose of the RANK is used to flatten the treee so that we have
                               // the better performance of the find function.


char Find(char vertex) {
   if (PARENT[vertex] == vertex)
      return PARENT[vertex];
   else
      return Find(PARENT[vertex]);
}

void Union(char root1, char root2) {
   if (RANK[root1] > RANK[root2]) {
      PARENT[root2] = root1;
   }
   else if (RANK[root1] < RANK[root2]) {
      PARENT[root1] = root2;
   }
   else {
      PARENT[root1] = root2;
      RANK[root2]++;
   }

}

void MakeSet(char vertex) {
   PARENT[vertex] = vertex;
   RANK[vertex] = 0;
}


void Kruskal(Graph& g) {
   vector<Edge> A;
   for(auto c: g.vertices) {
      MakeSet(c);
   }

   sort(g.edges.begin(), g.edges.end(), [](Edge x, Edge y) { return x.weight < y.weight;});
   //O(E*log(E))
   for (Edge e: g.edges) {
      char root1 = Find(e.vertex1);
      char root2 = Find(e.vertex2);
      if(root1 != root2) {
         A.push_back(e);
         Union(root1, root2);
      }
   }

   // print out the minimum spanning tree
   for(Edge e: A) {
      cout << e.vertex1 << "--" << e.vertex2 << " " << e.weight << endl;
   }
}

int main() {
   char t[] = {'a', 'b', 'c', 'd', 'e', 'f'};
   Graph g; // created a graph
   g.vertices = vector<char>(t, t + sizeof(t)/sizeof(t[0]));

   g.edges.push_back(Edge('a', 'b', 4));
   g.edges.push_back(Edge('a', 'f', 2));
   g.edges.push_back(Edge('f', 'b', 5));
   g.edges.push_back(Edge('c', 'b', 6));
   g.edges.push_back(Edge('c', 'f', 1));
   g.edges.push_back(Edge('f', 'e', 4));
   g.edges.push_back(Edge('d', 'e', 2));
   g.edges.push_back(Edge('d', 'c', 3));


   // call the function Kruskal to find MST of graph g

   Kruskal(g);

   return 0;

}

執行:






即下圖:


相關文章