【剑指Offer-二叉树】面试题8:二叉树的下一个节点
题目描述
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
思路1
二叉树的中序遍历顺序为:左孩子,根,右孩子。而一个节点也只会有3种情况:该节点是其父节点的左孩子;该节点是其父节点的右孩子;该节点无父节点,是根节点。根据是否包含右孩子,可以把这3种情况的每一种继续细分为2种情况。下面对这3种情况逐个分析:
1、该节点是其父节点的左孩子。这时可以细分为两种情况:该节点有右子树和没有右子树:
1.1、该节点有右子树,则该节点的下一个节点就是右子树的最左节点;
1.2、该节点没有右子树,则根据中序遍历规则,该节点的下一个节点为其父节点;
2、该节点是其父节点的右孩子。这时可以再细分为两种情况:该节点有右子树和没有右子树:
2.1、该节点有右子树,同1.1;
2.2、该节点没有右子树,则沿着父节点指针一直向上遍历,直到找到一个是其父节点左孩子的节点;
3、该节点没有父节点,为根结点。这时也可以细分为两种情况:该节点有右子树和没有右子树:
3.1、该节点有右子树:和1.1相同;
3.2、该节点没有右子树,则下一个节点为空。
对应的代码如下:
/*
struct TreeLinkNode {
int val;
struct TreeLinkNode *left;
struct TreeLinkNode *right;
struct TreeLinkNode *next; //父节点
TreeLinkNode(int x) :val(x), left(NULL), right(NULL), next(NULL) {
}
};
*/
class Solution {
public:
TreeLinkNode* GetNext(TreeLinkNode* pNode)
{
TreeLinkNode* node = nullptr;
if(pNode==nullptr)
return node;
if(pNode->next!=nullptr) //不是根结点
{
if(pNode->next->left==pNode) //左子树
{
if(pNode->right==nullptr) //左子树有右子树
node = pNode->next;
else{ //左子树没有右子树
node = pNode->right;
while(node->left!=nullptr){
node = node->left;
}
}
}
else{ //右子树
if(pNode->right==nullptr){ //右子树没有右子树
TreeLinkNode* cur = pNode;
TreeLinkNode* parent = pNode->next;
while(parent && parent->right==cur){
cur = parent;
parent = parent->next;
}
node = parent;
}
else{ //右子树有右子树
node = pNode->right;
while(node->left!=nullptr)
node = node->left;
}
}
}
else{ //根结点
if(pNode->right!=nullptr){ //根结点有右子树
node = pNode->right;
while(node->left!=nullptr)
node = node->left;
}
}
return node;
}
};
思路2
思路1有点麻烦,但比较好想。可以把情况简化到3种,这也是书上的做法:
1、该节点有右孩子,那么下一个节点就是其右孩子的最左子结点;
2、该节点没有右孩子并且该节点是其父节点的左孩子,那么下一个节点使就是其父节点;
3、该节点没有右孩子并且该节点是其父节点的右孩子,则沿着父节点指针一直向上遍历,直到找到一个是其父节点左孩子的节点;
对应代码如下:
/*
struct TreeLinkNode {
int val;
struct TreeLinkNode *left;
struct TreeLinkNode *right;
struct TreeLinkNode *next;
TreeLinkNode(int x) :val(x), left(NULL), right(NULL), next(NULL) {
}
};
*/
class Solution {
public:
TreeLinkNode* GetNext(TreeLinkNode* pNode)
{
TreeLinkNode* node = nullptr;
if(pNode==nullptr)
return node;
if(pNode->right!=nullptr){
node = pNode->right;
while(node->left!=nullptr)
node = node->left;
}
else if(pNode->next!=nullptr){
if(pNode->next->left==pNode)
node = pNode->next;
else{
TreeLinkNode* cur = pNode;
TreeLinkNode* parent = pNode->next;
while(parent!=nullptr && parent->right==cur){
cur = parent;
parent = parent->next;
}
node = parent;
}
}
return node;
}
};