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

来源:互联网 发布:淘宝买家评价多久清空 编辑:程序博客网 时间:2024/05/29 18:53

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

给定二叉树的头结点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;    }};


原创粉丝点击