题目描述
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
解法一:
最开始我想的是穷举法。
假设有一颗满二叉树,考虑每一个节点的情况。结果发现自己总结归纳能力太差,所以决定先用笨方法做出来。
转换思路:把中序遍历的结果存放在vector中,然后再遍历整个vector,从而获得结果(当然这样也比较麻烦)
/*
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)
{
//空节点
if (!pNode)
return pNode;
//查找根节点
TreeLinkNode *root = pNode;
while (root->next)
{
root = root->next;
}
//生成中序遍历的vector
findNextNode(root);
//遍历vector寻找pNode的下一个节点
int length = vec.size();
for (int i = 0; i < length; i++)
{
if (vec[i] == pNode)
{
if (i + 1 == length)
return NULL;
else
return vec[i + 1];
}
}
return NULL;
}
private:
void findNextNode(TreeLinkNode* root)
{
if (root->left != NULL)
findNextNode(root->left);
vec.push_back(root);
if (root->right != NULL)
findNextNode(root->right);
}
private:
vector<TreeLinkNode*> vec;
};
解法二:
还是解法一最开始提到的思路,对各种情况进行总结如下
- 如果节点为空,则返回空
- 如果该节点存在右节点(左节点不可能下一个节点。如果不明白,请google中序遍历),那么下一个节点就是右节点的最左节点。如下图:
- 如果该节点不是根节点。(1)该节点是父节点的左孩子,那么下一个节点就是父节点。如下图:
(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)
{
//空节点
if (!pNode)
return pNode;
//假设是根节点
if (pNode->right != NULL)
{
pNode = pNode->right;
while (pNode->left != NULL)
pNode = pNode->left;
return pNode;
}
while (pNode->next != NULL)
{
TreeLinkNode* parent = pNode->next;
if (parent ->left == pNode)
return parent;
pNode = pNode->next;
}
return NULL;
}
};