非递归遍历二叉树--java实现

经典数据结构--二叉树的遍历

递归遍历二叉树只有三行代码,特别容易理解且特别容易实现,但是非递归就没有那么的一目了然,不过其实就是把递归的做法平铺开来而已。下面来看每一种顺序的做法。

先序遍历:也就是先访问根节点,再左孩子,再右孩子。如何做呢,用手在纸上画一颗简单的二叉树,你会发现,先序遍历的顺序就是从根节点开始,一直访问左孩子,直到叶子(无孩子),然后访问这个叶子的父亲的右孩子(可能是子二叉树,不一定是一个单独的节点),祖先的右孩子......,然后就结束了。

在实现的时候可以用这样的方法:

1.声明一个栈,从根节点开始访问当前节点(设为temp),并将其入栈;

2.判断结点temp的左孩子是否为空,若为空,则出栈,并将栈顶结点的右孩子赋值给新的当前结点temp,循环至1 ;若不为空,将当前节点的左孩子赋值给新的当前结点temp

3.循环到栈为空且当前节点temp也为空结束遍历

代码:

public void preOrderTraversal(Node root) {
		Stack<Node> s = new Stack<Node>();
		Node temp = root;
		while (temp != null || !s.isEmpty()) {
			while (temp != null) {
				System.out.print(temp.value + " ");
				s.push(temp);
				temp = temp.left;
			}
			if (!s.isEmpty()) {
				temp = s.peek();
				s.pop();
				temp = temp.right;
			}
		}
	}
中序遍历:也就是把根节点放在中间访问,先访问左孩子,再根节点,再右孩子这样的顺序。

实现方法:

其实只要对先序遍历做一行代码的移动就可以,原先是先访问再入栈,现在变成先入栈,等到出栈的时候再访问,就可以实现。

代码:

public void inOrderTraversal(Node root) {
		Stack<Node> s = new Stack<Node>();
		Node temp = root;
		while (temp != null || !s.isEmpty()) {
			while (temp != null) {
				s.push(temp);
				temp = temp.left;
			}
			if (!s.isEmpty()) {
				temp = s.peek();
				System.out.print(temp.value + " ");
				s.pop();
				temp = temp.right;
			}
		}
	}
后序遍历:也就是根节点最后被访问,先左孩子,再右孩子,最后根节点的顺序。

实现的时候要稍微复杂一点:

用手画一棵树,可以发现,后续遍历,每一次访问的节点的共同特点是“没有孩子”,打上引号的原因是这个没有孩子包含两种情况,一种是叶子节点,也就是真的没有孩子节点,当然是可以直接访问的,还有一种是左孩子和右孩子(不管有一个还是两个)都被访问过了,才可以被直接访问。

那么实现的时候就可以按照下面的代码来:

用cur记录当前节点,pre记录上一次访问的节点。

1.如果cur的左右都空,那么访问;

2.如果pre不为空,也就是上一次有访问,且pre是cur的左孩子或者右孩子,就访问cur,且出栈,pre=cur;

3.如果其他情况,先入栈右孩子,再入栈左孩子,这样出栈的时候就是先左后右

4.循环直到栈为空

代码:

public static void postOrderTraversal(Node root) {
		Stack<Node> s = new Stack<Node>();
		Node cur;
		Node pre = null;
		s.push(root);
		while (!s.isEmpty()) {
			cur = s.peek();
			if ((cur.left == null && cur.right == null)
					|| (pre != null && (cur.left == pre || cur.right == pre))) {
				System.out.print(cur.value + " ");
				s.pop();
				pre = cur;
			} else {
				if (cur.right != null)
					s.push(cur.right);
				if (cur.left != null)
					s.push(cur.left);

			}
		}
	}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值