经典算法题-基础-寻找二叉树的下一个节点

Posted shellmad

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了经典算法题-基础-寻找二叉树的下一个节点相关的知识,希望对你有一定的参考价值。

问题描述

题目描述
给定一个二叉树和其中的一个结点,请找出中序遍历中的下一个结点并且返回

要求
时间限制:1秒 空间限制:32768K

方法原型

public TreeNode getNext(TreeNode treeNode)
public class TreeNode {
    int val;
    TreeNode left = null;
    TreeNode right = null;
    TreeNode parent = null;
    TreeNode(int val) { this.val = val;}
}

分析思路

二叉树的中序遍历对学习过数据结构的人都不陌生,即先递归访问当前树节点的左子树,再访问当前节点,然后递归访问右子树。
比如对于二叉树:
技术图片

其中序遍历的结果为:
4, 2, 8, 5, 9, 1, 6, 3, 7

对于任意一个节点,要找到其中序遍历中的下一个节点,我们可以分情况讨论,一共三种情况:

  • 当前节点有右子树:如上图中的1,3,2,5
  • 当前节点没有右子树,且是父节点的左孩子:如上图中的4,6,8
  • 当前节点没有右子树,且是父节点的右孩子:如上图中的9,7

对于这三种,找出它们下一个节点的方法分别是:

当前节点有右子树

下一个节点是该右子树中的最左元素
如上图中的1的下一个节点是6,相关的伪代码为:

If(node.right != null) {
     node = node.right;
     while(node.left != null){
      node = node.left;
     }
      next = node
}

当前节点没有右子树,且是父节点的左孩子

父节点就是下一个节点。如下图中的元素4,其下一个节点是2.
技术图片

相关的伪代码如下:

if(node.parent != null && node.parent.left == node) {
 next = node.parent
}

当前节点没有右子树,且是父节点的右孩子

这种情况下,需要往根回溯,如果遇到某个节点是作为左孩子存在,则那个节点的父节点就是我们要找的下一个元素。
技术图片

如图中的9号元素,从它开始往根回溯,当遇到2时,2是作为1的左孩子存在,那么1就是我们要找寻的“下一个”元素。
以下动图体现找寻过程:
技术图片

当然,也可能存在我们直到遍历到根也没有发现作为左孩子存在的元素,那说明当前节点已经是最后一个,没有下一个节点存在。
相关伪代码如下:

while(node.parent != null) {
        node = node.parent;
        if(node = node.parent.left){
               next = node.parent;
                return;
         }
}

相关代码

以上思路的JAVA版本实现如下:

package com.shellmad;

public class Solution {

    public static void main(String[] args) {
        TreeNode node1 = new TreeNode(1);
        TreeNode node2 = new TreeNode(2);
        TreeNode node3 = new TreeNode(3);
        TreeNode node4 = new TreeNode(4);
        TreeNode node5 = new TreeNode(5);
        TreeNode node6 = new TreeNode(6);
        TreeNode node7 = new TreeNode(7);
        TreeNode node8 = new TreeNode(8);
        TreeNode node9 = new TreeNode(9);
        node1.left = node2;
        node1.right = node3;
        node2.left = node4;
        node2.right = node5;
        node5.left = node8;
        node5.right = node9;
        node3.left = node6;
        node3.right = node7;
        node2.parent = node1;
        node3.parent = node1;
        node4.parent = node2;
        node5.parent = node2;
        node8.parent = node5;
        node9.parent = node5;
        node6.parent = node3;
        node7.parent = node3;
        Solution solution = new Solution();
        TreeNode node = null;

        node = solution.getNext(node1);
        if (node != null) {
            System.out.println(node.val);
        } else {
            System.out.println("没有下一个节点");
        }

        node = solution.getNext(node2);
        if (node != null) {
            System.out.println(node.val);
        } else {
            System.out.println("没有下一个节点");
        }

        node = solution.getNext(node3);
        if (node != null) {
            System.out.println(node.val);
        } else {
            System.out.println("没有下一个节点");
        }

        node = solution.getNext(node4);
        if (node != null) {
            System.out.println(node.val);
        } else {
            System.out.println("没有下一个节点");
        }

        node = solution.getNext(node5);
        if (node != null) {
            System.out.println(node.val);
        } else {
            System.out.println("没有下一个节点");
        }

        node = solution.getNext(node6);
        if (node != null) {
            System.out.println(node.val);
        } else {
            System.out.println("没有下一个节点");
        }

        node = solution.getNext(node7);
        if (node != null) {
            System.out.println(node.val);
        } else {
            System.out.println("没有下一个节点");
        }

        node = solution.getNext(node8);
        if (node != null) {
            System.out.println(node.val);
        } else {
            System.out.println("没有下一个节点");
        }

        node = solution.getNext(node9);
        if (node != null) {
            System.out.println(node.val);
        } else {
            System.out.println("没有下一个节点");
        }
    }

    public TreeNode getNext(TreeNode treeNode) {
        // 检查节点是否为空
        if (treeNode == null) {
            return null;
        }

        // 处理情况1,当前节点有右子树
        if (treeNode.right != null) {
            treeNode = treeNode.right;
            while (treeNode.left != null) {
                treeNode = treeNode.left;
            }
            return treeNode;
        }

        // 处理情况2和3
        while (treeNode.parent != null) {
            if (treeNode == treeNode.parent.left) {
                return treeNode.parent;
            }
            treeNode = treeNode.parent;

        }

        return null;
    }
}


class TreeNode {
    int val;
    TreeNode left = null;
    TreeNode right = null;
    TreeNode parent = null;
    TreeNode(int val) {
        this.val = val;
    }
}

以上是关于经典算法题-基础-寻找二叉树的下一个节点的主要内容,如果未能解决你的问题,请参考以下文章

算法题之求二叉树的最大距离

[ 剑指offer ] 面试题8:二叉树的下一个节点

面试题:二叉树的下一个节点

面试题8:二叉树的下一个节点

面试题8:二叉树的下一个节点

剑指Offer - 面试题8:二叉树的下一个节点