二叉树的遍历 中序 后序 先序 递归 非递归

先序遍历结果:- + a * - b c d / e f 

中序遍历结果:a + b - c * d - e / f 

后序遍历结果:a b c - d * + e f / - 

层次遍历结果:- + / a * e f - d b c 

 

package lengreen.struct.other;

import lengreen.struct.Iterator;
import lengreen.struct.LinkedList;
import lengreen.struct.Queue;
import lengreen.struct.Stack;
import lengreen.struct.impl.ArrayQueue;
import lengreen.struct.impl.BinaryTreeNode;
import lengreen.struct.impl.DoubleLinkedList;
import lengreen.struct.impl.SingleLinkedStack;

public class BinaryTreeTest {
	private BinaryTreeNode root;

	public static void main(String[] args) {
		BinaryTreeTest bt = new BinaryTreeTest();
		bt.genRoot();
		// Iterator it = bt.midOrder(bt.root, new DoubleLinkedList());
		// Iterator it = bt.lastOrder(bt.root, new DoubleLinkedList());
		// Iterator it = bt.preOrder(bt.root, new DoubleLinkedList());
		Iterator it = bt.levelOrder(bt.root, new DoubleLinkedList());
		// Iterator it = bt.order(1);
		while (!it.isDone()) {
			BinaryTreeNode btn = (BinaryTreeNode) it.currentItem();
			System.out.print(btn.getData().toString() + " ");
			it.next();
		}
	}

	// 层次遍历
	public Iterator levelOrder(BinaryTreeNode rt, LinkedList list) {
		if (rt == null) {
			return null;
		}
		Queue q = new ArrayQueue();
		BinaryTreeNode p = null;
		q.enqueue(rt);
		while (!q.isEmpty()) {
			p = (BinaryTreeNode) q.dequeue();// 取出队首元素,访问之
			list.insertLast(p);
			if (p.hasLeftChild()) {
				q.enqueue(p.getLeftChild());// 如果左节点存在,放入队列中
			}
			if (p.hasRightChild()) {
				q.enqueue(p.getRightChild());// 如果右节点存在,放入队列中
			}
		}
		return list.elements();
	}

	// 二叉树遍历的递归算法
	public void orderRecursion(BinaryTreeNode rt, LinkedList list, int orderby) {
		if (rt == null)
			return; // 递归基,空树直接返回
		switch (orderby) {
		case 1: // 先序遍历访问根结点
			list.insertLast(rt);
			orderRecursion(rt.getLeftChild(), list, orderby); // 遍历左子树
			orderRecursion(rt.getRightChild(), list, orderby); // 遍历右子树
			break;
		case 2: // 中序遍历访问根结点
			orderRecursion(rt.getLeftChild(), list, orderby); // 遍历左子树
			list.insertLast(rt);
			orderRecursion(rt.getRightChild(), list, orderby); // 遍历右子树
			break;
		case 3: // 后续遍历访问根结点
			orderRecursion(rt.getLeftChild(), list, orderby); // 遍历左子树
			orderRecursion(rt.getRightChild(), list, orderby); // 遍历右子树
			list.insertLast(rt);
			break;
		}
	}

	// 二叉树先序遍历非递归算法
	public Iterator preOrder(BinaryTreeNode bt, LinkedList list) {
		Stack s = new SingleLinkedStack();
		BinaryTreeNode p = bt;// 找到最左节点
		while (p != null) {
			while (p != null) {
				list.insertLast(p);// 访问根节点
				if (p.hasRightChild()) {// 右子树压栈
					s.push(p.getRightChild());
				}
				p = p.getLeftChild();// 继续访问左子树直到为空
			}
			if (!s.isEmpty()) {
				p = (BinaryTreeNode) s.pop();// 当当前左子树遍历完成,存右子树的栈退栈
			}
		}
		return list.elements();
	}

	// 找到最左节点
	private BinaryTreeNode goFarLeft(BinaryTreeNode bt, Stack s) {
		if (bt == null) {
			return null;
		}
		while (bt.hasLeftChild()) {
			s.push(bt);
			bt = bt.getLeftChild();
		}
		return bt;
	}

	// 二叉树中序遍历的非递归算法
	public Iterator midOrder(BinaryTreeNode bt, LinkedList list) {
		Stack s = new SingleLinkedStack();
		BinaryTreeNode p = goFarLeft(bt, s);// 找到最左节点
		// 如果最左节点不为空则继续查找
		while (p != null) {
			// 中序访问当前节点
			list.insertLast(p);
			if (p.hasRightChild()) {
				// 如果有右孩子节点,则访问有孩子节点的最左孩子节点
				p = goFarLeft(p.getRightChild(), s);
			} else if (!s.isEmpty()) {
				// 如果没有右孩子节点且栈不为空,则弹栈往回找上一级
				p = (BinaryTreeNode) s.pop();
			} else {
				p = null;// 栈为空则查找完成
			}
		}
		return list.elements();
	}

	// 二叉树后序遍历非递归算法
	public Iterator lastOrder(BinaryTreeNode bt, LinkedList list) {
		Stack s = new SingleLinkedStack();
		BinaryTreeNode p = bt;// 找到最左节点
		BinaryTreeNode pre = null;// 缓存上次访问节点
		// 如果最左节点不为空则继续查找
		while (p != null || !s.isEmpty()) {
			while (p != null) {// 查找最左节点
				s.push(p);
				p = p.getLeftChild();
			}
			if (!s.isEmpty()) {
				// 取出栈顶节点
				p = (BinaryTreeNode) s.peek();
				// 判断当前节点是否是父亲节点的右子节点,如果是
				// 只需访问其父节点即可完成以p的父节点为根节点的子树的访问
				if (!p.hasRightChild() || p.getRightChild() == pre) {
					list.insertLast(p);
					s.pop();
					pre = p;
					p = null;
				} else {
					p = p.getRightChild();
				}
			}
		}
		return list.elements();
	}

	private void genRoot() {
		root = new BinaryTreeNode("-");
		BinaryTreeNode a = new BinaryTreeNode("a");
		BinaryTreeNode b = new BinaryTreeNode("b");
		BinaryTreeNode c = new BinaryTreeNode("c");
		BinaryTreeNode d = new BinaryTreeNode("d");
		BinaryTreeNode e = new BinaryTreeNode("e");
		BinaryTreeNode f = new BinaryTreeNode("f");
		BinaryTreeNode plus = new BinaryTreeNode("+");
		BinaryTreeNode minus = new BinaryTreeNode("-");
		BinaryTreeNode multiply = new BinaryTreeNode("*");
		BinaryTreeNode except = new BinaryTreeNode("/");

		root.setLeftChild(plus);
		root.setRightChild(except);
		plus.setLeftChild(a);
		plus.setRightChild(multiply);
		multiply.setLeftChild(minus);
		multiply.setRightChild(d);
		minus.setLeftChild(b);
		minus.setRightChild(c);
		except.setLeftChild(e);
		except.setRightChild(f);
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值