目录

图的遍历:dfs和bfs

图的遍历:dfs和bfs

dfs深度优先遍历:按照某一策略选择一条道路遍历图,当到达无法前进的节点时退回上一节点选择另一条道路,并以此反复递归,直到遍历所有节点。

以树(一种特殊的图)的遍历为例介绍dfs:前序,中序,后序遍历实质均为深度优先遍历

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <stack>
#include <queue>
struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode()
     : val(0), left(nullptr), right(nullptr) {}
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
    TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};
//(递归,前序遍历)
void dfs(TreeNode* root){
        if(root!=nullptr)return ;
        else{
            process(root);//遍历根节点
            dfs(root->left);
            dfs(root->right);
        }
};
//(迭代)使用栈进行维护,将要遍历的节点压栈,然后出栈后检查此节点下是否还有未遍历的节点,有的话压栈,没有的话不断回溯(出栈),根据前序遍历的顺序先压右节点再压左节点
void dfs2(TreeNode* root){
    std::stack<TreeNode*> s;
    s.push(root);//压栈
    while(!s.empty()){//每次弹出结点即遍历此节点,遍历完毕,栈为空,结束循环
        TreeNode* node=s.top();//纪录节点
        s.pop();//弹出节点
        process(node);//遍历结点
        if (node->right)s.push(node->right);//压入右节点
        if (node->left)s.push(node->left);//压入左节点
    }
}

bfs广度优先遍历:指的是从图的一个未遍历的节点出发,先遍历这个节点的相邻节点,遍历完后再依次遍历每个相邻节点的相邻节点。

以树(一种特殊的图)的遍历为例介绍bfs:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
//使用队列,由根节点开始进入循环,遍历该节点,出队列,判断有无子节点,有则入队列(注意这也保证了下一层遍历顺序)
void bfs(TreeNode* root){
    std::queue<TreeNode*>q;
    q.push(root);
    while (!q.empty())
    {
        TreeNode* front=q.front();
        q.pop();
        process(front);
        if(front->left) q.push(front->left);
        if(front->right) q.push(front->right);   
    }    
}