【数据结构】二叉树(遍历方法、递归实现)的JAVA代码实现

二叉树的遍历

二叉树的遍历是指按照某种顺序访问二叉树中的每个结点,使每个结点被访问一次且仅被访问一次。通过一次完整的遍历,可使二叉树中的结点信息由非线性排列变成某种意义上的线性序列。也就是说,遍历操作是非线性结构线性化。

由二叉树的定义可知,一棵二叉树由根结点、左子树和右子树三部分组成。因此,只需要依次遍历这三个部分,就可以遍历整个二叉树。若以D、L、R分别表示访问根结点、遍历根结点的左子树和遍历根结点的右子树,则二叉树的遍历方式有6种,它们的含义如下表所示:

 先左后右先右后左
先序遍历DLRDRL
中序遍历LDRRDL
后序遍历LRDRLD

如果限定先左后右,则只有前三种方式。但这只是由根结点到左右子树结点的方式来遍历,其实还有一种遍历方式,层次遍历。下面就来讨论这四种遍历方式。

二叉树的遍历方式

先序遍历

先序遍历的递归过程为:若二叉树为空,遍历结束;否则,访问根结点,先序遍历根结点的左子树,先序遍历根结点的右子树。

对于上图的先序遍历,先遍历根结点A,再遍历A的左子树。而要遍历A的左子树,先遍历A的左子树的根结点B,再遍历它的左子树。如此循环。最终得到的结点序列:ABDGHCEIF。

	public void preorder(Node<E> p) {
		if (isEmpty()) {
			System.out.println("Tree is empty");
			return;
		}
		if (p != null) {
			System.out.print(p.getData() + " ");
			preorder(p.getLchild());
			preorder(p.getRchild());
		}
	}

中序遍历

中序遍历的递归过程为:若二叉树为空,遍历结束;否则,中序遍历根结点的左子树,访问根结点,中序遍历根结点的右子树。

对于上图的中序遍历,要遍历A根点,先遍历它的左子树。要遍历A的左子树,就要遍历它左子树的左子树。也就是说,最开始遍历的是最左边的结点G。然后遍历根结点,再右子树。如此循环。最终得到的结点序列:GDHBAEICF。

	public void inorder(Node<E> p) {
		if (isEmpty()) {
			System.out.println("Tree is empty");
			return;
		}
		if (p != null) {
			inorder(p.getLchild());
			System.out.print(p.getData() + " ");
			inorder(p.getRchild());
		}
	}

后序遍历

后序遍历的递归过程为:若二叉树为空,遍历结束;否则,后序遍历根结点的左子树,后序遍历根结点的右子树,访问根结点。

对于上图的后序遍历,要遍历A根点,先遍历它的左子树。要遍历A的左子树,就要遍历它左子树的左子树。也就是说,最开始遍历的是还是最左边的结点G。然后遍历右子树,再根结点。如此循环。最终得到的结点序列:GHDBIEFCA。

	public void postorder(Node<E> p) {
		if (isEmpty()) {
			System.out.println("Tree is empty");
			return;
		}
		if (p != null) {
			postorder(p.getLchild());
			postorder(p.getRchild());
			System.out.print(p.getData() + " ");
		}
	}

层次遍历

所谓层次遍历,就是从二叉树的第一层(根结点)开始,从上至下逐层遍历,在同一层,则按照从左至右的顺序对每个结点逐个访问。

层次遍历的基本思想是:由于层次遍历结点的顺序是先遇到的结点先访问,与队列的操作顺序相同。所以,在进行层次遍历时,设置一个队列,将根结点引用入队,当队列非空时,循环执行以下三步:

  1. 从队列中取出一个结点的引用,并访问该节点;
  2. 若该结点的左子树非空,将该结点的左子树引用入队;
  3. 若该结点的右子树非空,将该结点的右子树引用入队。
	public void levelOrder(Node<E> root) {
		// 根结点为空
		if (root == null) {
			return;
		}
		// 设置一个队列保存层序遍历的结点
		Queue<Node<E>> q = new LinkedList<Node<E>>();
		// 根结点入队
		q.add(root);
		// 队列非空,结点没有处理完
		while (!q.isEmpty()) {
			// 结点出队
			Node<E> tmp = q.poll();
			// 处理当前结点
			System.out.print(tmp.getData() + " ");
			// 将当前结点的左孩子结点入队
			if (tmp.getLchild() != null) {
				q.add(tmp.getLchild());
			}
			if (tmp.getRchild() != null) {
				// 将当前结点的右孩子结点入队
				q.add(tmp.getRchild());
			}
		}
	}

总结与分析

二叉树的四种遍历方式,先序遍历、中序遍历、后序遍历、层次遍历,除了层次遍历使用队列的方式之外,其他三种都是采用的递归的方式实现的,而递归是可以用栈的方式来实现的。也就是说二叉树的递归方式说到底也就是栈和队列的两种实现方式。这和图的遍历方式(深度优先、广度优先)的思想是一致的。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值