最大二叉搜索子树 后序遍历

有一棵二叉树,其中所有节点的值都不一样,找到含有节点最多的搜索二叉子树,并返回这棵子树的头节点.

给定二叉树的头结点root,请返回所求的头结点,若出现多个节点最多的子树,返回头结点权值最大的。

思路:找二叉树中最大搜索二叉子树无非两种情况:
第一种:如果来自root左子树上的最大BST以root.left为头,来自root右子树上的最大BST以root.right 为头,且左边BST的最大值小于root.val,且右边BST的最小值大于root.val。那么,以节点root为根节点的整棵树都是BST
第二种:不满足条件1的话,说明头节点不在搜索子树中,以root为根的树的最大BST是来自左子树的最大BST和右子树的最大BST中包含节点树较多的那一个。

具体的过程描述如下:

1,整个过程是二叉树的后序遍历。(左右根)

2,遍历到当前节点记为cur时,先遍历cur的左子树收集4个信息,分别是左子树上最大搜索二叉子树的头节点(IBST) ,节点数(ISize),最小值(IMin),最大值(IMax).(从下往上创建的二叉搜索子树,每处理一个结点若当前结点为根的树是二叉搜索树,则结点数目=左子树结点数+右子树结点数+1.而左右子树结点数又是从下往上传来的,从最底层null传来的是0,每层往上=左子树结点数+右子树结点数+1). 再遍历cur的右子树收集4个信息,分别是右子树上最大搜索二叉子树的头节点(RBST),节点数(RSize),最小值(RMin),最大值(RMax).

3, 根据步骤2收集的信息,判断是否满足第一种情况,如果满足第一种情况就返回cur,如果满足第二种情况,就返回IBST和RBST中较大的一个。

4,可以使用全局变量的方式实现步骤2中收集节点数,最大和最小的情况。

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};*/
class MaxSubtree {
public:
    TreeNode* getMax(TreeNode* root) {
        if (root == NULL)  return NULL;
        int max, min, nums;//记录二叉树的最大值,最小值和子树中最大二叉搜索树的结点数
        return myGetMax(root, max, min, nums);
    }
    TreeNode* myGetMax(TreeNode* node, int &maxNode, int &minNode, int &numNode){
      //递归边界:NULL。递归用到的计数,都是从递归边界开始的!所以写递归时一定要先写好递归边界的返回情况
        if (node == NULL){
            minNode = INT_MAX;//Null结点,子树最小值不存在,所以令为最大值
            maxNode = INT_MIN;///Null结点,子树最大值不存在,所以令为最小值
            numNode = 0;//Null结点的最大二叉搜索子树结点数为0
            return NULL;
        }
        //递归左右子树,获取4个信息
        int lmax, lmin, lnum;//记录左子树的最大值,最小值和结点数
        TreeNode *lnode = myGetMax(node->left, lmax, lmin, lnum);
        int rmax, rmin, rnum;//记录右子树的最大值,最小值和结点数
        TreeNode *rnode = myGetMax(node->right, rmax, rmin, rnum);
        //更新当前结点为根的子树的最大值、最小值
        maxNode = max(rmax, node->val);
        minNode = min(lmin, node->val);
        //根据左右子树递归信息,判断当前结点为根的子树性质:
        //如果是二叉搜索树则更新最大二叉搜索子树的信息
        if(lmax < node->val && rmin > node->val && lnode == node->left && rnode == node->right){
            numNode = lnum + rnum + 1;
            return node;
        }
        //如果不是,则返回左右子树中的最大二叉搜索子树的信息
        numNode = max(lnum,rnum);//更新当前子树的最大二叉搜索树的结点数
        return lnum > rnum ? lnode : rnode;
    }
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值