剑指Offer-题8(Java版):在中序遍历中,求二叉树的下一个节点

参考自:《剑指Offer——名企面试官精讲典型编程题》

题目:在中序遍历中,求二叉树的下一个节点
给定一棵二叉树和其中的一个节点,如何找出中序遍历顺序的下一个节点?树中的结点除了有两个分别指向左右子节点的指针以外,还有一个指向父节点的指针。

主要思路:
分三种情况:
1.该节点的右子树非空:它的下一节点就是右子树的最左节点。
2.该节点的右子树为空,但是它是其父节点的左节点:下一节点就是其父节点。
3.该节点的右子树为空,但是它是其父节点的右节点:沿着指向父节点的指针一直向上遍历,直到找到一个节点A,A是其父节点的左节点(A==A.parent.left),那么A.parent(A的父节点)就是所求的下一个节点。
若三种情况都不满足,则下一个节点为空。

关键点:中序遍历的特点:先左节点,再父节点,最后右节点

时间复杂度:O(树高度)

public class NextTreeNode
{
    public static void main(String[] args)
    {
//          10
//         /
//        6
//       /\
//      4  8
        TreeLinkNode node8 = getTree();
        TreeLinkNode next = getNextNodeFromInorder(node8);
        System.out.println(next.val); //10
    }

    private static TreeLinkNode getTree()
    {
        TreeLinkNode root = new TreeLinkNode(10);
        TreeLinkNode node6 = new TreeLinkNode(6);
        TreeLinkNode node4 = new TreeLinkNode(4);
        TreeLinkNode node8 = new TreeLinkNode(8);
        root.left = node6;
        node6.parent = root;
        node6.left = node4;
        node4.parent = node6;
        node6.right = node8;
        node8.parent = node6;
        return node8;
    }

    /**
     * 二叉树的下一个结点(中序遍历)
     * @param pNode
     * @return
     */
    public static TreeLinkNode getNextNodeFromInorder(TreeLinkNode pNode)
    {
        if (pNode == null) return null;
        //当前节点右子树非空,则查找右子树的最左子节点
        if (pNode.right != null)
        {
            return rightIsNotNull(pNode);
        } else if (pNode.parent != null)  //右子树为空,父节点非空
        {
            return rightIsNull(pNode);
        }
        return null;
    }

    //右子树非空
    private static TreeLinkNode rightIsNotNull(TreeLinkNode pNode)
    {
        TreeLinkNode right = pNode.right;
        //查找最左子节点
        while (right.left != null)
        {
            right = right.left;
        }
        return right;
    }

    //右子树为空,父节点非空
    private static TreeLinkNode rightIsNull(TreeLinkNode pNode)
    {
        TreeLinkNode current = pNode;
        TreeLinkNode parent = pNode.parent;
        //沿着指向父节点的指针一直向上遍历,直到找到一个节点current,
        //current是其父节点的左节点(current==parent.left),则退出循环
        while (parent != null && current == parent.right)
        {
            current = parent;
            parent = parent.parent;
        }
        return parent;
    }
}

class TreeLinkNode
{
    int val;
    TreeLinkNode left = null;
    TreeLinkNode right = null;
    TreeLinkNode parent = null; //父节点

    TreeLinkNode(int val)
    {
        this.val = val;
    }
}

猜你喜欢

转载自blog.csdn.net/m0_37862405/article/details/80068963