0
点赞
收藏
分享

微信扫一扫

搜索与图论-------DFS与BFS与拓扑排序

爱薇Ivy趣闻 2022-02-06 阅读 73

一.深度优先搜索(基于栈)

适用:

既可以在无向图中也可以在有向图

思路:

从根节点出发,每次遍历他的第一个孩子节点直到遍历到叶子节点,再退回到他的父亲节点,接着遍历父亲节点的其他孩子节点,如此重复,直到遍历完所有的节点。

核心代码:

int dfs(int u)

{

    st[u] = true; // st[u] 表示点u已经被遍历过

    for (int i = h[u]; i != -1; i = ne[i])

    {

        int j = e[i];

        if (!st[j]) 

        dfs(j);

    }

}

二.宽度优先遍历(基于队列)

适用:

既可以在无向图中也可以在有向图

思路:

从根节点开始,按由近及远的顺序一层一层的遍历,直到遍历完所有节点。

核心代码:

queue<int> q;
st[1] = true; // 表示1号点已经被遍历过
q.push(1);

while (q.size())
{
    int t = q.front();
    q.pop();

    for (int i = h[t]; i != -1; i = ne[i])
    {
        int j = e[i];
        if (!st[j])
        {
            st[j] = true; // 表示点j已经被遍历过
            q.push(j);
        }
    }
}

三.拓扑排序

特点:1.有向无环图

            2.序列里的每一个点只能出现一次。

             3.任何一对u和v,u总再v之前(u为起点,v为终点)

思路:

1.找一个入度为0的点

2.将该点的编号输出

3.将该点删除,同时将所有由该点出发的有向边删除

4.循环进行,直到图中所有点的入读为0;

核心代码:

bool topsort()
{
    int hh = 0, tt = -1;

    // d[i] 存储点i的入度
    for (int i = 1; i <= n; i ++ )
        if (!d[i])
            q[ ++ tt] = i;

    while (hh <= tt)
    {
        int t = q[hh ++ ];

        for (int i = h[t]; i != -1; i = ne[i])
        {
            int j = e[i];
            if (-- d[j] == 0)
                q[ ++ tt] = j;
        }
    }

    // 如果所有点都入队了,说明存在拓扑序列;否则不存在拓扑序列。
    return tt == n - 1;
}
举报

相关推荐

0 条评论