摘要
二叉树的下一个结点_牛客题霸_牛客网
给定一个二叉树其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的next指针。下图为一棵有9个节点的二叉树。树中从父节点指向子节点的指针用实线表示,从子节点指向父节点的用虚线表示
一、二叉树的中序遍历
根据给定输入中的结点指针向父级进行迭代,直到找到该树的根节点;然后根据根节点进行中序遍历,当遍历到和给定树节点相同的节点时,下一个节点就是我们的目标返回节点
- step 1:首先先根据当前给出的结点找到根节点
- step 2:然后根节点调用中序遍历
- step 3:将中序遍历结果存储下来
- step 4:最终拿当前结点匹配是否有符合要求的下一个结点
package Tree;
import java.util.ArrayList;
/**
* @Classname JZ08二叉树的下一个节点
* @Description TODO
* @Date 2023/2/24 20:00
* @Created by xjl
*/
public class JZ08二叉树的下一个节点 {
public class TreeLinkNode {
int val;
TreeLinkNode left = null;
TreeLinkNode right = null;
TreeLinkNode next = null;
TreeLinkNode(int val) {
this.val = val;
}
}
ArrayList<TreeLinkNode> nodes = new ArrayList<>();
public TreeLinkNode GetNext(TreeLinkNode pNode) {
// 获取根节点
TreeLinkNode root = pNode;
while (root.next != null) {
root = root.next;
}
// 中序遍历打造nodes
InOrder(root);
// 进行匹配
int n = nodes.size();
for (int i = 0; i < n - 1; i++) {
TreeLinkNode cur = nodes.get(i);
if (pNode == cur) {
return nodes.get(i + 1);
}
}
return null;
}
// 中序遍历
void InOrder(TreeLinkNode root) {
if (root != null) {
InOrder(root.left);
nodes.add(root);
InOrder(root.right);
}
}
}
复杂度分析:
- 时间复杂度:O(N),因为遍历了树中的所有节点。
- 空间复杂度:O(N),因为引入了存储所有节点的空间。
二、分类直接寻找
直接寻找分为三种情况
- 如果给出的结点有右子节点,则最终要返回的下一个结点即右子树的最左下的结点
- 如果给出的结点无右子节点,且当前结点是其父节点的左子节点,则返回其父节点
- 如果给出的结点无右子节点,且当前结点是其父节点的右子节点,则先要沿着左上方父节点爬树,一直爬到当前结点是其父节点的左子节点为止,返回的就是这个父节点;或者没有满足上述情况的则返回为NULL
具体做法:
- step 1:判断该节点是否符合思路中第一点,则一直找到右子树的左下节点为返回值
- step 2:判断该节点是否符合思路中第二点,则返回当前节点的父亲节点
- step 3:判断该节点是否符合思路中第三点,则迭代向上找父节点,直到迭代的当前节点是父节点的左孩子节点为止,返回该父节点;如果不满足上述情况返回NULL
import java.util.*;
public class Solution {
public TreeLinkNode GetNext(TreeLinkNode pNode) {
// 情况一
if(pNode.right != null) {
TreeLinkNode rchild = pNode.right;
// 一直找到右子树的最左下的结点为返回值
while(rchild.left != null) rchild = rchild.left;
return rchild;
}
// 情况二
if(pNode.next != null && pNode.next.left == pNode) {
return pNode.next;
}
// 情况三
if(pNode.next != null) {
TreeLinkNode ppar = pNode.next;
// 沿着左上一直爬树,爬到当前结点是其父节点的左自己结点为止
while(ppar.next != null && ppar.next.right == ppar) ppar = ppar.next;
return ppar.next;
}
return null;
}
}
复杂度分析:
- 时间复杂度:O(N),最大代价是当树退化成一个只包含右子节点的链表,当给定节点是中序遍历最后一个节点时,会进入情况三的分析部分,在向左上方向一直迭代直到根节点,才会发现应该返回NULL,即无下一个节点,此时代价最大。
- 空间复杂度:O(1),无额外空间的借用
博文参考
《剑指offer》