不带parent指针的successor求解

时间:2023-03-09 00:23:28
不带parent指针的successor求解

问题:

  请设计一个算法,寻找二叉树中指定结点的下一个结点(即中序遍历的后继)。给定树的根结点指针TreeNode* root和结点的值int p,请返回值为p的结点的后继结点的值。保证结点的值大于等于零小于等于100000且没有重复值,若不存在后继返回-1。注意这里没有parent指针。

思路:

  本质上还是二叉树的中序遍历。所以经过前面的学习我们有递归和非递归两种解法。

  解法一(递归解法):

 public class Successor2 {
public int findSucc(TreeNode root, int p) {
if (root == null)
return -1;
in(root, p);
return succ;
} private void in(TreeNode<Integer> node, int p) {
if (node == null)
return;
in(node.left, p);
if (preValue == p) {
if (succ != -1)
return;
succ = node.val;
// System.out.println(succ);
return;
}
preValue = node.val;
in(node.right, p);
} private int preValue = Integer.MIN_VALUE;
private int succ = -1; public static void main(String[] args) {
TreeNode root = buildTree(8, 6, 10);
root.left.left = buildTree(3, 1, 4);
root.right.right = buildTree(13, 11, 15);
root.right.left = new TreeNode(9); final Successor2 tool = new Successor2();
System.out.println(tool.findSucc(root, 8)); // 输出9
} public static <T> TreeNode<T> buildTree(T rootValue, T lValue, T rValue) {
TreeNode root = new TreeNode(rootValue);
TreeNode left = new TreeNode(lValue);
TreeNode right = new TreeNode(rValue);
root.left = left;
root.right = right;
return root;
} public static class TreeNode<T> { public T val;
public TreeNode<T> left = null;
public TreeNode<T> right = null; public TreeNode(T val) {
this.val = val;
} }
}

  解法二(非递归解法):

 import java.util.Stack;

 public class Successor1 {
public int findSucc(TreeNode<Integer> root, int p) {
if (root == null)
return -1;
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode curr = root;
boolean isFound = false;
// curr不为空或者栈不为空,都可以继续处理
while (curr != null || !stack.isEmpty()) {// 没有生产也没有消费,就退出循环了
// 左支路依次入栈
while (curr != null) {
stack.add(curr);
curr = curr.left;
}
if (!stack.isEmpty()) {
TreeNode<Integer> pop = stack.pop();// 栈的弹出顺序就是中序遍历的顺序
// 上一轮修改了标志位,当前出栈的值就是我们需要的值
if (isFound) {
return pop.val;
}
// 如果弹出值和p相同,那么下次弹出的值就是我们需要的值,修改标志位
else if (pop.val == p) {
isFound = true;
}
// curr指向pop的右子树,继续外层循环
curr = pop.right;// 有可能为空,为空,只消费栈中内容,不为空,就要向栈中生产若干内容
}
}
return -1;
} public static void main(String[] args) {
TreeNode<Integer> root = buildTree(1, 2, 3);
root.left.left = buildTree(4, 5, 6);
root.right.right = buildTree(7, 8, 9); System.out.println(new Successor1().findSucc(root, 3)); // 输出8
} public static <T> TreeNode<T> buildTree(T rootValue, T lValue, T rValue) {
TreeNode root = new TreeNode(rootValue);
TreeNode left = new TreeNode(lValue);
TreeNode right = new TreeNode(rValue);
root.left = left;
root.right = right;
return root;
} public static class TreeNode<T> { public T val;
public TreeNode<T> left = null;
public TreeNode<T> right = null; public TreeNode(T val) {
this.val = val;
} }
}