二叉树的遍历-迭代&递归

Posted naonaoling

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉树的遍历-迭代&递归相关的知识,希望对你有一定的参考价值。

 144. 二叉树的前序遍历 ??

 1 /**
 2  * Definition for a binary tree node.
 3  * public class TreeNode {
 4  *     int val;
 5  *     TreeNode left;
 6  *     TreeNode right;
 7  *     TreeNode(int x) { val = x; }
 8  * }
 9  */
10 class Solution {
11     public List<Integer> preorderTraversal(TreeNode root) {
12         List<Integer> res = new ArrayList();
13         Stack<TreeNode> stack = new Stack();
14         if(root==null){
15             return res;
16         }
17         
18         stack.push(root);
19         TreeNode cur = null;
20         while(!stack.isEmpty()){
21             cur = stack.pop();
22             res.add(cur.val);
23             if(cur.right!=null){
24                 stack.push(cur.right);
25             }
26             if(cur.left!=null){
27                 stack.push(cur.left);
28             }
29         }
30         return res;
31     }
32 }

 

 1 class Solution {
 2     public List<Integer> preorderTraversal(TreeNode root) {
 3         List<Integer> res = new ArrayList();
 4         preOrder(root, res);
 5         return res;
 6     }
 7     public void preOrder(TreeNode node, List<Integer> res){
 8         if(node==null){
 9             return;
10         }
11         res.add(node.val);
12         preOrder(node.left, res);
13         preOrder(node.right, res);
14     }
15 }

 94. 二叉树的中序遍历 ??

class Solution {
    public List<Integer> inorderTraversal(TreeNode root){
        List<Integer> res = new ArrayList();
        if(root == null){
            return res;
        }
        Stack<TreeNode> stack = new Stack();
        TreeNode cur = root;
        while(cur!=null || !stack.isEmpty()){
            while(cur!=null){
                stack.push(cur);
                cur=cur.left;
            }
            cur=stack.pop();
            res.add(cur.val);
            cur=cur.right;  // 重要!!!
        }
        return res;
    }
}

注:cur=cur.right,下一次遍历如果cur为空,说明stack.pop()的左子树的最右节点已经遍历完了,即左子树遍历完成,不要再去遍历其左子节点,避免陷入死循环。

 1 class Solution {
 2     public List<Integer> inorderTraversal(TreeNode root){
 3         List<Integer> res = new ArrayList();
 4         inOrder(root, res);
 5         return res;
 6     }
 7     public void inOrder(TreeNode node, List<Integer> res){
 8         if(node==null){
 9             return;
10         }
11         inOrder(node.left, res);
12         res.add(node.val);
13         inOrder(node.right, res);
14     }     
15 }

 

145. 二叉树的后序遍历 ??

 1 class Solution {
 2     public List<Integer> postorderTraversal(TreeNode root) {
 3         Stack<TreeNode> stack = new Stack<>();
 4         List<Integer> res = new ArrayList<>();
 5         if(root == null){
 6             return res;
 7         }
 8         stack.push(root);
 9         TreeNode cur = root;
10         TreeNode flag = root;
11         while(!stack.isEmpty()){
12             cur=stack.peek();
13             if((cur.right == null && cur.left == null)
14              || cur.right == flag || cur.left == flag){
15                  res.add(cur.val);
16                  flag=cur;
17                  stack.pop();
18                  continue;
19              }
20             if(cur.right!=null){
21                 stack.push(cur.right);
22             }
23             if(cur.left!=null){
24                 stack.push(cur.left);
25             }
26         }
27         return res;
28     }
29 }

注:为了引起不必要的麻烦和判断,最开始都把cur和flag指向root。(flag如果指向null会有问题的哦)

class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        Stack<TreeNode> stack = new Stack<>();
        List<Integer> res = new ArrayList<>();
        if(root==null){
            return res;
        }
        TreeNode cur = root;
        stack.push(root);
        while(!stack.isEmpty()){
            cur=stack.pop();
            res.add(0,cur.val);   // (1)
            if(cur.left!=null){
                stack.push(cur.left);
            }
            if(cur.right!=null){
                stack.push(cur.right);
            }
        }
       // Collections.reverse(res);  // (2)
        return res;
    }
}

?? 注:后序遍历的另一种解法。前序中左右=>先压左子变成中右左=>翻转左中右。这个解法对于求N叉树也适用。

 1 class Solution {
 2     public List<Integer> postorderTraversal(TreeNode root) {
 3         Stack<TreeNode> stack = new Stack<>();
 4         List<Integer> res = new ArrayList<>();
 5         postOrder(root, res);
 6         return res;
 7     }
 8     public void postOrder(TreeNode node, List<Integer> res){
 9         if(node==null){
10             return;
11         }
12         postOrder(node.left, res);
13         postOrder(node.right, res);
14         res.add(node.val);
15     }
16 }

