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

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

#include<iostream>
#include<string>
using namespace std;

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

BinaryTreeNode* GetNext(BinaryTreeNode* pNode)
{
	BinaryTreeNode* pNext = nullptr;
	if(pNode->m_pRight != nullptr)  //当前节点存在右子树
	{
		BinaryTreeNode* pRight = pNode->m_pRight;
		while(pRight->m_pLeft != nullptr)  //直接遍历到右子树的最左节点
			pRight = pRight->m_pLeft;

		pNext = pRight;  //右子树的最左节点就是中序遍历pNode的下一个节点pNext
	}
	else if(pNode->m_pParent != nullptr)  //当前节点没有右子树
	{
		BinaryTreeNode* pCurrent = pNode;
		BinaryTreeNode* pParent = pNode->m_pParent;
		while(pParent != nullptr && pCurrent == pParent->m_pRight)  //该节点是其父节点的右子节点向上遍历
		{
			pCurrent = pParent;
			pParent = pParent->m_pParent;
		}
		pNext = pParent;
	}
	return pNext;
}

BinaryTreeNode* createNode(string value, BinaryTreeNode* parent = nullptr)  //创建二叉树
{
    BinaryTreeNode* newNode = new BinaryTreeNode;
	newNode->m_nValue = value;
	newNode->m_pLeft = nullptr;
	newNode->m_pRight = nullptr;
	newNode->m_pParent = parent;
    return newNode;
}

BinaryTreeNode* findNodeWithValue(BinaryTreeNode* root, string value)
{
    if (root == nullptr)
	{
        return nullptr;
    }

    if (root->m_nValue == value)
	{
        return root;  // 找到目标节点
    }
   
    BinaryTreeNode* leftResult = findNodeWithValue(root->m_pLeft, value);  //递归在左子树中查找
	if (leftResult != nullptr)
    {
        return leftResult;  //如果在左子树找到了目标节点,则直接返回
    }
    BinaryTreeNode* rightResult = findNodeWithValue(root->m_pRight, value);  //递归在右子树中查找
	return rightResult;
}

void deleteBinaryTree(BinaryTreeNode* root)
{
    if (root == nullptr)
    {
        return;
    }

	if (root->m_pLeft != nullptr)  //递归删除左子树
    {
        deleteBinaryTree(root->m_pLeft);
    }
    if (root->m_pRight != nullptr)  //递归删除右子树
    {
        deleteBinaryTree(root->m_pRight);
    }

    delete root;
}

int main()
{
	BinaryTreeNode* root = createNode("a");
	root->m_pLeft = createNode("b", root);
	root->m_pLeft->m_pLeft = createNode("d", root->m_pLeft);
	root->m_pLeft->m_pRight = createNode("e", root->m_pLeft);
	root->m_pLeft->m_pRight->m_pLeft = createNode("h", root->m_pLeft->m_pRight);
	root->m_pLeft->m_pRight->m_pRight = createNode("i", root->m_pLeft->m_pRight);
	root->m_pRight = createNode("c", root);
	root->m_pRight->m_pLeft = createNode("f", root->m_pRight);
	root->m_pRight->m_pRight = createNode("g", root->m_pRight);

	string targetValue = "d";
	BinaryTreeNode* targetNode = findNodeWithValue(root, targetValue);
	if (targetNode != nullptr) 
	{
		BinaryTreeNode* pNext = GetNext(targetNode);
    	if (pNext != nullptr) 
		{
        	cout << "给定目标节点值: " << targetNode->m_nValue << "; 中序遍历的下一个节点: " << pNext->m_nValue << endl;
    	} 
		else 
		{
        	cout << "给定目标节点值: " << targetNode->m_nValue << "; 该目标节点为中序遍历最后一个节点" << endl;
    	}
	} 
	else 
	{
		cout << "给定目标节点值: " << targetValue << "; 此二叉树内没有该值" << endl;
	}

	deleteBinaryTree(root);
    return 0;
}

解题思路:根据中序遍历左根右的特点,1.当一个节点有右子树:则它的下一个节点就是它的右子树中最左节点;2.当一个节点没有右子树:(1)节点是其父节点的左子节点,则下一个节点是该父节点;(2)节点是其父节点的右子节点,沿着指向父节点指针向上遍历,直到找到一个是它父节点的左子节点的节点,如果存在,这个节点的父节点就是下一个节点。由于最开始没有定义父指针,导致输出错误。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值