• 图的表示、广度优先搜索、深度优先搜索


    1.图的表示

    a.邻接矩阵:适合稠密图(|E|接近|V|2)

    //用二维数组表示邻接矩阵
    int G[|V|][|V|];
    //初始化
    for(int i=0;i<|V|;i++){
        for(int j=0;j<|V|;j++){
            if( (i,j) in E){
                G[i][j] = 1;//or G[i][j] = weight[i][j];
            }
            else if(i==j){
                G[i][j] = 0;
            }
            else{
                G[i][j] = MAX;
            }
        }
    }

    b.邻接表:适合稀疏图(|E|远小于|V|2)

    //邻接表的表示
    class Node{
    public:
        int index;//顶点索引
        Node* next=nullptr;//下一顶点
        Node(int i):index(i){}
    };
    class VNode{
    public:
        char vertex;//顶点
        int index;//顶点索引
        int dist;//BFS:表示顶点到源点的距离,DFS:表示顶点第一次被发现的时间
        int finish;//BFS:无意义,DFS:表示顶点的邻接表扫描完成时的时间
        Color color;//顶点颜色
        int prev;//顶点的前驱
        Node* firstNode=nullptr;//第一条边的尾节点
        VNode(char c,int i):vertex(c),index(i){}
    };
    class Graph{
        vector<VNode> Adj;//所有顶点
    };
    //初始化
    void AddEdge(Graph &G,int i,int j,int weight,int w[][|V|]){
        Node* p = new Node(j);
        p->next = G.Adj[i].firstNode;
        G.Adj[i].firstNode = p;
        w[i][j]=weight;
            //有向图只需上面部分代码即可
        Node* p2 = new Node(i);
        p2->next = G.Adj[j].firstNode;
        G.Adj[j].firstNode = p2;
        w[j][i] = weight;
    }
    //初始化顶点
    for(int i=0;i<|V|;i++){
        G.Adj.push_back(VNode(V[i], i));
    }
    //初始化边、权重
    int w[6][6];
    for (int i = 0; i < 6; ++i){
        for (int j = 0; j < 6; ++j){
            if(i == j){
                w[i][j] = 0;
            }
            else{
                w[i][j] = MAX;
            }    
        }
    }
    for (i,j) in E:
        AddEdge(G,i,j,weight[i][j],w);

      

    2.广度优先搜索BFS

    思路:从某个源点开始遍历图,先将源点颜色置为灰色,然后将其加入队列Q,对Q中的元素进行如下循环操作:

    1.从队列Q中弹出一个元素u
    2.访问与u相邻的每个顶点v,若v的颜色为白色(未被发现)
        则将v的颜色置为灰色
        v与源点的距离更新为u到源点距离加1
        v的前驱更新为u
        将v压入队列Q
    3.u的邻接表扫描完成,将u的颜色置为黑色

    直至Q为空.

    伪代码:

    BFS(G,s)
        for each vertex u in G.V
            u.color = white
            u.d = MAX
            u.p = NIL
        s.color = gray
        s.d = 0
        s.p = NIL
        Q = ∅
        ENQUEUE(Q,s)
        while Q ≠ ∅
            u = DEQUEUE(Q)
            for each v in G.Adj[u]
                if v.color == white
                    v.color = gray
                    v.d = u.d+1
                    v.p = u
                    ENQUEUE(Q,v)
            u.color = black

    时间复杂度:O(V+E)

    打印源节点s到结点v的一条路径上的所有节点

    PrintPath(G,s,v)
        if v==s
            print s
        else if v.p == NIL
            print "No such path"
        else
            PrintPath(G,s,v.p)
            print v

    对于每个从源结点s可以到达的结点v,广度优先搜索里从结点s到结点v的简单路径就是图G中从结点s到结点v的"最短路径",即包含最少边数的路径.

    3.深有优先搜索DFS

    思路:对每一个顶点u,若u的颜色为白色,则对u进行深度优先访问(DFS-VISIT)

    1.全局时间戳time加1,u被发现的时间更新为time,u的颜色更新为灰色
    2.访问与u相邻的每个顶点v,若v的颜色为白色(未被发现)
        v的前驱更新为u
        对v进行深度优先访问
    3.u的邻接表扫描完成,u的颜色置位黑色,time加1,u的邻接表扫描完成时间更新为time

    一次深度优先访问可能无法访问到所有顶点,这正是要对每个顶点进行深度优先访问的原因.

    伪代码:

    DFS(G)
        for each vertex u in G.V
            u.color = white
            u.p = NIL
        time  = 0
        for each vertex u in G.V
            if u.color == white
                DFS-VISIT(G,u)
    DFS-VISIT(G,u)
        time = time +1//u has just been discovered
        u.d = time
        u.color = gray
        for each v in G.Adj[u]//explore edge(u,v)
            if v.color == white
                v.p = u
                DFS-VISIT(G,v)
        u.color = black//blacken u,it is finished
        time = time +1
        u.f = time

    时间复杂度:O(V+E)

    BFS和DFS的区别:

    BFS的前驱子图是一棵树,DFS的前驱子图是有多颗树组成的深林.

    结点颜色的含义:

    初始时未被发现是白色,被发现后为灰色,其邻接表被扫描完成后为黑色.

    遍历路径:

    若要得到图的遍历顺序,可在结点被访问后保存到一个向量.

  • 相关阅读:
    inet_ntoa 的一个小问题
    获取DNS服务器的版本信息
    host_network_interfaces_slow_mode_thresholds
    10月8日至11月底考试安排
    腾讯广点通防作弊
    移动广告作弊方式及防范方式
    广告联盟常用的防作弊手续
    移动端点击作弊与激活作弊的现象与预警
    数据科学家最常用的十种算法(我准备拿这个当成学习参考)
    项目的命名规范,为以后的程序开发中养成良好的行为习惯
  • 原文地址:https://www.cnblogs.com/bukekangli/p/4394504.html
Copyright © 2020-2023  润新知