学无先后,达者为师

网站首页 编程语言 正文

二叉树的递归和非递归遍历

作者:阿旋要毕业~ 更新时间: 2022-05-10 编程语言

树节点的基本结构:

  public class TreeNode {
      int val;
      TreeNode left;
      TreeNode right;
      TreeNode() {}
      TreeNode(int val) { this.val = val; }
      TreeNode(int val, TreeNode left, TreeNode right) {
          this.val = val;
          this.left = left;
          this.right = right;
    }
  }

1.先序遍历:

遍历顺序:根-左孩子-右孩子

1.1 递归算法:

class Solution {
    List res;
    public List preorderTraversal(TreeNode root) {
        res = new LinkedList();
        preTraver(root);
        return res;
    }
    public void preTraver(TreeNode root) {
        if(root != null) {
            res.add(root.val);
            preTraver(root.left);
            preTraver(root.right);
        }
    }
}

1.2 非递归算法:

使用栈来做。最外面用root变量来保存左孩子。root不为空,则直接入栈,并记录下当前值(因为先序遍历是先遍历根);如果root为空,说明此时栈顶结点应该遍历右孩子,则出栈,并遍历右孩子。

class Solution {
    List res;
    public List preorderTraversal(TreeNode root) {
        Deque stack = new LinkedList();
        List res = new ArrayList();
        while(root!=null || !stack.isEmpty()) {
            if(root != null) {
                stack.addFirst(root);
                res.add(root.val);
                root = root.left;
            } else {
                TreeNode p = stack.pollFirst();
                if(p.right != null) {
                    root = p.right;
                }
            }
        }
        return res;
    }
}

2.中序遍历

遍历顺序:左孩子-根-右孩子

2.1 递归算法:

使用栈来做。最外面用root变量来保存左孩子。root不为空,则直接入栈;如果root为空,说明此时栈顶结点应该遍历右孩子。

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

2.2 非递归算法:

使用栈来做。最外面用root变量来保存左孩子。root不为空,则直接入栈;如果root为空,说明此时栈顶结点应该遍历右孩子,则出栈,记录下当前结点的值(因为中序遍历是先遍历左孩子,然后才是根),然后遍历右孩子。

与先序遍历基本相同,唯一不同的地方在于何时记录结点值。先序遍历是入栈的时候记录结点值,中序遍历时出栈的时候记录结点值。

class Solution {
    public List inorderTraversal(TreeNode root) {
        List res = new ArrayList();
        Deque stack = new LinkedList();
        while(root!=null || !stack.isEmpty()) {
            if(root != null) {
                stack.addFirst(root);
                root = root.left;
            } else {
                TreeNode p = stack.poll();
                res.add(p.val);
                root = p.right;
            }
        }
        return res;
    }
}

3. 后序遍历

遍历顺序:左孩子-右孩子-根

3.1 递归算法

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

3.2 非递归算法

考虑到,先序遍历是(根-左孩子-右孩子)、后序遍历是(左孩子-右孩子-根)因此可以再先序遍历的基础上进行改进,改成(根-右孩子-左孩子),然后进行逆置操作。对于ArraList可以采用Collections.reverse(res)来进行逆置。

class Solution {
    
    public List postorderTraversal(TreeNode root) {
        List res = new ArrayList();
        Deque stack = new LinkedList();
        while(root != null || !stack.isEmpty()) {
            if(root != null) {
                stack.addFirst(root);
                res.add(root.val);
                root = root.right;
            } else {
                TreeNode p = stack.pollFirst();
                root = p.left;
            }
        }
        Collections.reverse(res);
        return res;
    }
}

4. 层序遍历

4.1 递归算法

记录下当前结点位于第几层,先后遍历左右结点。

class Solution {
    List> res;
    public List> levelOrder(TreeNode root) {
        res = new ArrayList>();
        if(root == null) {return res;}
        levelTravel(root, 0);
        return res;
    }
    public void levelTravel(TreeNode root, int level) {
        if(root == null) {
            return ;
        } 
        List temp ;
        if(level >= res.size()) {
          temp  = new ArrayList();
          res.add(temp);
        } else {
            temp = res.get(level);
        }
        temp.add(root.val);
        levelTravel(root.left,level +1);
        levelTravel(root.right,level +1);
        
    }
}

4.2  非递归算法

采用队列来做。

class Solution {
    public List> levelOrder(TreeNode root) {
        List> res = new ArrayList>();
        if(root == null) {return res;}
        Deque queue = new LinkedList();
        queue.addFirst(root);
        int n = 1;
        while(!queue.isEmpty()) {
            n = queue.size();
            List temp = new ArrayList();
            for(int i = 1; i <= n; i++) {
                TreeNode p = queue.pollLast();
                temp.add(p.val);
                if(p.left != null) {
                    queue.addFirst(p.left);
                } 
                if(p.right != null) {
                    queue.addFirst(p.right);
                } 
            }
            res.add(temp);
        }
        return res;
    }
}

原文链接:https://blog.csdn.net/xuan971130/article/details/124582306

栏目分类
最近更新