C++二叉树的深度优先搜索DFS和广度优先搜索BFS案例

案例

题目来源:leetcode 101. 对称二叉树

案例传送门

给定一个二叉树,检查它是否是镜像对称的。

例如,二叉树[1,2,2,3,4,4,3] 是对称的。

    1
   / \
  2   2
 / \ / \
3  4 4  3

但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的:

    1
   / \
  2   2
   \   \
   3    3

进阶:

你可以运用递归和迭代两种方法解决这个问题吗?

树的生成

层序生成树,通过给定元素生成(供调试DFS及BFS使用):

#include <vector>
#include <string>
#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) {}
};

class TreeMove {
private:
// 树的节点元素
    std::vector<std::string> nodeValue = {"1", "2", "2", "3", "#", "#", "3", "#", "1"};
// 树的根节点
    TreeNode* root = nullptr;
    
public:
    std::vector<std::string> getNodeValue() {
        return nodeValue;
    }
    
    TreeNode* creatTree(std::vector<std::string>& nodeValue) {
// 如果vector为空或首元素为"#"则返回空
        if (nodeValue.empty() || !strcmp(nodeValue.front().c_str(), "#"))
            return nullptr;
// 队列内存放二级指针
        std::queue<TreeNode**> treeLeaf;
        treeLeaf.push(&root);
        int vIndex = 0;
        while (vIndex < nodeValue.size()) {
            TreeNode** temp = treeLeaf.front();
            treeLeaf.pop();
                if (strcmp(nodeValue[vIndex].c_str(), "#")) {
                    *temp = new TreeNode(std::stoi(nodeValue[vIndex]));
// 将空指针的(左右孩子的)地址存入队列。指针虽是个指向为空的变量,但指针本身具有地址。
                    treeLeaf.push(&(*temp) -> left);
                    treeLeaf.push(&(*temp) -> right);
                }
            ++ vIndex;
        }
        return root;
    }
};

int main(int argc, const char * argv[]) {
    TreeMove tree;
    std::vector<std::string> nodeValue = tree.getNodeValue();
    TreeNode* root = tree.creatTree(nodeValue);
    return 0;
}

深度优先搜索DFS

过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次。

/**
 * Definition for a binary tree node.
 * 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) {}
 * };
 */
class Solution {
public:
    bool isSymmetric(TreeNode* root) {
        return helper(root -> left, root -> right);
    }
    bool helper(TreeNode* left, TreeNode* right) {
        if (!left && !right) {
            return true;
        }
        if (!left || !right) {
            return false;
        }
        
        if (left -> val == right -> val) {
            if (helper(left -> left, right -> right)) {
                return helper(left -> right, right -> left);
            }
            else return false;
        }
        return false;
    }

广度优先搜索BFS

系统地展开并检查图中的所有节点。

/**
 * Definition for a binary tree node.
 * 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) {}
 * };
 */
class Solution {
public:
    bool isSymmetric(TreeNode* root) {
        queue<TreeNode*> q;
        q.push(root);
        while(!q.empty()) {
            int size = q.size();
            vector<long> layer;
            for(int i = 0; i < size; ++i) {
                TreeNode* temp = q.front();
                q.pop();
                if (temp)
                    layer.push_back(temp -> val);
                else
                // 用LONG_MAX代替空节点
                    layer.push_back(LONG_MAX);
                if (temp) {
                    q.push(temp -> left);
                    q.push(temp -> right);
                }
            }
            if (!isReg(layer)) return false;
        }
        return true;
    }

    bool isReg(vector<long>& v) {
        for (int i = 0; i < v.size()/2; ++i) {
            if (v[i] != v[v.size() - i - 1]) {
                return false;
            }
        }
        return true;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值