用STL存储邻接链表

图的存储最常见的方式是邻接链表和邻接矩阵存储. 邻接矩阵和邻接链表具体是什么这里就不多说了. 由于项目需要, 我需要实现一个能够自动查重的邻接链表, 即不能插入重复结点的邻接链表. 考虑到”不能重复”这一特点, 如果使用stl容器的话, 非map/set/hashmap/hashset莫属. 多的不说, 上代码:

一. 顶点类的定义

enum State
{
    WHITE, GRAY, BLACK
};
extern struct Edge;
typedef set<Edge> AdjVerticeSet;
struct Vertice
{
    AdjVerticeSet adjacentVertices;
    int id;
    State color;
    unsigned int begin; // dfs或bfs发现节点的时间
    unsigned int end;   // dfs完成访问的时间
    int distance;       // 记录最短路径
    Vertice(int _id = 0) :id(_id), color(WHITE), begin(0), end(0), adjacentVertices(AdjVerticeSet()),distance(1){}
    void addEdge(Vertice* target);
};
typedef pair<int, Vertice*> Node;
typedef map<int, Vertice*> VerticeSet;

对顶点添加边

void Vertice::addEdge(Vertice* target)
{
    Edge e = Edge(target);
    adjacentVertices.insert(e);
}

二. 边节点的定义

extern struct Vertice;
struct Edge {
    int weight;
    Vertice* target;
    Edge(Vertice* _target, int _weight = 1) :target(_target), weight(_weight){}
    bool operator<(const Edge& another) const
    {
        return target - another.target < 0;
    }
    bool operator==(const Edge& another) const
    {
        return target - another.target == 0;
    }
    bool operator>(const Edge& another) const
    {
        return target - another.target > 0;
    }
};

三. 邻接链表的封装类

class Graph
{
private:
    // 出度邻接链表
    VerticeSet allVertices;

#pragma region 内存管理
public:
    Graph()
    {
        allVertices = VerticeSet();
    }
    ~Graph(){
        for (auto n : allVertices)
        {
            delete n.second;
        }
    }
#pragma endregion 内存管理
private:
    void dfs_visit(Vertice* n, int& timestamp);
public:
    void dfs();
    void appendEdge(int id_a, int id_b, int weight=1);
    void appendUndirectedEdge(int id_a, int id_b, int weight = 1)
    {
        appendEdge(id_a, id_b, weight);
        appendEdge(id_b, id_a, weight);
    }
    void display();
    bool bellmanFord(int source_id);
    Vertice* operator[](int id)
    {
        if (allVertices.count(id)>0)
            return allVertices.find(id)->second;
        else return NULL;
    }
    
    void dijkstra(int source_id);
};

typedef map<Vertice*, int> ResultList;
typedef pair<Vertice*, int> ResultPair;

向邻接链表添加边:

void Graph::appendEdge(int id_a, int id_b, int weight)
{
    if (allVertices.count(id_a) == 0)
        allVertices.insert(Node(id_a, new Vertice(id_a)));
    if (allVertices.count(id_b) == 0)
        allVertices.insert(Node(id_b, new Vertice(id_b)));
    Vertice* va = allVertices.find(id_a)->second;
    Vertice* vb = allVertices.find(id_b)->second;
    va->adjacentVertices.insert(Edge(vb,weight));
}
posted @ 2015-01-14 18:10  Roy_Mustango  阅读(340)  评论(0编辑  收藏  举报