二叉树 前序中序后序层序遍历 迭代、递归方法

144 Binary Tree Preorder Traversal44.8%Medium 前序遍历

Given a binary tree, return the preorder traversal of its nodes' values.

For example:
Given binary tree {1,#,2,3},

   1
    \
     2
    /
   3

return [1,2,3].

Note: Recursive solution is trivial, could you do it iteratively?


前序遍历递归方法:比较简单
class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> res;
        if(!root) return res;
        preorder(res,root);
        return res;
    }
    void preorder(vector<int>& res, TreeNode* root){
        if(root) res.push_back(root->val);
        else return ;
        preorder(res,root->left);
        preorder(res,root->right);
        return ;
    }
};

前序遍历:迭代方法,设置一个栈,首先将出栈写入 先push由节点,再push左节点
class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
       vector<int> res;
        if(!root) return res;
        stack<TreeNode*> Stack;
        Stack.push(root);
        while(!Stack.empty())
        {
            TreeNode* curNode=Stack.top();
            res.push_back(curNode->val);
            Stack.pop();
            if(curNode->right)
                Stack.push(curNode->right);
            if(curNode->left)
                Stack.push(curNode->left);
        }
        return res;
    }
};
前序遍历:第三种迭代方法


94 Binary Tree Inorder Traversal 46.3%Medium  二叉树中序遍历

Given a binary tree, return the inorder traversal of its nodes' values.

For example:
Given binary tree [1,null,2,3],

   1
    \
     2
    /
   3

return [1,3,2].

这个题目使用递归方法较简单

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> res;
        if(!root) return res;
        inorder(res,root);
        return res;
    }
    void inorder(vector<int>& res,TreeNode* root){
        //中序遍历
        if(root->left) inorder(res,root->left);//左子树优先遍历
        res.push_back(root->val);//这个时候处理的是根
        if(root->right) inorder(res,root->right);//右子树最后遍历
    }
    
};
思路2:迭代的方法  使用stack,这种方法的缺点是改变了原来的结构

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> res;
        if(!root) return res;
        stack<TreeNode*> s;
        s.push(root);
        while(!s.empty())//当s不为空时,持续迭代
        {
           TreeNode* p=s.top();
            if(p->left)
            {
                s.push(p->left);
                p->left=NULL;//这里需要这样,因为当回到根节点时,还会判断左子树
            }
            else
            {
                res.push_back(p->val);
                s.pop();
                if(p->right)
                    s.push(p->right);
            } 
        }
        return res;
    }
    
};
思路3:使用stack和一个unordered_map
这个思路与思路2基本一致,只是为了不改变树的结构,在遍历到当前节点的左子树(存在左子树才作操作,不存在时啥事没有)时,使用一个map

记录是否已经遍历过这个节点了

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> res;
        if(!root) return res;
        unordered_map<TreeNode*,bool> flag;
        stack<TreeNode*> s;
        s.push(root);
        while(!s.empty())//当s不为空时,持续迭代
        {
           TreeNode* p=s.top();
            if(p->left&&!flag[p])
            {
                s.push(p->left);
                flag[p]=true;//这里需要这样,因为当回到根节点时,还会判断左子树
            }
            else
            {
                res.push_back(p->val);
                s.pop();
                if(p->right)
                s.push(p->right);
            } 
        }
        return res;
    }
    
};

思路4:使用stack,不会改变树的结构 非常重要  背过

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> res;
        stack<TreeNode*> s;
        TreeNode* current=root;
        while(!s.empty()||current)//
        {
            if(current)//这个变量实际上包含了上一次的信息
            {
                s.push(current);
                current=current->left;
            }
            else
            {
                TreeNode* pNode=s.top();
                res.push_back(pNode->val);
                s.pop();
               current=pNode->right;
            } 
        }
        return res;
    }
    
};

145 Binary Tree Postorder Traversal40.0%Hard 后序遍历

递归方法,较简单:
class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> res;
        if(!root) return res;
        postorder(res,root);
        return res;
    }
    void postorder(vector<int>& res, TreeNode* root){
        if(root==nullptr) return ;
        postorder(res,root->left);
        postorder(res,root->right);
        res.push_back(root->val);
        return ;
    }
};

迭代方法,多加练习:

1、将vector插入的时候使用insert函数,插到前面
vector<int> postorderTraversal(TreeNode *root) {
    vector<int> v;
    if (!root) return v;
    
    stack<TreeNode *> s;
    s.push(root);
    
    TreeNode *p = NULL;
    while(!s.empty()) {
        p = s.top();
        s.pop();
        v.insert(v.begin(), p->val);
        if (p->left) s.push(p->left);
        if (p->right) s.push(p->right);
    }
    
    return v;
}



2、 迭代 还要练习
vector<int> postorderTraversal(TreeNode* root) {
    vector<int> nodes;
    stack<TreeNode*> toVisit;
    TreeNode* curNode = root;
    TreeNode* lastNode = NULL;
    while (curNode || !toVisit.empty()) {
        if (curNode) {
            toVisit.push(curNode);
            curNode = curNode -> left;
        }
        else {
            TreeNode* topNode = toVisit.top();
            if (topNode -> right && lastNode != topNode -> right)
                curNode = topNode -> right;
            else {
                nodes.push_back(topNode -> val);
                lastNode = topNode;
                toVisit.pop();
            }
        }
    }
    return nodes;
}

