【剑指Offer学习】【面试题58:二叉树的下一个结点】
题目:给定一棵二叉树和当中的一个结点。怎样找出中序遍历顺序的下一个结点?树中的结点除了有两个分别指向左右子结点的指针以外,另一个指向父节点的指针。
解题思路
  假设一个结点有右子树。那么它的下一个结点就是它的右子树中的左子结点。也就是说右子结点出发一直沿着指向左子结点的指针。我们就能找到它的下一个结点。 
  接着我们分析一个结点没有右子树的情形。
假设结点是它父节点的左子结点。那么它的下一个结点就是它的父结点。 
  假设一个结点既没有右子树。而且它还是它父结点的右子结点。这种情形就比較复杂。我们能够沿着指向父节点的指针一直向上遍历,直到找到一个是它父结点的左子结点的结点。假设这种结点存在。那么这个结点的父结点就是我们要找的下一个结点。
结点定义
private static class BinaryTreeNode {
    private int val;
    private BinaryTreeNode left;
    private BinaryTreeNode right;
    private BinaryTreeNode parent;
    public BinaryTreeNode() {
    }
    public BinaryTreeNode(int val) {
        this.val = val;
    }
    @Override
    public String toString() {
        return val + "";
    }
}代码实现
public class Test58 {
    private static class BinaryTreeNode {
        private int val;
        private BinaryTreeNode left;
        private BinaryTreeNode right;
        private BinaryTreeNode parent;
        public BinaryTreeNode() {
        }
        public BinaryTreeNode(int val) {
            this.val = val;
        }
        @Override
        public String toString() {
            return val + "";
        }
    }
    public static BinaryTreeNode getNext(BinaryTreeNode node) {
        if (node == null) {
            return null;
        }
        // 保存要查找的下一个节点
        BinaryTreeNode target = null;
        if (node.right != null) {
            target = node.right;
            while (target.left != null) {
                target = target.left;
            }
            return target;
        } else if (node.parent != null){
            target = node.parent;
            BinaryTreeNode cur = node;
            // 假设父新结点不为空。而且。子结点不是父结点的左孩子
            while (target != null && target.left != cur) {
                cur = target;
                target = target.parent;
            }
            return target;
        }
        return null;
    }
    private static void assemble(BinaryTreeNode node,
                                 BinaryTreeNode left,
                                 BinaryTreeNode right,
                                 BinaryTreeNode parent) {
        node.left = left;
        node.right = right;
        node.parent = parent;
    }
    public static void main(String[] args) {
        test01();
    }
    //                            1
    //                  2                   3
    //             4         5          6          7
    //          8     9   10   11   12   13    14   15
    public static void test01() {
        BinaryTreeNode n1 = new BinaryTreeNode(1); // 12
        BinaryTreeNode n2 = new BinaryTreeNode(2); // 10
        BinaryTreeNode n3 = new BinaryTreeNode(3); // 14
        BinaryTreeNode n4 = new BinaryTreeNode(4); // 9
        BinaryTreeNode n5 = new BinaryTreeNode(5); // 11
        BinaryTreeNode n6 = new BinaryTreeNode(6); // 13
        BinaryTreeNode n7 = new BinaryTreeNode(7); // 15
        BinaryTreeNode n8 = new BinaryTreeNode(8); // 4
        BinaryTreeNode n9 = new BinaryTreeNode(9); // 2
        BinaryTreeNode n10 = new BinaryTreeNode(10); // 5
        BinaryTreeNode n11 = new BinaryTreeNode(11); // 1
        BinaryTreeNode n12 = new BinaryTreeNode(12); // 6
        BinaryTreeNode n13 = new BinaryTreeNode(13); // 3
        BinaryTreeNode n14 = new BinaryTreeNode(14); // 7
        BinaryTreeNode n15 = new BinaryTreeNode(15); // null
        assemble(n1, n2, n3, null);
        assemble(n2, n4, n5, n1);
        assemble(n3, n6, n7, n1);
        assemble(n4, n8, n9, n2);
        assemble(n5, n10, n11, n2);
        assemble(n6, n12, n13, n3);
        assemble(n7, n14, n15, n3);
        assemble(n8, null, null, n4);
        assemble(n9, null, null, n4);
        assemble(n10, null, null, n5);
        assemble(n11, null, null, n5);
        assemble(n12, null, null, n6);
        assemble(n13, null, null, n6);
        assemble(n14, null, null, n7);
        assemble(n15, null, null, n7);
        System.out.println(getNext(n1));
        System.out.println(getNext(n2));
        System.out.println(getNext(n3));
        System.out.println(getNext(n4));
        System.out.println(getNext(n5));
        System.out.println(getNext(n6));
        System.out.println(getNext(n7));
        System.out.println(getNext(n8));
        System.out.println(getNext(n9));
        System.out.println(getNext(n10));
        System.out.println(getNext(n11));
        System.out.println(getNext(n12));
        System.out.println(getNext(n13));
        System.out.println(getNext(n14));
        System.out.println(getNext(n15));
    }
}执行结果
【剑指Offer学习】【面试题58:二叉树的下一个结点】的更多相关文章
- 【剑指offer】面试题 8. 二叉树的下一个结点
		面试题 8. 二叉树的下一个结点 NowCoder 题目描述 给定一棵二叉树和其中的一个结点,如何找出中序遍历顺序的下一个结点?树中的结点除了有两个分别指向左右子结点的指针以外,还有一个指向父结点的指 ... 
