LeetCode:二叉树的前、中、后序遍历

描述:

 

-------------------------------------------------------

 

前序遍历:

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

给出一棵二叉树,返回其节点值的前序遍历。

样例

给出一棵二叉树 {1,#,2,3},

   1
    \
     2
    /
   3

 返回 [1,2,3].

 

----------------------------------------------------------

 

中序遍历:

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

样例

给出二叉树 {1,#,2,3},

   1
    \
     2
    /
   3

返回 [1,3,2].

 

------------------------------------------------------

 

后序遍历:

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

给出一棵二叉树,返回其节点值的后序遍历。 

样例

给出一棵二叉树 {1,#,2,3},

   1
    \
     2
    /
   3

返回 [3,2,1]

 C++解题思路:

用一个栈stack就可以解决问题,vector使用.push_back方法来将元素压入栈中。

前序:

 递归一:

/**
 * 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:
    vector<int> sol;
    
    void recurseSol(TreeNode * root) {
        if (!root) {
            return;
        }
        sol.push_back(root->val);
        recurseSol(root->left);
        recurseSol(root->right);
    }
    
    vector<int> preorderTraversal(TreeNode* root) {
        recurseSol(root);
        return sol;
    }
};

非递归与递归二:

/**
 * 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:
    //非递归
    vector<int> preorderTraversal2(TreeNode* root) {
        vector<int> res;
        stack<TreeNode*> s;
        TreeNode *p = root;
        while (p || !s.empty()) {
            while (p){
                s.push(p);
                res.push_back(p->val);
                p = p->left;
            }
            p = s.top();
            s.pop();
            p = p->right;
        }
        return res;
    }
    //递归
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> vec1,vec2;
        if (!root) {
            return vec1;
        }
        int r = root->val;
        vec1 = preorderTraversal(root->left);
        vec2 = preorderTraversal(root->right);
        
        vec1.insert(vec1.begin(),r);
        vec1.insert(vec1.end(),vec2.begin(),vec2.end());  
        return vec1;
    }
};

 

中序:

/**
 * 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:
    //非递归
    vector<int> inorderTraversal2(TreeNode* root) {
        vector<int> res;
        stack<TreeNode*> s;
        TreeNode *p = root;
        while (p || !s.empty()) {
            while (p) {
                s.push(p);
                p = p->left;
            }
            p = s.top();
            s.pop();
            res.push_back(p->val);
            p = p->right;
        }
        return res;
    }
    //递归
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> vec1,vec2;
        if (!root) {
            return vec1;
        }
        vec1 = inorderTraversal(root->left);
        vec1.push_back(root->val);
        vec2 = inorderTraversal(root->right);
        
        vec1.insert(vec1.end(),vec2.begin(),vec2.end());  
        return vec1;
    }
};

 

后序:

后序非递归采用的思路是先将二叉树排序为(根-右-左),然后利用reverse函数反转vector的序列。

 

/**
 * 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:
    //非递归
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> res;
        if (!root){
            return res;
        }
        stack<TreeNode*> s;
        TreeNode *p = root;
        s.push(p);
        while (!s.empty()) {
            p = s.top();  
            res.push_back(p->val);
            s.pop();
            if(p->left)
                s.push(p->left);
            if(p->right)
                s.push(p->right);
        }
        reverse(res.begin(),res.end());
        return res;
            
    }
    
    //递归
    vector<int> postorderTraversal2(TreeNode* root) {
        vector<int> vec1,vec2;
        if (!root) {
            return vec1;
        }
        vec1 = postorderTraversal(root->left);
        vec2 = postorderTraversal(root->right);        
        
        vec1.insert(vec1.end(),vec2.begin(),vec2.end());  
        vec1.push_back(root->val);
        return vec1;
    }
};

 

 

 

 

JAVA解题思路:

递归实现二叉树的遍历相对简单,如果用list存放遍历结果,每次递归使用list.addall()方法即可添加“子树”;

使用非递归实现遍历比较复杂,这里我利用栈(stack)来实现节点的存取操作,使其顺利add进入list中返回。

代码如下:

 

  1 package week1;
  2 
  3 import java.awt.List;
  4 import java.util.ArrayList;
  5 import java.util.Stack;
  6 
  7 public class 二叉树遍历 {
  8     /**
  9      * Definition of TreeNode:
 10      */
 11     public class TreeNode {
 12         public int val;
 13         public TreeNode left, right;
 14 
 15         public TreeNode(int val) {
 16             this.val = val;
 17             this.left = this.right = null;
 18         }
 19     }
 20     
 21     
 22 //==============先序遍历=======================================================
 23     /*
 24      * @param root: A Tree
 25      * @return: Preorder in ArrayList which contains node values.
 26      * 递归
 27      */
 28     public ArrayList<Integer> preorderTraversal(TreeNode root) {
 29         // write your code here
 30         ArrayList<Integer> list = new ArrayList<Integer>();
 31         if (root == null) return list;
 32         list.add(root.val);  //先将根节点放入
 33         if(root.left != null) list.addAll(preorderTraversal(root.left)); //递归左子树,放入list中
 34         if(root.right != null) list.addAll(preorderTraversal(root.right));  //递归右子树,放入list中
 35         return list;
 36     }
 37     
 38     /*
 39      * @param root: A Tree
 40      * @return: Preorder in ArrayList which contains node values.
 41      * 非递归
 42      */
 43     public ArrayList<Integer> preorderTraversal2(TreeNode root) {
 44         // write your code here
 45         ArrayList<Integer> res = new ArrayList<Integer>();
 46         if(root == null) return res;
 47         Stack<TreeNode> stack = new Stack<TreeNode>();
 48         stack.push(root);  //入栈操作
 49         while(!stack.empty()){
 50             TreeNode node = stack.pop(); //当前节点出栈
 51             res.add(node.val);
 52             if(node.right != null) stack.push(node.right);  //先入右子树节点,因为先进后出
 53             if(node.left != null) stack.push(node.left);
 54         }
 55         return res;
 56     }
 57     
 58     
 59 //==============中序遍历=======================================================
 60     /**
 61      * 递归
 62      */
 63     public ArrayList<Integer> inorderTraversal(TreeNode root) {
 64         // write your code here
 65         ArrayList<Integer> list = new ArrayList<Integer>();
 66         if (root == null) return list;
 67         if(root.left != null) list.addAll(inorderTraversal(root.left));
 68         list.add(root.val);
 69         if(root.right != null) list.addAll(inorderTraversal(root.right));
 70         return list;
 71     }
 72     
 73     /**
 74      * 非递归
 75      */
 76     public ArrayList<Integer> inorderTraversal2(TreeNode root) {
 77         // write your code here
 78         ArrayList<Integer> res = new ArrayList<Integer>();
 79         if(root == null) return res;
 80         Stack<TreeNode> stack = new Stack<TreeNode>();
 81         TreeNode node = root;
 82         while(node != null || !stack.empty()){
 83             while(node != null){   //一直遍历左子树入栈,直到左叶子节点,才开始下一步出栈
 84                 stack.push(node);
 85                 node = node.left;
 86             }
 87             node = stack.pop();
 88             res.add(node.val);
 89             node = node.right; //左-中-右
 90         }
 91         return res;
 92     }
 93     
 94     
 95 //==============后序遍历=======================================================
 96     /**
 97      * 递归
 98      */
 99     public ArrayList<Integer> postorderTraversal(TreeNode root) {
100         // write your code here
101         ArrayList<Integer> list = new ArrayList<Integer>();
102         if (root == null) return list;
103         if(root.left != null) list.addAll(postorderTraversal(root.left));
104         if(root.right != null) list.addAll(postorderTraversal(root.right));
105         list.add(root.val);
106         return list;
107     }
108     
109     /**
110      * 非递归
111      */
112     public ArrayList<Integer> postorderTraversal2(TreeNode root) {
113         // write your code here
114         ArrayList<Integer> list = new ArrayList<Integer>();
115         if (root == null) return list;
116         Stack<TreeNode> stack = new Stack<TreeNode>();
117         stack.push(root);
118         while(!stack.empty()){
119              TreeNode node = stack.pop();
120              list.add(0,node.val);  //此方法有两个参数,第一个参数指定插入位置,第二个为插入值,这里一直在0位置插入,意思是最新插入的一直在list的最前面,之前插入的到了后面
121              if(node.left != null) stack.push(node.left);
122              if(node.right != null) stack.push(node.right);
123         }
124         return list;
125     }
126 }

 

至此完成二叉树的遍历。  by still

posted @ 2017-08-21 11:03  华不摇曳  阅读(629)  评论(0编辑  收藏  举报