问题:

  请设计一个算法,寻找二叉树中指定结点的下一个结点(即中序遍历的后继)。给定树的根结点指针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;
} }
}

不带parent指针的successor求解的更多相关文章

  1. 带parent指针的successor求解

    题目: 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点(不存在重复数据).树中的结点不仅包含左右子结点,同时包含指向父结点的指针. 思路: 如果当前节点有右孩子,则下一个节点是右孩子中 ...

  2. 单链表(带random指针)深拷贝(Copy List with Random Pointer)

    问题: A linked list is given such that each node contains an additional random pointer which could poi ...

  3. 复制一个带random指针的链表

    一个单链表,其中除了next指针外,还有一个random指针,指向链表中的任意某个元素.如何复制这样一个链表呢? 通过next来复制一条链是很容易的,问题的难点在于如何恰当地设置新链表中的random ...

  4. [LeetCode] 138. Copy List with Random Pointer 拷贝带随机指针的链表

    A linked list is given such that each node contains an additional random pointer which could point t ...

  5. Qt中QObject中的parent参数

    今天写了一个小程序,验证了带参的构造函数中参数parent的作用. 在MainWindow中声明一个QDialog类型的指针,在MainWindow中对它进行初始化.我采用了两种初始化方式,一种是带参 ...

  6. 一篇文章带你吃透,Java界最神秘技术ClassLoader

    ClassLoader 是 Java 届最为神秘的技术之一,无数人被它伤透了脑筋,摸不清门道究竟在哪里.网上的文章也是一篇又一篇,经过本人的亲自鉴定,绝大部分内容都是在误导别人.本文我带读者彻底吃透 ...

  7. Pyqt 中__init__(self,parent==None) parent理解

    参考: 在PyQt中,所有class都是从QObject派生而来,QWidget对象就可以有一个parent.这种parent-child关系主要用于两个方面: 没有parent的QWidget类被认 ...

  8. C++ 带有指针成员的类处理方式

    在一个类中,如果类没有指针成员,一切方便,因为默认合成的析构函数会自动处理所有的内存.但是如果一个类带了指针成员,那么需要我们自己来写一个析构函数来管理内存.在<<c++ primer&g ...

  9. C++反汇编第三讲,反汇编中识别虚表指针,以及指向的虚函数地址

    C++反汇编第三讲,反汇编中识别虚表指针,以及指向的虚函数地址 讲解之前,了解下什么是虚函数,什么是虚表指针,了解下语法,(也算复习了) 开发知识为了不码字了,找了一篇介绍比较好的,这里我扣过来了,当 ...

随机推荐

  1. 使用Spring Boot Actuator、Jolokia和Grafana实现准实时监控

    由于最近在做监控方面的工作,因此也读了不少相关的经验分享.其中有这样一篇文章总结了一些基于Spring Boot的监控方案,因此翻译了一下,希望可以对大家有所帮助. 原文:Near real-time ...

  2. jdk下载以及配置

    http://jingyan.baidu.com/article/6dad5075d1dc40a123e36ea3.html

  3. 6.app架构基础

    app架构,一个听起来高大尚的名字,很多小伙伴听到这个词语感觉很迷茫,不知道架构具体说的是啥?在q群里,"app后端应该怎么架构"这个问题被问了无数次.通过阅读本文,根据本人提出的 ...

  4. spring的依赖注入是什么意思

    最近学习spring框架,对依赖注入有些模糊,遂上网翻阅资料,做了下列总结,原博客为CSDN 南夏的 spring的依赖注入是什么意思,侵删! Spring 能有效地组织J2EE应用各层的对象.不管是 ...

  5. java.util.ConcurrentModificationException异常的解决

    问题复现: List<String> list = new ArrayList<>();list.add("11");list.add("55&q ...

  6. 某校高中生利用Python,巧妙获取考试成绩,看到成绩后无言以对!

    Python是非常有吸引力的编程语言,学习Python的不是帅哥就是美女.为什么这么说呢?因为我和我的女朋友都是学习Python认识的,小编肯定是帅哥,不用去怀疑,而且我眼光特高. 给大伙讲一个故事, ...

  7. 树莓派.安装Firefox浏览器

    sudo apt-get install firefox-esr 要做全屏效果的话, 可以加装插件FF Fullscreen 插件地址: https://addons.mozilla.org/en-U ...

  8. JAVA经典算法40题(原题+分析)之分析

    JAVA经典算法40题(下) [程序1]   有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?   1.程序分析:  ...

  9. BZOJ_3879_SvT_后缀数组+单调栈

    BZOJ_3879_SvT_后缀数组+单调栈 Description (我并不想告诉你题目名字是什么鬼) 有一个长度为n的仅包含小写字母的字符串S,下标范围为[1,n]. 现在有若干组询问,对于每一个 ...

  10. b2OJ_1565_[NOI2009]植物大战僵尸_拓扑排序+最大权闭合子图

    b2OJ_1565_[NOI2009]植物大战僵尸_拓扑排序+最大权闭合子 题意:n*m个植物,每个植物有分数(可正可负),和能保护植物的位置.只能从右往左吃,并且不能吃正被保护着的,可以一个不吃,求 ...