102. 二叉树的层次遍历 ??

 1 class Solution {
 2     public List<List<Integer>> levelOrder(TreeNode root) {
 3         List<List<Integer>> res = new ArrayList<List<Integer>>();
 4         if(root==null){
 5             return res;
 6         }
 7         Queue<TreeNode> queue = new LinkedList<>(); // 注意queue的定义
 8         List<Integer> curList = new ArrayList<>();
 9         TreeNode cur = root;
10         queue.offer(root);
11         queue.offer(null);
12         while(!queue.isEmpty()){
13             cur = queue.poll();
14             if(cur!=null){
15                 curList.add(cur.val);
16                 if(cur.left!=null){
17                     queue.offer(cur.left);
18                 }
19                 if(cur.right!=null){
20                     queue.offer(cur.right);
21                 }
22             }else if(cur==null){
23                 res.add(curList);
24                 curList = new ArrayList<>();
25                 if(!queue.isEmpty()){   // 注意怎么结束,以及不要丢解
26                      queue.offer(null);
27                 }
28             }
29         }
30         return res;
31     }
32 }

 107. 二叉树的层次遍历 II

1 LinkedList<List<Integer>> res = new LinkedList<>();
2 res.addFirst(curList);
3 //投机取巧

637. 二叉树的层平均值

 1 class Solution {
 2     public List<Double> averageOfLevels(TreeNode root) {
 3         List<Double> res = new ArrayList<>();
 4         if(root==null){
 5             return res;
 6         }
 7         Queue<TreeNode> queue = new LinkedList<>(); // 注意queue的定义
 8         double curSum = 0.0;
 9         int curSize = 0;
10         TreeNode cur = root;
11         queue.offer(root);
12         queue.offer(null);
13         while(!queue.isEmpty()){
14             cur = queue.poll();
15             if(cur!=null){
16                 curSum+=cur.val;
17                 curSize++;
18                 if(cur.left!=null){
19                     queue.offer(cur.left);
20                 }
21                 if(cur.right!=null){
22                     queue.offer(cur.right);
23                 }
24             }else if(cur==null){
25                 res.add(curSum/curSize);
26                 curSum=0.0;
27                 curSize=0;
28                 if(!queue.isEmpty()){   // 注意怎么结束,以及不要丢解
29                      queue.offer(null);
30                 }
31             }
32         }
33         return res;
34     }
35 }

103. 二叉树的锯齿形层次遍历

 1 class Solution {
 2     public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
 3         List<List<Integer>> res = new ArrayList<List<Integer>>();
 4         if(root==null){
 5             return res;
 6         }
 7         Queue<TreeNode> queue = new LinkedList<>(); // 注意queue的定义
 8         List<Integer> curList = new ArrayList<>();
 9         TreeNode cur = root;
10         queue.offer(root);
11         queue.offer(null);
12         int flag = 0;
13         while(!queue.isEmpty()){
14             cur = queue.poll();
15             if(cur!=null){
16                 if(flag%2==0){
17                     curList.add(cur.val);
18                 }else{
19                     curList.add(0, cur.val);
20                 }
21                 if(cur.left!=null){
22                     queue.offer(cur.left);
23                 }
24                 if(cur.right!=null){
25                     queue.offer(cur.right);
26                 }
27             }else if(cur==null){
28                 res.add(curList);
29                 curList = new ArrayList<>();
30                 flag++;
31                 if(!queue.isEmpty()){   // 注意怎么结束,以及不要丢解
32                      queue.offer(null);
33                 }
34             }
35         }
36         return res;
37     }
38 }

429. N叉树的层序遍历

 1 class Solution {
 2     public List<List<Integer>> levelOrder(Node root) {
 3       List<List<Integer>> res = new ArrayList<List<Integer>>();
 4         if(root==null){
 5             return res;
 6         }
 7         Queue<Node> queue = new LinkedList<>(); 
 8         List<Integer> curList = new ArrayList<>();
 9         Node cur = root;
10         queue.offer(root);
11         queue.offer(null);
12         while(!queue.isEmpty()){
13             cur = queue.poll();
14             if(cur!=null){
15                 curList.add(cur.val);
16                 for(Node child : cur.children){   // 就差在这了
17                     queue.offer(child);
18                 }
19             }else if(cur==null){
20                 res.add(curList);
21                 curList = new ArrayList<>();
22                 if(!queue.isEmpty()){   
23                      queue.offer(null);
24                 }
25             }
26         }
27         return res;
28     }
29 }

993. 二叉树的堂兄弟节点

最开始用层次遍历解的,但是忽略了不能是亲兄弟!DFS!

 

以上是关于二叉树的遍历-迭代&递归的主要内容,如果未能解决你的问题,请参考以下文章

二叉树的遍历(递归+迭代)

二叉树的遍历:迭代实现

二叉树的遍历:迭代实现

二叉树的遍历:迭代实现

二叉树的递归与迭代遍历

二叉树的前中后序遍历迭代&广度遍历