- 剑指Offer(书):二叉树的下一个节点
		题目:给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回.注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针. 分析:若一个节点有右子树,那么他的下一个节点就是他右子树中 ... 
- 剑指offer笔记面试题8----二叉树的下一个节点
		题目:给定一棵二叉树和其中的一个节点,如何找出中序遍历序列的下一个节点?树中的节点除了有两个分别指向左.右子节点的指针,还有一个指向父节点的指针. 测试用例: 普通二叉树(完全二叉树,不完全二叉树). ... 
- 《剑指offer》面试题39 二叉树的深度(java)
		摘要: 今天翻到了<剑指offer>面试题39,题目二中的解法二是在函数的参数列表中通过指针的方式进行传值,而java是没有指针的,所以函数要进行改造.然而我翻了下别人的java版本(我就 ... 
- (剑指Offer)面试题58:二叉树的下一个结点
		题目: 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回.注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针. 思路: 考虑中序遍历的过程, 如果当前结点存在右子节点, ... 
- 【剑指Offer】58:二叉树的下一个结点
		题目描述 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回.注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针. 题解一:递归 //既然给了二叉树的某个结点,且二叉树存 ... 
- 【剑指offer】面试题 55. 二叉树的深度
		面试题 55. 二叉树的深度 题目一:二叉树的深度 题目描述:输入一棵二叉树,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度. Java 实现 ... 
- 《剑指Offer》面试题-重建二叉树
		题目描述: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7 ... 
- 《剑指offer》面试题25 二叉树中和为某一值的路径 Java版
		(判断是否有从根到叶子节点的路径,其和为给定值.记录这些路径.) 我的方法:这道题我是按照回溯的思路去做的,我们需要一个数据结构来保存和删除当前递归函数中添加的值.这里要打印一条路径,我们可以选择Li ... 
- 《剑指offer》面试题19 二叉树的镜像 Java版
		书中方法:这道题目可能拿到手没有思路,我们可以在纸上画出简单的二叉树来找到规律.最后我们发现,镜像的实质是对于二叉树的所有节点,交换其左右子节点.搞清楚获得镜像的方法,这道题实际上就变成了一道二叉树遍 ... 
随机推荐
- javascript 之 className属性
			Javascript 可以通过className 属性灵活的更改一个标签元素的CSS 类选择器来实现样式的变化. 1.用className 属性修改节点的css类别 代码如下: <html> ... 
- 属性动画详解一(Property Animation)
			效果图: Android动画有3类: 1.View Animation (Tween Animation) 2.Drawable Animation (Frame Animation) 2.Prope ... 
- hdu 3072 有向图缩点成最小树形图计算最小权
			题意,从0点出发,遍历所有点,遍历边时候要付出代价,在一个SCC中的边不要付费.求最小费用. 有向图缩点(无需建立新图,,n<=50000,建则超时),遍历边,若不在一个SCC中,用一个数组更新 ... 
- 牛客网 牛客小白月赛2 C.真真假假-String遍历比较
			C.真真假假 链接:https://www.nowcoder.com/acm/contest/86/C 这个题真的是无敌的水,但是自己写前面的string数组的时候,里面的这些头文件要用双引号(&qu ... 
- (17)python Beautiful Soup 4.6
			一.安装 1.登陆官网:https://www.crummy.com/software/BeautifulSoup/ 2.下载 3.解压 4.安装 cmd找到文件路径,运行 setup.py buil ... 
- ECNU 3480 没用的函数 (ST表预处理 + GCD性质)
			题目链接 ECNU 2018 JAN Problem E 这题卡了双$log$的做法 令$gcd(a_{i}, a_{i+1}, a_{i+2}, ..., a_{j}) = calc(i, j)$ ... 
- POJ 2484 A Funny Game [博弈]
			题意:n枚硬币围成一个圈,每次每个人可以从中取走一枚或者相邻的两枚(如果两枚硬币原本中间隔着一枚硬币,后来被取走,这两枚硬币不算相邻).谁取走最后一枚硬币谁就赢了. 思路:我们可以找找规律. 首先,n ... 
- Java线程池ThreadPoolExecutor类源码分析
			前面我们在java线程池ThreadPoolExecutor类使用详解中对ThreadPoolExector线程池类的使用进行了详细阐述,这篇文章我们对其具体的源码进行一下分析和总结: 首先我们看下T ... 
- Using Find_Alert and Show_Alert in Oracle Forms
			Show_alert is used to display model window messages in Oracle Forms and Find_alert searches the list ... 
- 在线更新dede程序后 网站出现错误 DedeCMS Error:Tag disabled:"php" more...!
			dedecms出现DedeCMS Error:Tag disabled:php原因解决 ------------------------------------------------------- ... 
