Morris迭代算法+迭代器版本
Morris迭代算法的核心思想是取root的前驱节点,然后判断前驱节点的后继标记是不是root,如果是,那么说明前面的前驱已经全部输出完毕,那么就清空前继节点的后继标记,然后按序遍历,如果不是,那么就继续按续遍历。如果root没有前继节点,那么就输出root节点,向后遍历即可。
中序遍历
我们一般用Morris迭代算法都是中序遍历,大多数用于二叉搜索树非常好用。
算法步骤:
- 如果当前节点的左子节点为空时,输出当前节点,并将当前节点置为该节点的右子节点;
- 如果当前节点的左子节点不为空,找到当前节点左子树的最右节点(该节点为当前节点中序遍历的前驱节点);
- 如果最右节点的右指针为空(right=null),将最右节点的右指针指向当前节点,当前节点置为其左子节点;
- 如果最右节点的右指针不为空,将最右节点右指针重新置为空(恢复树的原状),输出当前节点,并将当前节点置为其右节点;
- 重复1~2,直到当前节点为空。
前序遍历
算法步骤:
- 如果当前节点的左子节点为空时,输出当前节点,并将当前节点置为该节点的右子节点;
- 如果当前节点的左子节点不为空,找到当前节点左子树的最右节点(该节点为当前节点中序遍历的前驱节点);
- 如果最右节点的右指针为空(right=null),将最右节点的右指针指向当前节点,并输出当前节点(在此处输出),当前节点置为其左子节点;
- 如果最右节点的右指针不为空,将最右节点右指针重新置为空(恢复树的原状),并将当前节点置为其右节点;
- 重复1~2,直到当前节点为空。
后序遍历
算法步骤:
后序遍历较前两者比较麻烦,需要建立一个临时节点,并令该节点的左子节点为root,并且需要一个子过程,倒序输出某两个节点之间路径上的各个节点。
- 如果当前节点的左子节点为空时,则将其右子节点作为当前节点;
- 如果当前节点的左子节点不为空,找到当前节点左子树的最右节点(该节点为当前节点中序遍历的前驱节点);
- 如果最右节点的右指针为空(right=null),将最右节点的右指针指向当前节点,当前节点置为其左子节点;
- 如果最右节点的右指针不为空,将最右节点右指针重新置为空(恢复树的原状),倒序输出从当前节点的左子节点到该最右节点路径上的所有节点,并将当前节点置为其右节点;
- 重复1~2,直到当前节点为空。
因为后序遍历比较不好理解,一般不用,用栈模拟比较好。
中序遍历迭代器版本
#include <bits/stdc++.h>
using namespace std;
struct TreeNode
{
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
class Solution
{
public:
TreeNode* getNext(TreeNode* &root)
{
while(root != nullptr)
{
if(root->left != nullptr)
{
TreeNode * prev = root->left;
while(prev->right != nullptr && prev->right != root)
{
prev = prev->right;
}
if(prev->right == root)
{
// cout root
root = root->right;
prev->right = nullptr;
return root;
}else
{
prev->right = root;
root = root->left;
}
}else
{
// cout root
root = root->right;
return root;
}
}
return nullptr;
}
vector<int> getAllElements(TreeNode* root1, TreeNode* root2)
{
TreeNode * r1 = getNext(root1);
TreeNode * r2 = getNext(root2);
vector<int> ans;
while(r1 != nullptr || r2 != nullptr)
{
if(r2 == nullptr || (r1 != nullptr && r1->val < r2->val))
{
ans.push_back(r1->val);
r1 = getNext(root1);
}else if(r1 == nullptr || (r2 != nullptr && r2->val < r1->val))
{
ans.push_back(r2->val);
r2 = getNext(root2);
}
}
return ans;
}
};