107 Binary Tree Level Order Traversal II39.9%Easy  二叉树层序遍历

Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left to right, level by level from leaf to root).

For example:
Given binary tree [3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7

return its bottom-up level order traversal as:

[
  [15,7],
  [9,20],
  [3]
]
自己的思路:使用队列完成层序遍历
看解答有两种思路:
思路1:使用宽度优先遍历+队列
class Solution {
public:
    vector<vector<int>> levelOrderBottom(TreeNode* root) {
        //使用队列
        queue<TreeNode*> q;
        vector<vector<int>> res;
        if(!root) return res;
        q.push(root);
        while(!q.empty())
        {
            int length=q.size();
            vector<int> temp;
            while(length--)//这个循环针对的是每一层的节点,当length保存的是一层节点的数量
            {
                TreeNode* tempNode=q.front();
                if(tempNode->left) q.push(tempNode->left);
                if(tempNode->right) q.push(tempNode->right);
                temp.push_back(tempNode->val);
                q.pop();
            }
            res.push_back(temp);
        }
        return vector<vector<int>> (res.rbegin(),res.rend());//注意这种倒置的语法形式,不需要再调用reverse函数
    }
};

思路2:使用深度优先遍历,递归的形式
class Solution {
public:
    vector<vector<int>> levelOrderBottom(TreeNode* root) {
       if(root==nullptr) return res;
        DFS(root,0);
        return vector<vector<int>> (res.rbegin(),res.rend());
    }
    void DFS(TreeNode* root,int level){//用level标记每一层
        if(!root) return;
        if(level==res.size())//当前层的节点还没有加入到结果中
        {
            res.push_back(vector<int>());
        }
        res[level].push_back(root->val);
        DFS(root->left,level+1);
        DFS(root->right,level+1);
    }
    vector<vector<int>> res;//为了不在函数参数中出现,再类中定义成员变量,起到当前层次的全局变量的效果
    
};
102. Binary Tree Level Order Traversal 层序遍历

Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level).

For example:
Given binary tree [3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7

return its level order traversal as:

[
  [3],
  [9,20],
  [15,7]
]
class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        vector<vector<int>> res;
        if(root==NULL) return res;
        queue<TreeNode*> Queue;
        Queue.push(root);
        while(!Queue.empty())
        {
            int n=Queue.size();
            vector<int> temp;
            for(int i=0;i<n;i++)
            {
                TreeNode* topNode=Queue.front();
                temp.push_back(topNode->val);
                if(topNode->left!=nullptr)
                    Queue.push(topNode->left);
                if(topNode->right!=nullptr)
                    Queue.push(topNode->right);
                Queue.pop();
            }
            res.push_back(temp);
        }
        return res;
    }
};
637. Average of Levels in Binary Tree 层序遍历 简单舍弃

Given a non-empty binary tree, return the average value of the nodes on each level in the form of an array.

Example 1:

Input:
    3
   / \
  9  20
    /  \
   15   7
Output: [3, 14.5, 11]
Explanation:
The average value of nodes on level 0 is 3,  on level 1 is 14.5, and on level 2 is 11. Hence return [3, 14.5, 11].
class Solution {
public:
    vector<double> averageOfLevels(TreeNode* root) {
        queue<TreeNode*> q;
        vector<double> res;
        if(root==nullptr) return res;
        q.push(root);
        while(!q.empty())
        {
            
            int n=q.size();
            double temp=0;
            for(int i=0;i<n;i++)
            {
                TreeNode* topNode=q.front();
                temp+=topNode->val;
                if(topNode->left)
                    q.push(topNode->left);
                if(topNode->right)
                    q.push(topNode->right);
                q.pop();
            }
            temp/=n;
            res.push_back(temp);
        }
        return res;
    }
};

103. Binary Tree Zigzag Level Order Traversal 之字形打印,中序遍历变种

Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to right, then right to left for the next level and alternate between).

For example:
Given binary tree [3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7

return its zigzag level order traversal as:

[
  [3],
  [20,9],
  [15,7]
]
分析: 由于打印顺序不一样,两次入栈的顺序不一样,因此设置一个奇偶次循环的标志。另外,当前层和子层不能保存到一个栈里面,因此设置两个辅助栈。
class Solution {
public:
    vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
        stack<TreeNode*> s[2];
        vector<vector<int>> res;
        if(root==nullptr) return res;
        s[0].push(root);
        bool oven=true;
        int current=0,next=1;
        while(!s[current].empty())
        {
            
            int n=s[current].size();
            vector<int> temp;
            for(int i=0;i<n;i++)
            {
                TreeNode* topNode=s[current].top();
                temp.push_back(topNode->val);
                if(oven){
                if(topNode->left)
                    s[next].push(topNode->left);
                if(topNode->right)
                    s[next].push(topNode->right); 
                }
                else
                {
                    if(topNode->right)
                    s[next].push(topNode->right);
                if(topNode->left)
                    s[next].push(topNode->left);
                }
                s[current].pop();
            }
            oven=oven?false:true;
            res.push_back(temp);
            next=1-next;
            current=1-current;
        }
        return res;
    }
};






  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值