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

简介: 二叉树的遍历(递归And迭代)

二叉树的遍历



以 1 二叉树为例讲解:


2 3

4 5 6 7


递归法


思路:

按照递归调用的机制,我们按照只要遍历到就打印的方式得到的数据为:


【1,2,4,4,4,2,5,5,5,2,1,3,6,6,6,3,7,7,7,3,1】


前序遍历


我们将前序遍历所得到的数据都是在调用递归机制的元素首次出现的位置,那么按照前序遍历:【中 - 左 - 右】的顺序即可完成


所以我们得到的就是【1,2,4,5,3,6,7,1】


public void prefix(){
    System.out.println(this);
    if(this.left != null){
        this.left.prefix();
    }
    if (this.right != null){
        this.right.prefix();
    }
}


中序遍历


中序遍历所得到的数据都是在调用递归机制的元素第二次出现的位置,那么按照前序遍历:【左 - 中 - 右】的顺序即可完成


所以我们得到的就是【4,2,5,1,6,3,7】


//中序遍历
public void infix(){
    if(this.left != null){
        this.left.infix();
    }
    System.out.println(this);
    if (this.right != null){
        this.right.infix();
    }
}


后序遍历


后序遍历所得到的数据都是在调用递归机制的元素最后一次出现的位置,那么按照前序遍历:【左 - 右 - 中】的顺序即可完成


所以我们得到的就是【4,5,2,6,7,3,1】


//后序遍历
public void suffix(){
    if(this.left != null){
        this.left.suffix();
    }
    if (this.right != null){
        this.right.suffix();
    }
    System.out.println(this);
}


迭代法


思路:

首先我们来了解一下递归的实现: 每一次递归调用都会把函数的局部变量、参数和返回值等都压入调用栈,然后在结束本层递归操作的时候,从栈顶弹出上一次递归的各项参数,这也是为什么递归可以返回上一层位置的原因。


那么由此我们也可以不用递归,知道了递归调用的本质实现方法,我们就可以自己用栈实现。


前序遍历


**思路 : **


前序遍历是 【中 -> 左 -> 右】那么我们就可以从根节点加入栈,然后将右孩子 加入栈 最后再将左孩子 压入栈 ,这样我们得到的出栈顺序就是 【中 -> 左 -> 右】


  1. 将root根节点压入栈
  2. 进入循环,出栈
  3. 打印出栈节点的val
  4. 判断右孩子是否为null ,如果不是,将右孩子压入栈
  5. 判断左孩子是否为null, 如果不是,将左孩子压入栈
  6. 循环【3->5】当栈为空时 退出循环,得到结果。


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


中序遍历


**思路: **


中序遍历和前序遍历有所不同,中序遍历的顺序是【中- > 左 - > 右 】。


  1. 先将所有左边的节点全部入栈,直到left== null为止,否则一直顺序的进栈
  2. 当left为null时,出栈 ,然后将出栈的出栈的节点的val打印
  3. 将节点右移
  4. 当【temp(临时节点) 为空, 并且栈也为空时】退出循环, 否则继续【1- > 3】步骤。


class Solution {
    List<Integer> list = new ArrayList<>();
    public List<Integer> inorderTraversal(TreeNode root) {
        if(root == null){
            return list;
        }
        Stack<TreeNode> s = new Stack<>();
        TreeNode node = root;
        while(node != null || !s.isEmpty()){
            if(node != null){
                s.push(node);
                node = node.left;
            }else{
                node = s.pop();
                list.add(node.val);
                node = node.right;
            }
        }
        return list;
    }
}


后序遍历


后序遍历的顺序是【左 -> 右 -> 中】,与前两者不同,我们需要两个栈 ,栈s1 和 s2


其实经过第一轮的入栈出栈之后,得到的结果就是后序遍历结果的反转数,所以再次入栈出栈后我们就可以得到后序遍历的完整结果


  1. 先将根节点压入栈,然后进入循环
  2. 进入循环后先将栈s1 中的元素出栈,并入s2栈
  3. 判断左孩子是否为null ,如果不是,将左孩子压入栈s1
  4. 判断右孩子是否为null, 如果不是,将右孩子压入栈s1
  5. 【当栈s1为空时】退出循环,否则继续【2- > 4】
  6. 将栈s2顺序出栈,并打印


class Solution {
    List<Integer> list = new ArrayList<>();
    public List<Integer> postorderTraversal(TreeNode root) {
        if(root == null){
            return list;
        }
        Stack<TreeNode> s1 = new Stack<>();
        Stack<TreeNode> s2 = new Stack<>();
        TreeNode node = root;
        s1.push(node);
        while(!s1.isEmpty()){
            node = s1.pop();
            s2.push(node);
            if(node.left != null){
                s1.push(node.left);
            }
            if(node.right != null){
                s1.push(node.right);
            }
        }
        while(!s2.isEmpty()){
            TreeNode cur = s2.pop();
            list.add(cur.val);
        }
        return list;
    }
}


目录
相关文章
|
2月前
leetcode94二叉树的中序遍历(迭代做法)
leetcode94二叉树的中序遍历(迭代做法)
26 0
|
20天前
|
算法 数据可视化 数据挖掘
LeetCode题目104: 二叉树的最大深度(递归\迭代\层序遍历\尾递归优化\分治法实现 )
LeetCode题目104: 二叉树的最大深度(递归\迭代\层序遍历\尾递归优化\分治法实现 )
LeetCode题目104: 二叉树的最大深度(递归\迭代\层序遍历\尾递归优化\分治法实现 )
|
20天前
|
存储 SQL 算法
LeetCode 题目 94:五种算法递归|迭代|莫里斯|线索二叉树|栈的迭代二叉树 实现中序遍历
LeetCode 题目 94:五种算法递归|迭代|莫里斯|线索二叉树|栈的迭代二叉树 实现中序遍历
2705:扩号匹配问题(递归与非递归)
题目链接:http://noi.openjudge.cn/ch0202/2705/ 总时间限制:1000ms内存限制:65536kB 描述 在某个字符串(长度不超过100)中有左括号、右括号和大小写字母;规定(与常见的算数式子一样)任何一个左括号都从内到外与在它右边且距离最近的右括号匹配。
2080 0
|
11月前
|
算法
用递归的思想实现二叉树前、中、后序迭代遍历
用递归的思想实现二叉树前、中、后序迭代遍历
52 1
|
9月前
49 # 用递归和非递归两种方式实现链表反转
49 # 用递归和非递归两种方式实现链表反转
36 0
|
存储 编译器
二叉树的递归遍历与迭代遍历(图示)
本文将讲述二叉树递归与迭代的相关知识。
95 0
|
存储 算法
二叉树的前序/中序/后序遍历—采用递归与迭代两种方法实现嗷
二叉树的前序/中序/后序遍历—采用递归与迭代两种方法实现嗷
|
算法 C++ 异构计算
Day14——二叉树的前中后序遍历(迭代&&递归)
Day14——二叉树的前中后序遍历(迭代&&递归)
84 0