给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。(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;
    }


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

相关文章
|
10月前
|
Java
Java语言实现字母大小写转换的方法
Java提供了多种灵活的方法来处理字符串中的字母大小写转换。根据具体需求,可以选择适合的方法来实现。在大多数情况下,使用 String类或 Character类的方法已经足够。但是,在需要更复杂的逻辑或处理非常规字符集时,可以通过字符流或手动遍历字符串来实现更精细的控制。
578 18
|
10月前
|
存储 Java 索引
用Java语言实现一个自定义的ArrayList类
自定义MyArrayList类模拟Java ArrayList核心功能,支持泛型、动态扩容(1.5倍)、增删改查及越界检查,底层用Object数组实现,适合学习动态数组原理。
430 4
|
11月前
|
存储 Java Apache
Java语言操作INI配置文件策略
以上步骤展示了基本策略,在实际项目中可能需要根据具体需求进行调整优化。例如,在多线程环境中操作同一份配置时需要考虑线程安全问题;大型项目可能还需考虑性能问题等等。
399 15
|
算法 Java
Java语言实现链表反转的方法
这种反转方法不需要使用额外的存储空间,因此空间复杂度为,它只需要遍历一次链表,所以时间复杂度为,其中为链表的长度。这使得这种反转链表的方法既高效又实用。
709 0
指针进阶(C语言终)
指针进阶(C语言终)
|
存储 C语言
C语言如何使用结构体和指针来操作动态分配的内存
在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
2157 13
|
存储 人工智能 C语言
C语言程序设计核心详解 第八章 指针超详细讲解_指针变量_二维数组指针_指向字符串指针
本文详细讲解了C语言中的指针,包括指针变量的定义与引用、指向数组及字符串的指针变量等。首先介绍了指针变量的基本概念和定义格式,随后通过多个示例展示了如何使用指针变量来操作普通变量、数组和字符串。文章还深入探讨了指向函数的指针变量以及指针数组的概念,并解释了空指针的意义和使用场景。通过丰富的代码示例和图形化展示,帮助读者更好地理解和掌握C语言中的指针知识。
983 4
|
C语言
无头链表二级指针方式实现(C语言描述)
本文介绍了如何在C语言中使用二级指针实现无头链表,并提供了创建节点、插入、删除、查找、销毁链表等操作的函数实现,以及一个示例程序来演示这些操作。
302 0
|
编译器 C语言
【C语言初阶】指针篇—下
【C语言初阶】指针篇—下
|
存储 C语言
【C语言初阶】指针篇—上
【C语言初阶】指针篇—上