图的最小生成树算法:Kruskal算法与Prim算法

图的最小生成树算法

Kruskal算法
Prim算法

Kruskal算法

struct Node {
public:
    int val;
    Node * father;
    Node(int _val) {
        val = _val;
        father = this;
    }
};

struct Edge
{
    Node * snode;
    Node * enode;
    int weight;
    Edge(Node * s, Node *e,int w)
    {
        snode = s;
        enode = e;
        weight = w;
    }
    bool operator==(const Edge & rhs)
    {
        return this->enode == rhs.enode &&this->snode == rhs.snode;
    }
    bool operator > (const Edge & rhs) const
    {
        return this->weight>rhs.weight;
    }
};

struct Edge_Hash
{
    size_t operator()(const Edge & rhs)
    {
        return std::hash<Node *>()(rhs.snode) ^ std::hash<Node *>()(rhs.enode);
    }
};

Node * union_find(Node * node)
{
    while (node->father!=node)
    {
        node = node->father;
    }
    return node;
}
void union_join(Node * the_one, Node * the_one_int_group)
{
    auto big_father=union_find(the_one_int_group);
    auto small_father = union_find(the_one);
    small_father->father = big_father;
}

vector<Edge> MinTree_Kruskal(const set<Node *> & nodes, 
    const std::priority_queue<Edge, vector<Edge>, std::greater<Edge>> &src_edges)
{
    auto edges = src_edges;
    vector<Edge> ret;
    int node_size = nodes.size();
    while (!edges.empty())
    {
        auto tmp_edge=edges.top();
        edges.pop();
        if (union_find(tmp_edge.snode) != union_find(tmp_edge.enode))
        {
            ret.push_back(tmp_edge);
            union_join(tmp_edge.snode, tmp_edge.enode);
            if (ret.size() == node_size - 1)
            {
                break;
            }
        }
        else
        {
            cout << "union_find same"<<endl;
        }
    }
    int sum = 0;
    std::for_each(ret.begin(), ret.end(), [&sum](const Edge & e){
        sum += e.weight;
        cout << "[" << e.snode->val << "," << e.enode->val << "] : " << e.weight << endl;
    });
    cout <<"--------------------"<<sum<< endl;
    return ret;
}

Prim算法

#define  INF 9999999
class Node {
public:
    int val;
    vector> neighbors;
    Node(int _val) {
        val = _val;
        neighbors.clear();
    }
};

vector> MinTree_Prim(Node * start,const set & nodes,const multimap> &edges)
{
    vector> tree_edges;
    auto node_src = nodes;//可选点的保存集合
    set node_tree;//生成树的保存集合
    node_tree.insert(start);
    node_src.erase(start);

    //从可选点集中,选出一点A;
    //从生成树点集中,选出另一点B,两者构成一条边;
    //这些边中权重最小的边,其对应A点,即可加入生成树点集中。
    while (!node_src.empty())
    {
        int min_weight = INF;
        Node * end_node = NULL;
        Node * start_node=NULL;
        for (auto item : node_src)
        {
            auto range = edges.equal_range(item);
            for (auto it = range.first; it != range.second; ++it)
            {
                if (it->second.second < min_weight&& 
                    node_tree.find(it->second.first) != node_tree.end())
                {
                    min_weight = it->second.second;
                    end_node = it->first;
                    start_node = it->second.first;
                }
            }
        }
        node_tree.insert(end_node);
        node_src.erase(end_node);
        tree_edges.emplace_back(start_node,end_node);
    }
    cout << "---------------" << endl;
    std::for_each(tree_edges.begin(), tree_edges.end(),
        [](std::pair edge){cout <<"["<< edge.first->val << "," << edge.second->val<<"]"; });
    cout << endl;
    return tree_edges;
}

你可能感兴趣的:(算法和数据结构知识积累)