题目描述
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
解题思路
方法一:暴力
1、思路:根据题目所给条件,输入是一个结点,要求找到这个结点在中序遍历顺序下的下一个结点。因为每个结点不仅包含左右子结点,还包含一个指向父结点的指针next,所以可以根据所给结点往上找到根节点,根节点就是父结点指针为空的那个结点,然后通过中序遍历保存结点的中序遍历序列,最后在数组中找到该结点然后输出后一个位置的结点即可。
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:
vector<TreeLinkNode *> list;
void midTravel(TreeLinkNode *root) {
if (!root) return;
midTravel(root->left);
list.push_back(root);
midTravel(root->right);
}
TreeLinkNode* GetNext(TreeLinkNode* pNode)
{
if (!pNode) return nullptr;
TreeLinkNode *root = pNode;
TreeLinkNode *tmp = pNode->next;
while (tmp) {
root = tmp;
tmp = tmp->next;
}
midTravel(root);
for (auto i = list.begin(); i != list.end(); i++) {
if ((i + 1 != list.end()) && (*i == pNode)) {
return *(i+1);
}
}
return nullptr;
}
};
3、复杂度:
时间复杂度:O(n);
空间复杂度:O(n)。
方法二: 线索二叉树
1、思路:类似构造线索二叉树的思想,将每个结点的next指针指向中序遍历顺序下的下一个结点。在中序遍历的过程中,每个结点的next指针要先清空,避免最后一个结点的next指针没被赋值的情况。
2、代码:
class Solution {
public:
TreeLinkNode *pre = nullptr;
void Convert(TreeLinkNode* cur)
{
if (!cur) return;
Convert(cur->left);
cur->next = nullptr;
if (pre) {
pre->next = cur;
}
pre = cur;
Convert(cur->right);
}
TreeLinkNode* GetNext(TreeLinkNode* pNode)
{
if (!pNode) return nullptr;
TreeLinkNode *root = pNode;
TreeLinkNode *tmp = pNode->next;
while (tmp) {
root = tmp;
tmp = tmp->next;
}
Convert(root);
return pNode->next;
}
};
3、复杂度:
时间复杂度:O(n);
空间复杂度:O(n)。
方法三:找规律
1、思路:根据中序遍历“左->根->右”的特性,某个结点的下一个结点一定在右边,根据右子树是否存在可以分两种情况:
- 该结点的右子树存在,则下一个结点为右子树的最左结点,如果右子树没有左结点,下一个结点就是右子树;
- 该结点的右子树不存在,则下一个结点为该结点的第一个右父结点,如果不存在则没有下一个结点。
2、代码:
class Solution {
public:
TreeLinkNode* GetNext(TreeLinkNode* pNode)
{
if (!pNode) return nullptr;
//第一种情况
if (pNode->right) {
//求右子树的最左结点
TreeLinkNode *rleft = pNode->right;
while (rleft->left) {
rleft = rleft->left;
}
return rleft;
}
//第二种情况
while (pNode->next) {
if (pNode->next->left == pNode) {
return pNode->next;
}
pNode = pNode->next;
}
return nullptr;
}
};
3、复杂度:
时间复杂度:O(n);
空间复杂度:O(1)。