【算法第四版 读书笔记】图——无向图

//图的抽象数据类型
class Graph 
{
public:
    Graph(int v);                   //创建一个含有V个顶点不含边的图
    int V()const;                   //顶点数
    int E()const;                   //边数
    void addEdge(int v, int w);     //添加一条边v-w
    vector<int> adj(int v)const;    //和v相邻的所有顶点
    string toString()const;         //对象的字符串表示
}


//常用图处理代码:

int degree(Graph G. int v)
{ //计算顶点v的度数
    int cnt = 0;
    for (int w : G.adj(v))  ++cnt;
    return cnt;
}

int maxDegree(Graph G)
{ //计算所有顶点的最大度数  
    int maxCnt = 0;
    for (int i = 0; i < G.V(); ++i)
        if (degree(G, i) > maxCnt) maxCnt = degree(G, i); 
    return maxDegree;
}

int aveDegree(Graph G)
{ //计算所有顶点的平均度数
    return G.E() * 2 / G.V();
}

int numberOfSelfLoops(Graph G)
{ //计算自环个数
    int cnt = 0;
    for (int v = 0; v < G.V(); ++i)
        for (int w : G.adj(v))
            if (w == v)  ++cnt;
    return cnt;
}

string toString (Graph G)
{ //Graph实例方法
    string s = G.V() + " vertices, " + G.E() + " edges\n";
    for (int v = 0; v < G.V(); ++v)
    {
        s += v + ": ";
        for (int w : G.adj(v))
            s += w + " ";
        s += "\n";
    }
    return s;
}


//图的邻接矩阵和邻接表实现见 基本数据结构实现 专栏 【数据结构】图


//图的搜索算法API
class Search : public Graph 
{
    Search(Graph G, int s);     //找到与s连通的所有顶点
    bool marked(int v);         //s和v是否连通
    int count();                //与s连通顶点数
}


//深度优先搜索
void dfs(Graph G, int v)
{
    marked[v] = true;
    ++count;
    for (int w : G.adj(v)) 
    {  
        if (!marked[w])  dfs(G, w);
    }
}


//广度优先搜索
void bfs(Graph G, int v)
{
    queue<int>que;
    que.push(v);
    while(!que.empty())
    {
        int t = que.pop();
        marked[t] = true;
        ++count;
        for (int w : G.adj(t))
        {
         	if (!marked[w])   que.push(w);
        }
    }
}


//寻找路径
class DFPaths
{
private:
    bool* marked;
    int* edgeTo;
    int s;      //起点
    void dfs(Graph G, int v)
    {  
        marked[v] = true;
        for (int w : G.adj(v))
        {
            if (!marked[w])
            {
                edge[w] = v;
                dfs(G, w);
            }
        }
    }

public:
    DFPaths(Graph G, int s)
    {
        marked = new bool[G.V()];
        edgeTo = new int[G.V()];
        this.s = s;
        dfs(G, s);
    }
    bool hasPathTo(int v)const { return marked[v]; }
    vector<int> pathTo(int v)
    {
        vector<int>path;
        if (!marked[v]) return path;
        for (int x = v; x != s; x = edgeTo[x])
        {
            path.push_back(x);
        }
        path.push_back(s);
        return path;
    }
}

//连通分量
class CC
{
private:
    bool* marked;
    int* id;
    int count;
    void dfs(Graph G, int v)
    {
        marked[v] = true;
        id[v] = count;
        for (int w : G.adj(v)) 
        {  
            if (!marked[w])  dfs(G, w);
        }
    }

public:
    CC() 
    {
        for (int i = 0; i < G.V(); ++i)
        {
            if (!marked[i])
            {
                dfs(G, i);
                ++count;
            }
        }
    }
    bool connected(int v, int w)const {  return id[v] == id[w]; }
    int id(int v)const {  return id[v]; }
    int count()const { return count; }
}


//判断有无环
class Cycle
{
private:
    bool* marked;
    bool hasCycle;
    void dfs(Graph G, int v, int u)
    {
        marked[v] = true;
        for (int w : G.adj(v))
        {
            if (!marked[w])  dfs(G, w, v);
            else if (w != u) hasCycle = true;
        }
    }

public:
    Cycle(Graph G)
    {
        marked = new bool[G.V()];
        for (int s = 0; s < G.V(); ++s)
            if (!marked[s])  dfs(G, s, s);
    }

    bool hasCycle()const { return hasCycle; }
}


//判断是否为二分图
class TwoColor
{
private:
    bool* marked;
    bool* color;
    bool isTwoColorable;
    void dfs(Graph G, int v)
    {
        marked[v] = true;
        for (int w : G.adj(v))
        {
            if (!marked[v])
            {
                color[w] = !color[v];
                dfs(G, w);
            }
            else 
            {
                if (color[v] == color[w])
                    isTwoColorable = false;
            }
        }
    }

public:
    TwoColor(Graph G)
    {
        marked = new bool[G.V()];
        color = new bool[G.V()];
        for (int s = 0; s < G.V(); ++s)
        {
            if (!marked[s]) dfs(G, s);
        }
    }

    bool isBipartite()const { return isTwoColorable; }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值