二叉树总结-递归与非递归实现

二叉树相关算法主要考察的是递归、宽度优先搜索和广度优先搜索,很多问题都是前序、中序、后序和层序遍历的变形,遍历的递归与非递归实现都应该熟练掌握

遍历通常分为前序遍历、中序遍历、后序遍历、层序遍历四种情况。对于遍历方式只是打印顺序而已,所以四种遍历复杂度均相同。

1、二叉树的遍历

遍历的时间复杂度与空间复杂度
1.非递归遍历(辅助栈)
    时间复杂度:O(N)
    空间复杂度:O(N)
    由于每个节点都要进栈和出栈,所以时间复杂度为O(N),同样空间复杂度也为O(N),N为结点数。
2.递归遍历
    时间复杂度:O(N)
    空间复杂度:O(N)
    递归实现的本质也是系统帮我们建立了栈结构,而系统栈需要记住每个节点的值,所以空间复杂度仍为O(N)。
递归实现
前序遍历

class Solution {
    List<Integer> res=new ArrayList<>();
    public List<Integer> preorderTraversal(TreeNode root) {
        if(root==null){
            return res;
        }
         //List res=new ArrayList<>();
         res.add(root.val);
         preorderTraversal(root.left);
         preorderTraversal(root.right);
         return res;

    }
}

中序遍历

class Solution {
    List<Integer> res=new ArrayList<>();
    public List<Integer> inorderTraversal(TreeNode root) {
        if(root==null){
            return res;
        }
        inorderTraversal(root.left);
        res.add(root.val);
        inorderTraversal(root.right);
        return res;

    }
}

后序遍历

class Solution {
    List<Integer> res=new ArrayList<Integer>();
    public List<Integer> postorderTraversal(TreeNode root) {
        if(root==null){
            return res;
        }
        postorderTraversal(root.left);
        postorderTraversal(root.right);
        res.add(root.val);
        return res;

    }
}

非递归版本
先序遍历

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

中序遍历

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;
    }
}

后序遍历

class Solution {
  public List<Integer> postorderTraversal(TreeNode root) {
    Stack<TreeNode> stack = new Stack<>();
    List<Integer> output = new ArrayList<>();
    if (root == null) {
      return output;
    }

    stack.add(root);
    while (!stack.isEmpty()) {
      TreeNode node = stack.pop();
      output.add(node.val);
      if (node.left != null) {
        stack.push(node.left);
      }
      if (node.right != null) {
        stack.push(node.right);
      }
    }
    Collections.reverse(output);
    return output;
  }
}

层序遍历

class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> res=new ArrayList<>();
        if(root==null){
            return res;
        }
        Queue<TreeNode> q=new LinkedList<>();
        q.offer(root);
        while(!q.isEmpty()){
           // root=q.poll();
            List<Integer> list=new ArrayList<>();
            int size=q.size();
            for(int i=0;i<size;i++){
                root=q.poll();
                list.add(root.val);
                if(root.left!=null){
                    q.offer(root.left);
                }
                if(root.right!=null){
                    q.offer(root.right);
                }
            }
            res.add(list);
        }
        return res;
    }
}

2、二叉树遍历的变形题

二叉搜索树的第K个结点
二叉树的左视图/右视图

你可能感兴趣的:(算法)