史上最全二叉树遍历详解(Java实现,原理相同)

二叉树遍历方法合集:

史上最全二叉树遍历详解(Java实现,原理相同)_第1张图片
最近在LeetCode力扣上刷数据结构的二叉树合集,遇到的二叉树遍历方法,于是想理解透彻。本文讲解了二叉树遍历的四种方法,前、中。后序遍历。

对应题目:
94.二叉树的中序遍历
144.二叉树的前序遍历
145.二叉树的后序遍历
102.二叉树的层序遍历

只要参考任意一种解法的代码,将其中的输出代码替换成添加数组元素即可。
我的本意是想让大家能深入的理解二叉树遍历的过程,之后完成这三道题和其它二叉树遍历的题目能够感觉轻松一点。

递归解法

递归解法是比较常用而且容易理解的方法,只要理解了思路就能够很好的去使用他。
**比如前序遍历:**前序遍历的递归方法就是:根、左、右,先打印根节点,只有再去寻找他的左子树,左子树找到末尾的时候返回再找又指数,直到完成。

下面放代码:

前序遍历

public static void PreOrderRecur(TreeNode root){
	if(root == null) return;
	System.out.println(root.data);
	PreorderRecur(root.left);
	PreorderRecur(root.right);
}

中序遍历

public static void InOrderRecur(TreeNode root){
	if(root == null) return;
	InorderRecur(root.left);
	System.out.println(root.data);
	InorderRecur(root.right);
}

后序遍历

public static void PostOrderRecur(TreeNode root){
	if(root == null) return;
	PostorderRecur(root.left);
	PostorderRecur(root.right);
	System.out.println(root.data);
}

观察可以发现,递归的实现其实只是输出根节点的位置不一样,并没有很大的不同。

迭代解法

本质上是在模拟递归,因为在递归的过程中使用了系统栈,所以在迭代的解法中常用Stack来模拟系统栈。注意栈的先进后出顺序,输出出来的就是倒序打印。

史上最全二叉树遍历详解(Java实现,原理相同)_第2张图片

前序遍历

⼆叉树的前序遍历顺序是根-左-右。我们可以采⽤⼀个栈来辅助,我们把先序遍历的结果放到⼀个ArrayList 容器中作为返回值,具体步骤如下:
1、把⼆叉树的根节点 root 放进栈。
2、如果栈不为空,从栈中取出⼀个节点,把该节点放⼊容器的尾部;如果该节点的右⼦树不为空,则
把有节点放⼊栈;如果该节点的左⼦树不为空,则把左⼦树放⼊栈中。
3、⼀直重复步骤 2 ,直到栈为空,此时遍历结束,代码如下:

static List<Interger> PreOrderTraversal(TreeNode root){
	List(Interger) result = new ArrayList<>();
	Stack<TreeNode> stack = new Stack();
	if(root == null) return result;
	stack.push(root);//首先把根节点放入栈中
	while(!stack.isEmpty(){
	//当栈中不为空的时候,执行以下操作
	TreeNode temp = stack.pop();//取出栈中的节点,用一个临时变量保存
	result.add(temp.val);//将变量的值加入结果队列中
	if(tmp.right!=null)
		stack.push(root.right);//如果该节点的右⼦树不为空,则把有节点放⼊栈
	if(tmp.left!=null)
		stack.push(root.left);//如果该节点的左⼦树不为空,则把左⼦树放⼊栈中。
		}
	return result;
}
	
	

中序遍历

史上最全二叉树遍历详解(Java实现,原理相同)_第3张图片

⼆叉树的中序遍历顺序是左-根-右。我们可以采⽤⼀个栈来辅助,我们把中序遍历的结果放到⼀个
ArrayList 容器中作为返回值,具体步骤如下:
1、进⼊ while 循环,接着把根节点及其所有左⼦节点放⼊栈中。
2、从栈中取出⼀个节点,把该节点放⼊容器的尾部;如果该节点的右⼦节点不为空,则把右⼦节点及
其右⼦节点的所有左⼦节点放⼊队列。
3、⼀直重复步骤 2 ,直到栈为空并且当前节点也为空则退出循环。
可能看解释反⽽有点乱,直接看代码吧,配合代码就容易懂了

代码如下:

public List<Integer> InOrderTraversal(TreeNode root){
    List<Integer> res = new ArrayList<>();
    Stack<TreeNode> stack = new Stack<>();

    while (root != null || !stack.isEmpty())
    {
        if(root != null){
            stack.push(root);
            root=root.left;
        }
        else{
            root = stack.pop();
            res.add(root.data);
            root=root.right;
        
        }
    }
    return res;
}

后续遍历

宽搜+逆序输出 = 后序遍历
⼆叉树的后序遍历顺序是左-右-根。我们可以采⽤⼀个栈来辅助,不过它和前序遍历以及中序遍历还是有点区别的,我们把后序遍历的结果放到⼀个 LinkedList 容器中作为返回值,具体步骤如下:
1、把⼆叉树的根节点 root 放进栈。
2、如果栈不为空,从栈中取出⼀个节点,把该节点插⼊到容器的头部。;如果该节点的左⼦树不为
空,则把该左⼦树放⼊栈中;如果该节点的右⼦树不为空,则把右⼦树放⼊栈中。,
注意,之前的前序遍历和中序遍历,我们都是⽤ ArrayList 容器,并且是把节点插⼊到容器的尾部,这
就是后序遍历的不同点。
3、⼀直重复步骤 2 ,直到栈为空,此时遍历结束
代码如下:

public List<Integer> postOderTraversal(TreeNode root) {
    LinkedList<Integer> res = new LinkedList<>();// 注意,采⽤链表
    Stack<TreeNode> stack = new Stack<>();
    if(root == null)
        return res;
    stack.push(root);
    while (!stack.isEmpty()) {
        TreeNode tmp = stack.pop();// 注意,是放在第⼀个位置
        res.addFirst(tmp.val);
        if(tmp.left != null)
            stack.push(tmp.left);
        if(tmp.right != null)
            stack.push(tmp.right);
    }
        return res;
    }

你可能感兴趣的:(LeetCode,Java)