Java不使用递归完成二叉树的前中后序遍历

Java不使用递归完成二叉树的先中后序遍历

【题⽬】
按照⼆叉树的先序遍历打印⼆叉树,并且不能使⽤递归。

先序遍历

  1. ⼆叉树的先序遍历顺序是根-左-右。我们可以采⽤⼀个栈来辅助,我们把先序遍历的结果放到⼀个ArrayList 容器中作为返回值,具体步骤如下:

    1、把⼆叉树的根节点 root 放进栈。

    2、如果栈不为空,从栈中取出⼀个节点,把该节点放⼊容器的尾部;如果该节点的右⼦树不为空,则把有节点放⼊栈;如果该节点的左⼦树不为空,则把左⼦树放⼊栈中。

    3、⼀直重复步骤 2 ,直到栈为空,此时遍历结束,代码如下:

static List<Integer> preOderTraversal(TreeNode root) {
	 List<Integer> result = new ArrayList<>();
	 Stack<TreeNode> stack = new Stack<>();
	 if(root == null)
		 return result;
	 stack.push(root);
	 
	 while (!stack.isEmpty()) {
		 TreeNode tmp = stack.pop();
		 result.add(tmp.value);
		 if(tmp.right != null)
	 	   	 stack.push(tmp.right);
		 if(tmp.left != null)
			 stack.push(tmp.left);
	 }
	 return result;
 }

中序遍历

⼆叉树的中序遍历顺序是左-根-右。我们可以采⽤⼀个栈来辅助,我们把中序遍历的结果放到⼀个ArrayList 容器中作为返回值,具体步骤如下:

1、进⼊ while 循环,接着把根节点及其所有左⼦节点放⼊栈中。

2、从栈中取出⼀个节点,把该节点放⼊容器的尾部;如果该节点的右⼦节点不为空,则把右⼦节点及其右⼦节点的所有左⼦节点放⼊队列。

3、⼀直重复步骤 2 ,直到栈为空并且当前节点也为空则退出循环。
可能看解释反⽽有点乱,直接看代码吧,配合代码就容易懂了。

public List<Integer> inOderTraversal(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.val);
			 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;
 }
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值