深度优先遍历(DFS,全称为 Depth First Traversal),是我们树或者图这样的数据结构中常⽤的
⼀种遍历算法。这个算法会尽可能深的搜索树或者图的分支,直到⼀条路径上的所有节点都被遍历
完毕,然后再回溯到上⼀层,继续找⼀条路遍历。
在⼆叉树中,常见的深度优先遍历为:前序遍历、中序遍历以及后序遍历。
因为树的定义本⾝就是递归定义,因此采⽤递归的方法去实现树的三种遍历不仅容易理解⽽且代码很简洁。并且前中后序三种遍历的唯⼀区别就是访问根节点的时机不同,在做题的时候,选择⼀个适当的遍历顺序,对于算法的理解是非常有帮助的。
一、计算布尔二叉树的值
1.题目描述
2.算法思路
书面解释就是:
画图来理解一下:
我们如果想知道根节点true or false,我们需要知道其子节点,true or false,进而层层递归
3.代码实现
class Solution
{
public:
bool evaluateTree(TreeNode* root)
{
if(root->left == nullptr)
{
return root->val == 0 ? false : true;
}
bool left = evaluateTree(root->left);
bool right = evaluateTree(root->right);
return root->val == 2 ? left | right : left & right;
}
};
二、求根节点到叶节点数字之和
1.题目描述
2.算法思路
我们画图来理解一下,举个例子:
我们有如下二叉树
首先,我们
合父节点的信息与当前节点的信息计算当前节点数字,并向下传递:
溯时返回当前子树(当前节点作为子树根节点)数字和:
最后返回计算的和就行了
3.代码实现
class Solution {
public:
int dfs(TreeNode* root, int prevSum)
{
if (root == nullptr)
{
return 0;
}
int sum = prevSum * 10 + root->val;
if (root->left == nullptr && root->right == nullptr)
{
return sum;
} else
{
return dfs(root->left, sum) + dfs(root->right, sum);
}
}
int sumNumbers(TreeNode* root) {
return dfs(root, 0);
}
};
三、二叉树剪枝
1.题目描述
2.算法思路
如果我们选择从上往下删除,我们需要收集左右⼦树的信息,这可能导致代码编写相对困难。然而, 通过观察我们可以发现,如果我们先删除最底部的叶子节点,然后再处理删除后的节点,最终的结果并不会受到影响。 因此,我们可以采⽤后序遍历的方式来解决这个问题。在后序遍历中,我们先处理左子树,然后处理 右子树,最后再处理当前节点。在处理当前节点时,我们可以判断其是否为叶子节点且其值是否为 0,
如果满足条件,我们可以删除当前节点。
算法流程:
后序遍历的主要流程:
3.代码实现:
class Solution
{
public:
TreeNode* pruneTree(TreeNode* root)
{
if(root == nullptr) return nullptr;
root->left = pruneTree(root->left);
root->right = pruneTree(root->right);
if(root->left == nullptr && root->right == nullptr && root->val == 0)
{
delete root; // 防⽌内泄漏
root = nullptr;
}
return root;
}
};
四、验证二叉搜索树
1.题目描述
2.算法思路
如果一棵树是二叉搜索树,那么它的中序遍历的结果一定是⼀个严格递增的序列。 因此,我们可以初始化⼀个无穷小的全区变量,用来记录中序遍历过程中的前驱结点。那么就可以在中序遍历的过程中,先判断是否和前驱结点构成递增序列,然后修改前驱结点为当前结点,传入下一层的递归中。
算法流程:
3.代码实现
class Solution
{
public:
long prev = LONG_MIN;
bool isValidBST(TreeNode* root)
{
if(root == nullptr) return true;
bool left = isValidBST(root->left);
// 剪枝
if(left == false) return false;
bool cur = false;
if(root->val > prev)
cur = true;
// 剪枝
if(cur == false) return false;
prev = root->val;
bool right = isValidBST(root->right);
return left && right && cur;
}
};
感谢大家的观看,如有错误欢迎指正!