本质上来说,三种遍历都是基于DFS的遍历,只是打印输出的顺序不同。
前序的递归版本
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
void preorderTraversal(TreeNode* root, vector<int>& array)
{
if(root==NULL)
return;
array.push_back(root->val);
preorderTraversal(root->left,array);
preorderTraversal(root->right,array);
}
vector<int> preorderTraversal(TreeNode* root) {
vector<int> array;
preorderTraversal(root,array);
return array;
}
};
将这个版本用栈改为非递归版本, 非常类似BFS的过程
前序遍历根左右,压栈的顺序要反过来,先右后左
前序遍历的非递归版本是最容易实现的,因为和标准的DFS是相同的。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
void preorderTraversal(TreeNode* root, vector<int>& nums)
{
if(root==nullptr) return;
stack<TreeNode*> st;
st.push(root);
while(!st.empty()){
TreeNode* cur = st.top();
st.pop();
nums.push_back(cur->val);
if(cur->right) st.push(cur->right);
if(cur->left) st.push(cur->left);
}
}
vector<int> preorderTraversal(TreeNode* root) {
vector<int> nums;
preorderTraversal(root,nums);
return nums;
}
};
后续遍历的递归版本
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
void postorderTraversal(TreeNode* root, vector<int>& array)
{
if(root==NULL)
return;
postorderTraversal(root->left,array);
postorderTraversal(root->right,array);
array.push_back(root->val);
}
vector<int> postorderTraversal(TreeNode* root)
{
vector<int> array;
postorderTraversal(root,array);
return array;
}
};
通过栈将后续遍历改为非递归版本,通过观察不难发现,直接采用上面的办法先入栈,最后再出栈是不对的。这里采用一个取巧的方法,按照后续遍历那样,只是先压入左子数,再压入右子数,最后再反转一次答案。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
void postorderTraversal(TreeNode* root, vector<int>& nums)
{
if(root==NULL)
return;
stack<TreeNode*> st;
st.push(root);
while(!st.empty()){
TreeNode* cur = st.top();
st.pop();
nums.push_back(cur->val);
if(cur->left) st.push(cur->left);
if(cur->right) st.push(cur->right);
}
reverse(nums.begin(),nums.end());
}
vector<int> postorderTraversal(TreeNode* root)
{
vector<int> nums;
postorderTraversal(root,nums);
return nums;
}
};
二叉树的中序遍历递归版本
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
void inorderTraversal(TreeNode* root, vector<int> & array)
{
if(root==NULL)
return;
inorderTraversal(root->left,array);
array.push_back(root->val);
inorderTraversal(root->right,array);
}
vector<int> inorderTraversal(TreeNode* root)
{
vector<int> array;
inorderTraversal(root,array);
return array;
}
};
二叉树的非递归实现是根据二叉树的特点,借助栈,先一直往左走,然后再往右。和前序遍历的思路不同。这一思路可以实现所谓二叉搜索树的迭代器,二叉搜索树的迭代器空间复杂度为O(h)
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
void inorderTraversal(TreeNode* root, vector<int> & nums)
{
TreeNode* cur = root;
stack<TreeNode*> st;
while(cur != nullptr || !st.empty()){
while(cur!=nullptr){
st.push(cur);
cur = cur->left;
}
cur = st.top();
st.pop();
nums.push_back(cur->val);
cur=cur->right;
}
}
vector<int> inorderTraversal(TreeNode* root)
{
vector<int> nums;
inorderTraversal(root,nums);
return nums;
}
};