代码随想录训练营17day-二叉树6

文章介绍了如何使用递归构建最大二叉树,合并两个二叉树,以及在二叉搜索树中搜索和验证其性质,强调了递归思路和初始化问题的处理。
摘要由CSDN通过智能技术生成

一、654 最大二叉树

主要思路:

1)找到起始到结束区间段的最大值的index;

2)创建节点,初始化(这里需要结构体所有的entry都初始化),然后递归到子树;

3)注意区间是左闭右开,因此填入区间时候需要区分;

4)返回root节点。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
 struct TreeNode* buildTree(int* nums, int numsSize, int left, int right)
 {
    //函数返回接口
    if(left >= right)
      return NULL;
    //找到最大值的index
    int maxvalueidx = left;
    for(int i = left + 1; i < right; i++)//遍历整个区间找到最大值
    {
         if(nums[i] > nums[maxvalueidx])
         {
            maxvalueidx = i;
         }
    }

    //malloc一个节点
    struct TreeNode* root = (struct TreeNode*)malloc(sizeof(struct TreeNode));
    root->val = nums[maxvalueidx];
    root->left = NULL;
    root->right = NULL;

    //递归调用
    root->left = buildTree(nums, numsSize, left, maxvalueidx);//左区间 左闭右开原则
    root->right = buildTree(nums, numsSize, maxvalueidx + 1, right);

    return root;
 }
struct TreeNode* constructMaximumBinaryTree(int* nums, int numsSize) {
    if(numsSize == 0)
    {
        return NULL;
    }
    return buildTree(nums, numsSize, 0, numsSize);
}

二、617 合并二叉树

 递归思路:

1)函数返回条件:如果root1为空,不管root2怎么样,直接返回root2;

2)把root1作为返回的节点,所以如果有值加到root1

3)root1的左右子树递归

struct TreeNode* mergeTrees(struct TreeNode* root1, struct TreeNode* root2) {
    //利用前序中序后序遍历都可以
    if(root1 == NULL) return root2;
    if(!root2) return root1;

    root1->val +=root2->val;
    root1->left = mergeTrees(root1->left, root2->left);
    root1->right = mergeTrees(root1->right, root2->right);
    return root1;
}

三、700 二叉搜索树中的搜索

 1 首先理解二叉搜索树:

  1. 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
  2. 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
  3. 它的左、右子树也分别为二叉搜索树

递归三要素:

1)返回条件:如果root为空,或者找到指定value;

2)单层递归:因为搜索树是有序的,所以应该判断;

3)因为不是全局搜索,找到指定条件需要返回,因此需要返回值。 

struct TreeNode* searchBST(struct TreeNode* root, int val) {
    if(root == NULL || root->val == val)
    {
        return root;
    }
    
    struct TreeNode*  result  = NULL;
    if(root->val > val)
    {
        //在左子树
        result =  searchBST(root->left, val);
    }
    if(root->val < val)
    {
        result =  searchBST(root->right, val);
    }

    return result;
}

四、98 验证二叉搜索树

这里遇到一个初始化问题:在leetcode上面,如果全局初始化,会导致数据异常!!!如下图,我把pre指针放在全局初始化,导致某一次预期pre应该为空,但是实际却没有。

struct TreeNode* pre;
bool check(struct TreeNode* root)
{
    if(root == NULL)
      return true;
   
    bool left_flag = check(root->left);
    //printf("L%d %d", left_flag, pre == NULL);
    if(pre != NULL && pre->val >= root->val)
       return false;
    //printf("LL%d %d", left_flag, pre == NULL);
    pre = root;
    bool right_flag = check(root->right);
    //printf("%d %d", left_flag, right_flag);
    return left_flag && right_flag;
}

bool isValidBST(struct TreeNode* root) {
   pre = NULL;
   return check(root);
}

另外一种写法:

 注意:maxvalue是在接口内部初始化的。

long long maxvalue;
bool check(struct TreeNode* root)
{
    // if(pre && root && pre->val >= root->val)
    //   return false;
    if(root == NULL)
      return true;
   
    bool left_flag = check(root->left);
    printf("L %d \n", left_flag);
    // if(pre && pre->val >= root->val)
    //    return false;
    // if(pre)
    // printf("LL%d %d %d\n", left_flag, pre->val, root->val);
    // pre = root;
     printf("right %lld %d\n", maxvalue, root->val);
    if (maxvalue < root->val) 
        maxvalue = root->val;
    else
     return false;
    printf("right\n");
    bool right_flag = check(root->right);
    printf("//%d %d\n", left_flag, right_flag);
    return left_flag && right_flag;
}

bool isValidBST(struct TreeNode* root) {
   //struct TreeNode* pre = NULL;
   maxvalue = LONG_MIN;
   return check(root);
}

迭代:

bool isValidBST(struct TreeNode* root) {
   //pre = NULL;
   //return check(root);
   //迭代
   //用来保存节点
   struct TreeNode** NodeStk = (struct TreeNode**)malloc(sizeof(struct TreeNode*) * 10001);
   struct TreeNode* cur = root;
   struct TreeNode* pre = NULL;
   int top = -1;
   while(cur || top > -1)
   {
      if(cur)
      {
         //前序遍历,一直入栈直到为空
         NodeStk[++top] = cur;
         cur = cur->left;
      }
      else
      {
        //cur为空,top就是叶子节点
        cur = NodeStk[top];
        top--;//出栈
        if(pre && pre->val >= cur->val)//如果上一个节点的值超过当前的值
        {
            return false;
        }
        pre = cur;
        cur = cur->right;//替换cur 遍历右节点 按照左中右的顺序
      }
   }
   return true;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值