方法有三个:
- Morris 中序遍历:时间复杂度
O
(
N
)
O(N)
O(N),空间复杂度
O
(
1
)
O(1)
O(1)
- 递归遍历:时间复杂度
O
(
N
)
O(N)
O(N),空间复杂度
O
(
N
)
O(N)
O(N)(递归栈)
- 迭代遍历:时间复杂度
O
(
N
)
O(N)
O(N),空间复杂度
O
(
N
)
O(N)
O(N)
Morris 中序遍历:
不适用额外的存储空间,通过改变节点的指向完成遍历。当前访问节点为root:
1.若当前节点不存在左子树
2.若当前节点存在左子树:
- 找到左子树中序遍历的最后一个节点【前驱节点:左-右-右-…-右】
- 若前驱节点右节点为空
– 右节点指向当前root – root = root
→
\rightarrow
→ left - 若前驱节点右节点不为空
– 当前值输出 – root = root
→
\rightarrow
→ right
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> out;
TreeNode* preds = root;
while(root){
if(!root->left) {
out.push_back(root->val);
root = root->right;
} else {
preds = root->left;
while(preds->right && preds->right != root) preds = preds->right;
if(!preds->right) {
preds->right = root;
root = root->left;
}
else {
out.push_back(root->val);
preds->right = nullptr;
root = root->right;
}
}
}
return out;
}
};
递归遍历:
class Solution {
vector<int> out;
void inorder(TreeNode* node) {
if(!node) return;
if(node->left) inorder(node->left);
out.push_back(node->val);
if(node->right) inorder(node->right);
}
public:
vector<int> inorderTraversal(TreeNode* root) {
inorder(root);
return out;
}
};
迭代遍历(堆):
出栈的时,存储输出值。 root 指针不断更新,对于每一个子树: 左边向下,用一个 while 找到最深的叶子节点 右边返回,当前节点先出栈,再访问右节点
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> out;
stack<TreeNode*> stk;
while(root || stk.size() > 0){
while(root){
stk.push(root);
root = root->left;
}
root = stk.top();
stk.pop();
out.push_back(root->val);
root = root->right;
}
return out;
}
};
|