剑指offer刷题-二叉树的下一个结点

题目描述

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

思路:

PS:

中序遍历首先处理左子树,然后是当前结点,最后是右子树
先序遍历先处理当前结点,再处理左右子结点
后序遍历先处理处理左右子结点,再处理当前结点

在这里插入图片描述
如上图,中序遍历的顺序为:d-b-h-e-i-a-f-c-g

1、如果当前结点有右子树,即找到右子树的最左子树。直到左子树为空,则为当前结点。

例如对于a,下一个结点为f;对于b,下一个结点为h。

2、若当前结点没有左右子结点,则需判断当前结点与父节点的关系。

  1. 父节点不存在,则返回null;
  2. 当前结点为父节点的左子节点,则下一个结点就是父节点;
  3. 当前结点为父节点的右子节点,情况较为复杂。
    需要不断向上查询,直到找到当前节点作为父节点的左子结点,此时的父节点即为下一个结点。
    如果一直查找不到,则下一个节点为null。
    例如为了找到g的下一个结点,不断向上找父节点,发现没有作为左子结点的结点,则下一个为Null。
    而对于节点 i,不断向上找父节点,直到找到结点 a,结点b是结点a 的左子结点,所以b 是下一个结点。

实现代码:

小白版本

public class Solution {
    public TreeLinkNode GetNext(TreeLinkNode pNode)
    {
        while(pNode != null)
        {
            //如果没有右子树
            if(pNode.right == null)
            {
                //为父节点的左结点,则下一个为父节点
                if(pNode.next != null && pNode == pNode.next.left)
                {
                    return pNode.next;
                }
                //为父节点的右节点,较为复杂
                else if(pNode.next != null && pNode == pNode.next.right)
                {
                    //找到作为左子节点的父节点
                    while(pNode.next != null)
                    {
                        while(pNode == pNode.next.left)
                        {
                            return pNode.next;
                        }
                        pNode = pNode.next;
                    }
                    //找不到则为null
                    return null;
                }
                //没有父节点
                else
                    return null;
            }
            //如果有右子树
            else
            {
                //找到最左子树
                while(pNode.right.left != null)
                {
                    pNode.right = pNode.right.left;
                }
                //直到找不到左子树,即当前结点
                return pNode.right;
            }
        }
        return null;
    }
}

大牛版本:

public class Solution {    
	public TreeLinkNode GetNext(TreeLinkNode node)    
	{        
		if(node==null)
			return null;        
		if(node.right!=null)        
		{       //有右子树
			node=node.right;            
			while(node.left!=null)            
			{                
				node=node.left;                           
			}
			return node;        
		}        
		while(node.next!=null)       
		{            
			//父节点
			if(node.next.left==node)
				return node.next;            
			node=node.next;        
		}        
		return null;    
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值