二叉树的下一个节点

题目描述

输入一棵二叉树前序遍历和中序遍历的结果,请重建该二叉树。

注意:

  • 如果给定的节点是中序遍历序列的最后一个节点,则返回空节点;
  • 二叉树一定不为空,且给定的节点一定不是空节点
样例
假定二叉树为:[2,1,3,null.null,null,null]
Input: 值等于2的节点
Output: 值等于3的节点
该的二叉树如下所示:
      2
     / \
    1   3

解题思路

  • 普通思路

    • 描述
      中序遍历二叉树并将节点通过vector存储,然后遍历vector查找即可。

    • 实现代码:

      /*
      包含头文件:
      #include <vector>
      结构体:
      struct TreeNode {
      	int val;
      	TreeNode* left;
      	TreeNode* right;
      	TreeNode(int val)
      	{
      		this->val = val;
      		this->left = NULL;
      		this->right = NULL;
      	}
      };
      */
      vector<TreeNode*> inNode; //存储中序遍历的二叉树节点
      int index; //存储指定节点在inNode中的位置
      
      void inorder(TreeNode* head,TreeNode* search)
      {
      	if (head != NULL)
      	{
      		inorder(head->left,search);
      		inNode.push_back(head);
              if(head == search)
              {
                  index = inNode.size() - 1;
      		}
      		inorder(head->right,search);
      	}
      }
      
    • 复杂度分析

      时间复杂度: ≈ O ( n ) ​ \approx O(n)​ O(n)

      ​ 遍历递归次数与节点数有关,虽不知具体是多少,但是一定是一个线性关系

      空间复杂度: O ( n + 1 ) ≈ O ( n ) O(n + 1) \approx O(n) O(n+1)O(n)

      ​ 使用一个vector类型变量和一个int类型变量

  • 高级思路

    • 描述

      本题目可以针对不同情况进行分析。题目要求找到节点的后继节点,按照中序遍历规则"左根右",则分情况当前节点的右子树是否存在。

      1. 当前节点右子树不为空

        获取右子树,右子树最左边的节点即为下一个节点

      2. 当前节点右子树为空

        找到当前节点的父节点,如果该节点是父节点的左节点,则后继节点即为该父节点。

    • 实现代码:

      /*
      包含头文件:
      #include <vector>
      结构体:
      struct TreeNode {
      	int val;
      	TreeNode* left;
      	TreeNode* right;
      	TreeNode* father; //存储当前节点的父节点
      	TreeNode(int val)
      	{
      		this->val = val;
      		this->left = NULL;
      		this->right = NULL;
      		this->father = NULL;
      	}
      };
      */
      
      TreeNode* inorderSuccessor(TreeNode* p)
      {
          if(p->right) //当前节点的右子树存在
          {
              p = p->right; //赋值为右子树
              while(p != NULL) //寻找最左节点,返回
              {
                  p = p->left;
              }
              return p;
          }
          
          while(p->father && p == p->father->right) //父节点存在,且该节点为父节点的右节点
          {
              p = p->father;
      	}
          return p->father; //如果是while第一个条件失败,则返回的是一个空父节点
                            //如果是while第二个条件失败,则返回的是父节点(此为后继节点)
      }
      
    • 复杂度分析

      时间复杂度: O ( l o g n ) O(log^n) O(logn)

      ​ 从当前节点向下或向上按照一种路径搜索,当然是 l o g n log^n logn

      空间复杂度: O ( 0 ) O(0) O(0)

      ​ 不需要任何辅助变量

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值