不带parent指针的successor求解
Posted xiaoyh
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了不带parent指针的successor求解相关的知识,希望对你有一定的参考价值。
问题:
请设计一个算法,寻找二叉树中指定结点的下一个结点(即中序遍历的后继)。给定树的根结点指针TreeNode* root和结点的值int p,请返回值为p的结点的后继结点的值。保证结点的值大于等于零小于等于100000且没有重复值,若不存在后继返回-1。注意这里没有parent指针。
思路:
本质上还是二叉树的中序遍历。所以经过前面的学习我们有递归和非递归两种解法。
解法一(递归解法):
1 public class Successor2 { 2 public int findSucc(TreeNode root, int p) { 3 if (root == null) 4 return -1; 5 in(root, p); 6 return succ; 7 } 8 9 private void in(TreeNode<Integer> node, int p) { 10 if (node == null) 11 return; 12 in(node.left, p); 13 if (preValue == p) { 14 if (succ != -1) 15 return; 16 succ = node.val; 17 // System.out.println(succ); 18 return; 19 } 20 preValue = node.val; 21 in(node.right, p); 22 } 23 24 private int preValue = Integer.MIN_VALUE; 25 private int succ = -1; 26 27 public static void main(String[] args) { 28 TreeNode root = buildTree(8, 6, 10); 29 root.left.left = buildTree(3, 1, 4); 30 root.right.right = buildTree(13, 11, 15); 31 root.right.left = new TreeNode(9); 32 33 final Successor2 tool = new Successor2(); 34 System.out.println(tool.findSucc(root, 8)); // 输出9 35 } 36 37 public static <T> TreeNode<T> buildTree(T rootValue, T lValue, T rValue) { 38 TreeNode root = new TreeNode(rootValue); 39 TreeNode left = new TreeNode(lValue); 40 TreeNode right = new TreeNode(rValue); 41 root.left = left; 42 root.right = right; 43 return root; 44 } 45 46 public static class TreeNode<T> { 47 48 public T val; 49 public TreeNode<T> left = null; 50 public TreeNode<T> right = null; 51 52 public TreeNode(T val) { 53 this.val = val; 54 } 55 56 } 57 }
解法二(非递归解法):
1 import java.util.Stack; 2 3 public class Successor1 { 4 public int findSucc(TreeNode<Integer> root, int p) { 5 if (root == null) 6 return -1; 7 Stack<TreeNode> stack = new Stack<TreeNode>(); 8 TreeNode curr = root; 9 boolean isFound = false; 10 // curr不为空或者栈不为空,都可以继续处理 11 while (curr != null || !stack.isEmpty()) {// 没有生产也没有消费,就退出循环了 12 // 左支路依次入栈 13 while (curr != null) { 14 stack.add(curr); 15 curr = curr.left; 16 } 17 if (!stack.isEmpty()) { 18 TreeNode<Integer> pop = stack.pop();// 栈的弹出顺序就是中序遍历的顺序 19 // 上一轮修改了标志位,当前出栈的值就是我们需要的值 20 if (isFound) { 21 return pop.val; 22 } 23 // 如果弹出值和p相同,那么下次弹出的值就是我们需要的值,修改标志位 24 else if (pop.val == p) { 25 isFound = true; 26 } 27 // curr指向pop的右子树,继续外层循环 28 curr = pop.right;// 有可能为空,为空,只消费栈中内容,不为空,就要向栈中生产若干内容 29 } 30 } 31 return -1; 32 } 33 34 public static void main(String[] args) { 35 TreeNode<Integer> root = buildTree(1, 2, 3); 36 root.left.left = buildTree(4, 5, 6); 37 root.right.right = buildTree(7, 8, 9); 38 39 System.out.println(new Successor1().findSucc(root, 3)); // 输出8 40 } 41 42 public static <T> TreeNode<T> buildTree(T rootValue, T lValue, T rValue) { 43 TreeNode root = new TreeNode(rootValue); 44 TreeNode left = new TreeNode(lValue); 45 TreeNode right = new TreeNode(rValue); 46 root.left = left; 47 root.right = right; 48 return root; 49 } 50 51 public static class TreeNode<T> { 52 53 public T val; 54 public TreeNode<T> left = null; 55 public TreeNode<T> right = null; 56 57 public TreeNode(T val) { 58 this.val = val; 59 } 60 61 } 62 }
以上是关于不带parent指针的successor求解的主要内容,如果未能解决你的问题,请参考以下文章