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

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

// 题目:给定一棵二叉树和其中的一个结点,如何找出中序遍历顺序的下一个结点?

// 树中的结点除了有两个分别指向左右子结点的指针以外,还有一个指向父结点的指针。

// 二叉树的结构体定义如下。

struct BinaryTreeNode
{
    int                    m_nValue;
    BinaryTreeNode*        m_pLeft;
    BinaryTreeNode*        m_pRight;
    BinaryTreeNode*        m_pParent;
};

解题思路:

以上图为例,节点有没有左子树不影响,因为左子树肯定会在节点之前被遍历。

如果输入节点有右子树,比如根节点a有右子树c,但是节点c可能是其他左子树的根节点,所以中序遍历不能选择c。

应该从c的左子树一条路走到黑,走到叶结点为止,这样才是中序遍历节点a的下一个节点。

如果输入节点没有右子树,遍历之后应该继续向上遍历(如果父节点存在的话)。

  如果节点是上一级节点的左子树,说明上一级节点是目前的根节点,下一个应该遍历它,比如节点h之后应遍历e。

  如果节点是上一级节点的右子树,说明这一个小区域的中序遍历已完成,应该沿右子树一直向上回溯。

  比如i节点一直回溯到b节点,b节点及b的子树都已经作为a的左子树被遍历完成,下一个就应该遍历b的父节点a。

不知道我有没有写明白,语言表述能力不太好,大概就是那么个意思。

伪代码:

BinaryTreeNode GetNext(BinaryTreeNode* pNode){
    if(pNode==nullptr)
        return nullptr;

    if(pNode拥有右子树pRight){
        while(pRight左子树不为空){
            pRight=pRight的左子树;
        }
    return pRight;
    }
    else if(pNode是父节点右子树){
        while(pNode父节点pParent是上一级节点的右子树){
            pParent=pParent的父节点;
        }
        return pParent的父节点;
    }
    else{
        return pNode的父节点;
    }
}

c/c++:

作者的代码是做了一些优化的,pNode是上一级节点的右子树/左子树的公共代码被提出来了,我还是看了两分钟才想明白,太菜了。。

BinaryTreeNode* GetNext(BinaryTreeNode* pNode) {
	//校验参数有效性
	if (pNode == nullptr)
		return nullptr;

	BinaryTreeNode* pNext = nullptr;
	//pNode拥有右子树
	if (pNode->m_pRight != nullptr) {
		BinaryTreeNode* pRight = pNode -> m_pRight;
		while (pRight->m_pLeft != nullptr)
			pRight = pRight->m_pLeft;

		pNext = pRight;
	}
	//pNode没有右子树
	else if(pNode->m_pParent!=nullptr){
		BinaryTreeNode* pCurrent = pNode;
		BinaryTreeNode* pParent = pNode->m_pParent;
		//pNode是父节点的右子树
		while (pParent != nullptr&&pCurrent == pParent->m_pRight) {
			pCurrent = pParent;
			pParent = pParent->m_pParent;
		}
		//pNode是父节点的左子树,直接向上遍历
		pNext = pParent;
	}
	return pNext;
}

参考资料:

剑指offer第二版面试题8

原文地址:https://www.cnblogs.com/BoqianLiu/p/9427150.html

时间: 2024-10-28 15:28:50

面试题8:二叉树的下一个结点的相关文章

【剑指offer】面试题 8. 二叉树的下一个结点

面试题 8. 二叉树的下一个结点 NowCoder 题目描述 给定一棵二叉树和其中的一个结点,如何找出中序遍历顺序的下一个结点?树中的结点除了有两个分别指向左右子结点的指针以外,还有一个指向父结点的指针. Java 实现 略 原文地址:https://www.cnblogs.com/hglibin/p/10930092.html

二叉树的下一个结点-剑指Offer

二叉树的下一个结点 题目描述 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回.注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针. 思路 当该结点有右子树时,下一个结点就是右子树中最左的那个结点 当该结点没有右子树,而且是父节点的左子树,那下一个结点就是父节点 当该结点没有右子树,而且是父节点的右子树,那就向上寻找直到是某个父节点的左子树,然后改父节点就是下一个结点,如果找到根节点还没有找到满足条件的父节点,那就是没有下一个结点 代码 /* public cla

【Java】 剑指offer(7) 二叉树的下一个结点

本文参考自<剑指offer>一书,代码采用Java语言. 题目 给定一棵二叉树和其中的一个结点,如何找出中序遍历顺序的下一个结点? 树中的结点除了有两个分别指向左右子结点的指针以外,还有一个指向父结点的指针. 思路 首先自己在草稿纸上画图,进行分析(不再展开).可以发现下一个结点的规律为: 1.若当前结点有右子树时,其下一个结点为右子树中最左子结点: 2.若当前结点无右子树时, (1)若当前结点为其父结点的左子结点时,其下一个结点为其父结点: (2)若当前结点为其父结点的右子结点时,继续向上遍

55、二叉树的下一个结点

一.题目 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回.注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针. 二.解法 1 /* 2 public class TreeLinkNode { 3 int val; 4 TreeLinkNode left = null; 5 TreeLinkNode right = null; 6 TreeLinkNode next = null; 7 8 TreeLinkNode(int val) { 9 this.val =

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

题目描述 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回.注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针. 思路: 1)如果一个节点有右子树,那么它的下一个结点就是它的右子树中的最左子节点: 2)如果一个节点没有右子树,并且它还是它父节点的右子节点,我们可以沿着指向父节点的指针一直向上遍历,知道找到一个是它父节点的右子节点的左子节点的节点,就是第一个向右转的子部分根节点. /* struct TreeLinkNode { int val; struct Tr

《剑指offer》:[58]二叉树的下一个结点

题目:给定一棵二叉树和其中一个结点,如何找出中序遍历顺序的下一个结点?树中的结点除了有两个分别指向左右子结点的指针外,还有一个指向父节点的指针. 分析:这里已经说了是中序遍历,所以我们就以中序遍历为例.由于是二叉树,所以有三种情况: (1)如果如果一个结点有右子树,那么它的下一个结点就是它的右子树中最左子节点.也就是说从右子节点出发一直沿着指向左子结点的指针,我们就能找到它的 下一个结点. (2)如果这个结点没有右子树,如果结点是它父节点的左子树,则它的下一个结点就是它的父节点. (3)如果一个

剑指offer(五十七)之二叉树的下一个结点

题目描述 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回.注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针. 代码: <span style="color:#000099;">/* public class TreeLinkNode { int val; TreeLinkNode left = null; TreeLinkNode right = null; TreeLinkNode next = null; TreeLinkNode(i

剑指Offer——二叉树的下一个结点

题目描述: 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回.注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针. 分析: 如果该结点存在右子树,那么返回右子树的最左结点. 如果该结点不存在右子树,那么如果该结点不是其父结点的最右结点,那么返回父结点:否则一直找到最大子树的最右结点是该结点,那么返回该最大子树的根结点的父结点. 代码: 1 /* 2 struct TreeLinkNode { 3 int val; 4 struct TreeLinkNode *le

57二叉树的下一个结点

题目描述 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回.注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针. 思路: 如果一个节点有右子树,那么他的下一个节点就是它的右子树中的最左节点. 如果一个节点没有右子树,如果节点是它父节点的左子节点,那么它的下一个节点就是它的父节点. 如果一个节点即没有右子树,并且它还是它父节点的右子节点,我们可以沿着指向父节点的指针一直向上遍历,直到找到一个是他父节点的左子节点的节点. 1 /* 2 public class Tre