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

1.考点

  • 考点1:对于中序遍历的理解;(也要对此拓展到前序遍历与后序遍历)
  • 考点2:如何在一个二叉树中找到一个点的下一个点;(二叉树的结构理解)

2.思路

  • 二叉树的前中后序遍历中,每种的遍历方式不同,对于找到某一个点的下一个点或上一个点的问题,只需要绘制出二叉树图,然后假设某一点为某节点的左节点/右节点,以及假设其有左子树也有右子树,那么这个节点就是一个X型结构,这个X型节点根据所述的上一节点与下一节点来考虑,以中序遍历(左根右)的寻找为例:
2.1 寻找下一节点:若有左子树,则左子树必为上一节点,故不考虑
  • (1)若有右子树:则右子树必为下一节点;
  • (2)若没有右子树,但自身是父节点的左节点:则父节点必为下一节点;
  • (3)若没有右子树,但自身是父节点的右节点:沿着父节点往上找,直到找到那个自身是其父节点的左节点的点,取该节点的父节点作为下一节点;
  • (4)若什么都没有:节点只有一个,也就不存在什么下一节点了,返回NULL。
2.2 寻找上一节点:若有右子树,则右子树必为下一节点,故不考虑
  • (1)若有左子树:则左子树必为上一节点;
  • (2)若没有左子树,但自身是父节点的右节点:则父节点必为上一节点;
  • (3)若没有左子树,但自身是父节点的左节点:沿着父节点往上找,直到找到那个自身是其父节点的右节点的点,取该节点的父节点作为上一节点;
  • (4)若什么都没有:节点只有一个,也就不存在什么上一节点了,返回NULL。

3.代码

  • 代码实现的是寻找二叉树的下一节点(中序遍历)
#include <iostream>
using namespace std;

//这是牛客网的结构例子,next就是父节点
struct TreeLinkNode
{
	int val;
	struct TreeLinkNode *left;
	struct TreeLinkNode *right;
	struct TreeLinkNode *next;
	TreeLinkNode(int x) :val(x), left(NULL), right(NULL), next(NULL) {}
};

//牛客网3ms,内存380K
class Solution
{
public:
	TreeLinkNode* GetNext(TreeLinkNode* pNode)
	{
		if (pNode == NULL)
			return NULL;
		//1.先判断有无右子树,有则找到右子树的最左节点(注意最左节点定义,如果没有就使用右子树初始点)
		if (pNode->right != NULL)
		{
			pNode = pNode->right;
			while (pNode->left != NULL)
				pNode = pNode->left;
			return pNode;
		}
		//2.再判断自身是父节点的左节点还是右节点还是没有父节点
		else if (pNode->next != NULL)
		{
			//2.1如果自身是父节点左节点,则下任为父节点(后来发现2.1和2.2可以直接合并)
			if (pNode->next->left == pNode)
				return pNode->next;
			//2.2如果自身是父节点右节点,则下任为父节点往上的那个为其父节点的左节点的节点的父节点(这个逻辑仔细读,由于是二叉树,这个点有且只有一个)
			//具体的实现不断地判断自身是否为父节点的左节点,不是就替换直至找到或到父节点为NULL
			while (pNode->next != NULL && pNode != pNode->next->left)
				pNode = pNode->next;
			return pNode->next;
		}
		//3.最后这个没啥用,其实前面的不同情况都自己返回了
		return NULL;
	}
};

int main()
{
	TreeLinkNode * node1 = new TreeLinkNode(1);
	TreeLinkNode * node2 = new TreeLinkNode(2);
	TreeLinkNode * node3 = new TreeLinkNode(3);
	TreeLinkNode * node4 = new TreeLinkNode(4);
	node1->left = node2;
	node1->right = node3;
	node2->left = node4;
	node2->next = node1;
	node3->next = node1;
	node4->next = node2;

	Solution s;
	cout << s.GetNext(node4)->val << endl;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

方寸间沧海桑田

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值