递归解法
递归解法可以简单套用三种遍历的框架:
- 前序遍历
void preorder(TreeNode* root){
//实现功能
preorder(root->left);
preorder(root->right);
}
- 中序遍历
void inorder(TreeNode* root){
inorder(root->left);
//实现功能
inorder(root->right);
}
- 后序遍历
void postorder(TreeNode* root){
postorder(root->left);
postorder(root->right);
//实现功能
}
Leetcode中前序遍历、中序遍历、后序遍历(题号144、94、145)迭代解法分别为:
1 . 前序遍历(递归)
public:
vector<int> Traversal(TreeNode* root){
vector<int>res;
if(root==nullptr) return res;
preorder(root,res);
return res;
}
void preorder(TreeNode* root, vector<int>&res){
if(root==nullptr) return;
res.push_back(root->val);//功能代码
preorder(root->left,res);
preorder(root->right,res);
}
- 中序遍历(递归)
public:
vector<int> Traversal(TreeNode* root){
vector<int>res;
if(root==nullptr) return res;
inorder(root,res);
return res;
}
void inorder(TreeNode* root, vector<int>&res){
if(root==nullptr) return;
inorder(root->left,res);
res.push_back(root->val);//功能代码
inorder(root->right,res);
}
- 后序遍历(递归)
public:
vector<int> Traversal(TreeNode* root){
vector<int>res;
if(root==nullptr) return res;
postorder(root,res);
return res;
}
void postorder(TreeNode* root, vector<int>&res){
if(root==nullptr) return;
postorder(root->left,res);
postorder(root->right,res);
res.push_back(root->val);//功能代码
}
迭代解法
迭代解法一般采用栈,下面是迭代解法的通用框架:
- 前序遍历(迭代)
vector<int> preorderTraversal(TreeNode* root){
vector<int>res;
if(root==nullptr) return res;
stack<TreeNode*>stk;
stk.push(root);
while(!stk.empty()){
TreeNode* node=stk.top();
stk.pop();
if(node!=nullptr){
if(node->right!=nullptr){
stk.push(node->right);
}
if(node->left!=nullptr){
stk.push(node->left);
}
stk.push(node);
stk.push(nullptr);
}
else{
res.push_back(stk.top()->val);
stk.pop();
}
}
return res;
}
- 中序遍历(迭代)
vector<int> inorderTraversal(TreeNode* root) {
vector<int>res;
if(root==nullptr) return res;
stack<TreeNode*>stk;
stk.push(root);
while(!stk.empty()){
TreeNode* node=stk.top();
stk.pop();
if(node!=nullptr){
if(node->right!=nullptr){
stk.push(node->right);
}
stk.push(node);
stk.push(nullptr);
if(node->left!=nullptr){
stk.push(node->left);
}
}
else{
res.push_back(stk.top()->val);
stk.pop();
}
}
return res;
}
- 后序遍历(迭代)
vector<int> postorderTraversal(TreeNode* root) {
vector<int>res;
if(root==nullptr) return res;
stack<TreeNode*> stk;
stk.push(root);
while(!stk.empty()){
TreeNode* node=stk.top();
stk.pop();
if(node!=nullptr){
stk.push(node);
stk.push(nullptr);
if(node->right!=nullptr){
stk.push(node->right);
}
if(node->left!=nullptr){
stk.push(node->left);
}
}
else{
res.push_back(stk.top()->val);
stk.pop();
}
}
return res;
}
迭代方法中压入nullptr的原因主要是通过nullptr来避免重复访问已经访问过的节点。
迭代方法主要参考Leetcode上的大佬题解。