二叉树的遍历(Java实现)

前言:

二叉树的遍历指的是按照某种固定的方向来遍历整个二叉树,然后返回一个数组/链表,即线性的数据结构,常用的遍历方式有三种,前序,中序和后序遍历,还有一种是按照每一层来访问二叉树的,叫做层序遍历,下面以返回一个List为例,总结每种遍历方式

//定义一个树节点
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }

前序遍历

前序遍历的顺序是根节点,左儿子,右儿子,然后逐个对左儿子和右儿子实施这种遍历方式,二叉树相关的算法大都都能使用递归解决,遍历当然也可以,前序遍历代码如下:

//首先是递归算法:前序遍历,顺序是根节点,左儿子,右儿子
class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
		List<Integer> res = new ArrayList<>();
        digui(root, res);
		return res;
    }
	public void digui(TreeNode root, List<Integer> res){
		if(root == null) return;
		res.add(root.val);
		digui(root.left, res);
		digui(root.right, res);
        return;
	}
}
//迭代算法:就是非递归了,结果返回的是个list,需要逐个的求树的根左右的值,也就是需要另外一个数据结构存储节点,这里使用栈,弹出栈顶元素,然后把其右儿子和左儿子入栈,逐步进行这个操作直至栈空*/
class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<Integer>();
		if(root == null) return res;
        Stack<TreeNode> stack = new Stack<>();
        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<>();
		digui(root, res);
		return res;
    }
	public void digui(TreeNode root, List<Integer> res){
		if(root == null) return;
		if(root.left != null){//res.add(root.left.val);这一行是错误的,注意每一层只需要add根节点,不用add其左右节点,因为下一层子节点就变根节点了,这里再add就会重复
			digui(root.left, res);
		}
		res.add(root.val);
		if(root.right != null) digui(root.right, res);
	}
}

//递归的方式:和前序遍历一样,使用栈作为辅助存储,和前序遍历的区别是前者可以以根节点为基准进行操作,中序遍历的话需要先放左儿子,也就是list的第一个元素是最左边的那个节点,这样的话栈的初始化就需要遍历到树的最左侧节点,然后开始每层循环:弹出栈顶元素(左儿子),然后把栈顶元素的右儿子入栈
class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<Integer>();
		if(root == null) return res;
        Stack<TreeNode> stack = new Stack<>();

        while(root != null || !stack.isEmpty()){//这里的初始化方式就是先遍历到树的最左侧节点
			while(root != null){
				stack.push(root);
				root = root.left;
			}
            root = stack.pop();//获取栈顶元素并出栈
            res.add(root.val);
            root = root.right;//如果右儿子不为空,则下面需要求其最左侧左儿子,然后入栈,为空则继续弹出
        }
        return res; 
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值