算法(2)----二叉树的深搜

前序:

二叉树的遍历:前序遍历,中序遍历,后序遍历,主要解决问题是利用这三种方法对其进行计算

一:计算布尔二叉树的值

题目:

有一个完整二叉树,有以下特征:

叶子结点要么为0,要么为1,分别表示false,   true

非叶子节点要么为2,要么为3,分别表示逻辑或,与逻辑与

计算一个叶子结点的值为:

如果节点为叶子结点,节点的值为它本身,即为false,  true

如果为非叶子节点,要计算两个孩子的节点值,然后将该节点的运算符对两个孩子进行运算

返回根节点root的布尔值

示例:

分析:

非叶子节点表示逻辑词,叶子节点表示对错,  二叉树又为完整二叉树,要得到整个二叉树的布尔值,要先从最下面开始,得到每个非叶子节点左右子树的布尔值,适用于后序遍历

函数头:将节点的位置传过去,并返回布尔值即可

bool evaluateTree(TreeNode* root);

函数体:得到左右子树的值,然后根据根节点的值返回它的布尔值

递归出口:左右节点均为空,直接返回该节点的值

class Solution {
public:
    bool evaluateTree(TreeNode* root) {
        if(root->left==nullptr&&root->right==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;
      }
};

二:求根节点到叶节点所有数字的和

题目:

给一个二叉树的根节点root,树中每个节点分别存有0~9的值,每条从根节点到叶节点的路径分别表示一个数字。

如:从根节点到叶节点的路径为1->2->3,则表示数字123

要计算所有根节点到叶节点所有路径的数字之和!

示例:

分析:

从根节点开始,一直传着节点的值,若遇到叶子节点节点,则这条路径借宿

函数头:递归函数,需要返回一个整数值,传参要传根节点和一个原先节点的值

int dfs(TreeNode* root, int persume)

函数体:先将原先得到的值乘10再加上当前节点的值,再对是否为叶子节点进行判断

递归出口:遇到左右节点均为空,直接返回原先算出来的值

int dfs(TreeNode*root,int persume)
    {
        persume = persume*10+root->val;
        if(root->left==nullptr&&root->right==nullptr)
        return persume;
        int ret = 0;
        if(root->left)  ret+= dfs(root->left,persume);
        if(root->right) ret+= dfs(root->right,persume);
        return ret;
        
    }

三:二叉树的剪枝

题目:

给一个二叉树的根节点,此外每个节点的值为要么为1,要么为0,返回移除了所有不包含1的子树的原子数。

示例:

分析:

要先判断左右子树是否为空,然后根据本身节点的值是否为0进行判断是否要对齐进行删除,要利用的为后序遍历

函数头:返回节点地址,传参节点的地址

TreeNode* pruneTree(TreeNode* root)

函数体:先判断本身节点是否为空,然后对左右子树进行处理,之后再根据本身节点的值进行判断要不要进行剪枝

递归出口:节点为空,直接返回空,之后直接返回root

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)
        {
            root = nullptr;
        }
        return root;
     }

四:验证二叉搜索树

题目:

给一个二叉树,判断是否为有效的搜索二叉树

有效搜索树:

节点左子树只包含小于当前节点的数

节点右子树只包含大于当前节点的数

所有·左子树和右子树都要为有效的搜索二叉树

PS:二叉搜索树的中序遍历的结果为一个有序的序列

示例:

分析以及一些重要的算法方法:

1:全局变量的优势:减少传参的个数,可以对其直接进行改变

2:回溯:在深入遍历时,一般都存在着回溯

3:剪枝:加速搜索过程   

思路:使用中序遍历,用一个值存放前一个节点的值,分别得到左右子树的值,再将根节点与之进行比较,如果大小关系符合就返回true,不符合返回false

分析:先判断左右子树是否为搜索二叉树,再加上本身进行判断

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;

      prev = root->val;
      bool right = isValidBST(root->right);
      return left&&right&&cur;
    }
};

五:查找二叉搜索树中第k小的元素

题目:

给定一个二叉搜索树的根节点 root,和一个整数 k ,请你设计一个算法查找其中第 k 小的元素(从 1 开始计数)

PS:搜索二叉树的中序遍历为一个有序的序列

分析:

总体思路:全局变量加中序遍历

先设立两个全局变量,一个存放最后要用的值,一个用来计数遍历的次数

class Solution {
    int cout;
    int ret;
public:
    int kthSmallest(TreeNode* root, int k) {
     cout = k;
     dfs(root);
     return ret;
    }
    void dfs(TreeNode* root)
    {
     if(root==nullptr||cout==0)  return;
     dfs(root->left);
     cout--;
     if(cout==0)  ret = root->val;
     dfs(root->right);
    }
};

六:二叉树的所有路径

题目:

给一个根节点,按任何顺序返回,从根节点到叶节点的所有路径

分析:

使用前序遍历对二叉树进行遍历,使用传参的方法实现回溯更加方便

创立一个全局变量string,用来存放各个路径的字符串

class Solution {
public:
    vector<string> ret;
    vector<string> binaryTreePaths(TreeNode* root) {
          string path;
          if(root==nullptr)  return ret;
          dfs(root,path);
          return ret;
    }
    void dfs(TreeNode* root,string path)
    {
        path += to_string(root->val);
        if(root->left==nullptr&&root->right==nullptr)
        {
            ret.push_back(path);
            return;
        }
        path+="->";
        if(root->left)  dfs(root->left,path);
        if(root->right) dfs(root->right,path);
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值