图的深度优先搜索(DFS)与广度优先搜索(BFS)

一、深度优先搜索(DFS)

  深度优先搜索的思想:假设初始状态是图中所有顶点均未被访问,则从某个顶点V出发,首先访问该顶点,然后从它的某一个未被访问的邻接点出发深度优先搜索遍历图,直至图中所有和V有路径相通的顶点都被访问到。 若此时尚有其他顶点未被访问到,则另选一个未被访问的顶点作起始点,重复上述过程,直至图中所有顶点都被访问到为止。显然,深度优先搜索是一个递归的过程。

1、图解深度优先搜索

  深度优先搜索可以用递归实现也可以用栈来实现:
这里写图片描述
这里写图片描述

2、深度优先搜索的demo:

(1)递归实现:

bool visited1[100] = {false};

void dfs_digui(int current, int m, vector<vector<int>> data)
{
    visited1[current] = true;
    cout << current << " ";
    for (int i = 0; i < m; ++i)
        if (data[i][0] == current && visited1[data[i][1]] == false)
            dfs_digui(data[i][1], m, data);
}

(2)非递归实现(栈):

bool visited2[100] = {false};
//深度优先搜索(随机访问一个节点,随后访问与之相邻的所有节点中未被访问过的一个)
void dfs(int current, int m, vector<vector<int>> data)
{
    stack<int> st;
    cout << current << " ";
    visited2[current] = true;//以顶点1为起点
    st.push(current);//入栈
    while (!st.empty())
    {
        for (int j = 0; j < m; ++j)
        {
            //访问和当前顶点相邻的所有顶点并将它们入栈
            if (data[j][0] == current && visited2[data[j][1]] == false)
                st.push(data[j][1]);
        }
        if (visited2[st.top()] == 0)//判断栈顶元素所在顶点是否被访问过
        {
            current = st.top();//栈顶元素作为新的顶点
            visited2[current] = true;
            cout << st.top() << " ";
            st.pop();//弹出已访问的顶点
        }
        else//如果栈顶元素被访问过则弹栈
            st.pop();
    }
}

二、广度优先搜索(BFS)

  广度优先搜索的思想是:从图中某顶点V出发,在访问了V之后依次访问V的各个未曾访问过的邻接点,然后分别从这些邻接点出发依次访问它们的邻接点,并使得“先被访问的顶点的邻接点先于后被访问的顶点的邻接点被访问,直至图中所有已被访问的顶点的邻接点都被访问到。如果此时图中尚有顶点未被访问,则需要另选一个未曾被访问过的顶点作为新的起始点,重复上述过程,直至图中所有顶点都被访问到为止。

1、图解广度优先搜索
这里写图片描述
这里写图片描述

2、广度优先搜索的demo:

(1)使用队列实现:

bool visited3[100] = {false};
//广度优先搜索(随机访问一个节点,随后访问与之相邻的所有未被访问过的节点)
void bfs(int current, int m, vector<vector<int>> data)
{
    queue<int> qe;
    cout << current << " ";
    visited3[current] = true;//以顶点1为起点
    qe.push(current);//加入队列
    while (!qe.empty())
    {
        for (int j = 0; j < m; ++j)
        {
            //访问和当前顶点相邻的所有顶点并将它们入队列
            if (data[j][0] == current && visited3[data[j][1]] == false)
                qe.push(data[j][1]);
        }
        if (visited3[qe.front()] == 0)//判断队头元素所在顶点是否被访问过
        {
            current = qe.front();//队头元素作为新的顶点
            visited3[current] = true;
            cout << qe.front() << " ";
            qe.pop();//已访问的顶点出队
        }
        else//如果队头元素被访问过则出队
            qe.pop();
    }
}
//主函数
int main(int argc, char const *argv[])
{
    int m, n;
    cin >> m >> n;
    vector<vector<int>> data;
    for (int i = 0; i < m; ++i)
    {
        vector<int> vec;
        int x;
        for (int j = 0; j < n; ++j)
        {
            cin >> x;
            vec.push_back(x);
        }
        data.push_back(vec);
    }
    dfs_digui(1, m, data);
    cout << endl;
    dfs(1, m, data);
    cout << endl;
    bfs(1, m, data);
    system("pause");
    return 0;
}
  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

~青萍之末~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值