给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。(Java语言实现)

简介: 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。(Java语言实现)

给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针(Java语言实现)


这是剑指Offer的题目,我的思路是这样的,就是把中序遍历的节点依次添加进ArrayList中,然后遍历ArrayList,找到目标节点的下一个节点就可以返回了,下面是我思路的代码实现。

package Day43;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
 * @Author Zhongger
 * @Description 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
 * @Date 2020.3.15
 */
public class GetNextSolution {
    public  List<TreeLinkNode> treeNodeArrayList = new ArrayList<>();
    public static void main(String[] args) {
        GetNextSolution getNextSolution = new GetNextSolution();
        TreeLinkNode root = new TreeLinkNode(8);
        TreeLinkNode node6 = new TreeLinkNode(6);
        TreeLinkNode node10 = new TreeLinkNode(10);
        TreeLinkNode node5 = new TreeLinkNode(5);
        TreeLinkNode node7 = new TreeLinkNode(7);
        TreeLinkNode node9 = new TreeLinkNode(9);
        TreeLinkNode node11 = new TreeLinkNode(11);
        root.left=node6;
        root.right=node10;
        node6.left=node5;
        node6.right=node7;
        node10.left=node9;
        node10.right=node11;
        System.out.println(getNextSolution.infixOrder(root));
        System.out.println(getNextSolution.GetNext(root));
    }
    public TreeLinkNode GetNext(TreeLinkNode pNode)
    {
        if (pNode==null){
            return null;
        }
        if (treeNodeArrayList.get(treeNodeArrayList.size()-1).val==pNode.val){//中序遍历序列中,pNode恰好是最后一个节点,那它的下一个节点就为空
            return null;
        }
        Iterator<TreeLinkNode> iterator = treeNodeArrayList.iterator();//迭代器
        while (iterator.hasNext()){
            TreeLinkNode next = iterator.next();
            if (next.val==pNode.val){//当前节点值与传入的节点值相同
                return iterator.next();
            }
        }
        return null;
    }
    public List<TreeLinkNode> infixOrder(TreeLinkNode root){//中序遍历
        if (root.left!=null){
            infixOrder(root.left);
        }
        System.out.println(root);
        treeNodeArrayList.add(root);
        if (root.right!=null){
            infixOrder(root.right);
        }
        return treeNodeArrayList;
    }
}
class TreeLinkNode {
    int val;
    TreeLinkNode left = null;
    TreeLinkNode right = null;
    TreeLinkNode next = null;
    TreeLinkNode(int val) {
        this.val = val;
    }
    @Override
    public String toString() {
        return "TreeLinkNode{" +
                "val=" + val +
                '}';
    }
}

我在自己的IDEA中调试过,输出的结果是没有问题的,但是在牛客网上提交,就通不过,例如下面这个测试用例:

image.png


但我在IDEA中调试的结果是:


image.png


显然是可以得到结果9的。实在没有办法,只能去评论区求助大佬,另外我还是不明白,节点类中的next指针有什么作用,它是指向当前节点的父节点的。这是能够通过的代码:

  public TreeLinkNode GetNext(TreeLinkNode pNode){
        if (pNode==null){
            return null;
        }
        if (pNode.right != null) {//当前节点有右子节点,那么当前节点的下一个节点就是它右子节点的最左子节点
            TreeLinkNode node = pNode.right;
            while (node.left != null)
                node = node.left;
            return node;  //找到了最左节点后,就把结果节点指向它,然后返回
        } else { //当前节点没有右子节点
            while (pNode.next != null) { //沿着父节点的指针遍历,直到找到一个节点成为它的父节点的左子节点
                TreeLinkNode parent = pNode.next;
                if (parent.left == pNode)
                    return parent;
                pNode = pNode.next;
            }
        }
        return null;
    }


通过刷题,我发现我还是太菜了点,想问题想得不够深入,没有利用到二叉树中序遍历的特征来进行求解。

相关文章
|
1月前
|
监控 Java API
如何使用Java语言快速开发一套智慧工地系统
使用Java开发智慧工地系统,采用Spring Cloud微服务架构和前后端分离设计,结合MySQL、MongoDB数据库及RESTful API,集成人脸识别、视频监控、设备与环境监测等功能模块,运用Spark/Flink处理大数据,ECharts/AntV G2实现数据可视化,确保系统安全与性能,采用敏捷开发模式,提供详尽文档与用户培训,支持云部署与容器化管理,快速构建高效、灵活的智慧工地解决方案。
|
1月前
|
SQL 安全 Java
安全问题已经成为软件开发中不可忽视的重要议题。对于使用Java语言开发的应用程序来说,安全性更是至关重要
在当今网络环境下,Java应用的安全性至关重要。本文深入探讨了Java安全编程的最佳实践,包括代码审查、输入验证、输出编码、访问控制和加密技术等,帮助开发者构建安全可靠的应用。通过掌握相关技术和工具,开发者可以有效防范安全威胁,确保应用的安全性。
52 4
|
1月前
|
存储 Java 开发者
在 Java 中,如何遍历一个 Set 集合?
【10月更文挑战第30天】开发者可以根据具体的需求和代码风格选择合适的遍历方式。增强for循环简洁直观,适用于大多数简单的遍历场景;迭代器则更加灵活,可在遍历过程中进行更多复杂的操作;而Lambda表达式和`forEach`方法则提供了一种更简洁的函数式编程风格的遍历方式。
|
2月前
|
Java 程序员 编译器
Java|如何正确地在遍历 List 时删除元素
从源码分析如何正确地在遍历 List 时删除元素。为什么有的写法会导致异常,而另一些不会。
39 3
|
2月前
|
Java 程序员 编译器
在Java编程中,保留字(如class、int、for等)是具有特定语法意义的预定义词汇,被语言本身占用,不能用作变量名、方法名或类名。
在Java编程中,保留字(如class、int、for等)是具有特定语法意义的预定义词汇,被语言本身占用,不能用作变量名、方法名或类名。本文通过示例详细解析了保留字的定义、作用及与自定义标识符的区别,帮助开发者避免因误用保留字而导致的编译错误,确保代码的正确性和可读性。
60 3
|
1月前
|
存储 C语言
C语言如何使用结构体和指针来操作动态分配的内存
在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
101 13
|
6月前
|
C语言
指针进阶(C语言终)
指针进阶(C语言终)
|
2月前
|
C语言
无头链表二级指针方式实现(C语言描述)
本文介绍了如何在C语言中使用二级指针实现无头链表,并提供了创建节点、插入、删除、查找、销毁链表等操作的函数实现,以及一个示例程序来演示这些操作。
36 0
|
3月前
|
存储 人工智能 C语言
C语言程序设计核心详解 第八章 指针超详细讲解_指针变量_二维数组指针_指向字符串指针
本文详细讲解了C语言中的指针,包括指针变量的定义与引用、指向数组及字符串的指针变量等。首先介绍了指针变量的基本概念和定义格式,随后通过多个示例展示了如何使用指针变量来操作普通变量、数组和字符串。文章还深入探讨了指向函数的指针变量以及指针数组的概念,并解释了空指针的意义和使用场景。通过丰富的代码示例和图形化展示,帮助读者更好地理解和掌握C语言中的指针知识。
128 4
|
4月前
|
C语言
【C初阶——指针5】鹏哥C语言系列文章,基本语法知识全面讲解——指针(5)
【C初阶——指针5】鹏哥C语言系列文章,基本语法知识全面讲解——指针(5)
下一篇
DataWorks