二叉树遍历:先序、中序、后序、层次遍历

二叉树遍历

  所谓遍历(Traversal)是指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问。访问结点所做的操作依赖于具体的应用问题。 遍历是二叉树上最重要的运算之一,是二叉树上进行其它运算之基础。



先序、中序、后序 (深度优先搜索DFS) 遍历思想

  从二叉树的递归定义可知,一棵非空的二叉树由根结点及左、右子树这三个基本部分组成。因此,在任一给定结点上,可以按某种次序执行三个操作:

⑴访问结点本身(N),
⑵遍历该结点的左子树(L),
⑶遍历该结点的右子树(R)。

  1. NLR:前序遍历(Preorder Traversal 亦称(先序遍历))

访问根结点的操作发生在遍历其左右子树之前。

2.LNR:中序遍历(Inorder Traversal)

访问根结点的操作发生在遍历其左右子树之中(间)。

3.LRN:后序遍历(Postorder Traversal)

访问根结点的操作发生在遍历其左右子树之后。

递归实现

在这里插入图片描述

前序遍历:1 2 4 5 3 6 7 8

中序遍历:4 2 5 1 3 7 6 8

后序遍历:4 5 2 7 8 6 3 1

源代码如下:

class Node {
	public int data;
	public Node leftNode;
	public Node rightNode;

	Node(int data) {
		this.data = data;
		leftNode = null;
		rightNode = null;
	}
}

public class BinTree {

	public static void main(String[] args) {
             //构建二叉树操作
		preOrderTraversal(n1);
		System.out.println();
		inOrderTraversal(n1);
		System.out.println();
		postOrderTraversal(n1);

	}

	public static void preOrderTraversal(Node node) {  //先序遍历
		if (node != null) {
			System.out.print(node.data + " ");
			preOrderTraversal(node.leftNode);
			preOrderTraversal(node.rightNode);
		}
	}

	public static void inOrderTraversal(Node node) {  //中序遍历
		if (node != null) {
			inOrderTraversal(node.leftNode);
			System.out.print(node.data + " ");
			inOrderTraversal(node.rightNode);
		}
	}

	public static void postOrderTraversal(Node node) {  //后序遍历
		if (node != null) {
			postOrderTraversal(node.leftNode);
			postOrderTraversal(node.rightNode);
			System.out.print(node.data + " ");
		}
	}

}

非递归实现

源代码如下

public static void preOrderTraversal(Node root) { // 先序遍历
		Stack<Node> s = new Stack<Node>();
		Node p = root;
		while (p != null || !s.isEmpty()) {
			while (p != null) { // 将左节点全部压入栈中
				System.out.print(p.data + " ");
				s.push(p);
				p = p.leftNode;
			}
			if (!s.isEmpty()) { // 左节点为空的情况下转向右子树
				p = s.pop();
				p = p.rightNode;
			}
		}
	}

	public static void inOrderTraversal(Node root) { // 中序遍历
		Stack<Node> s = new Stack<Node>();
		Node p = root;
		while (p != null || !s.isEmpty()) {
			while (p != null) { // 将左节点全部压入栈中
				s.push(p);
				p = p.leftNode;
			}
			if (!s.isEmpty()) { // 左节点为空的情况下转向右子树
				p = s.pop();
				System.out.print(p.data + " ");
				p = p.rightNode;
			}
		}
	}

	public static void postOrderTraversal(Node root) { // 后序遍历
		/*
		 * preOrderTraversal前序遍历顺序是:输出->左子树->右子树,postOrderTraversal后序遍历顺序是:左子树->右子树->输出
		 * 	输出->右子树->左子树为后序遍历的逆序,将这些数据压入S2栈中,再一一出栈,即可的到二叉树的后序遍历
		 */
		Stack<Node> s1 = new Stack<Node>();
		Stack<Node> s2 = new Stack<Node>();
		Node p = root;
		while (p != null || !s1.isEmpty()) {
			while (p != null) { // 将右节点全部压入s1、s2栈中
				s2.push(p);  //System.out.print(p.data + " "); 可以输出后序遍历的逆序
				s1.push(p);
				p = p.rightNode;
			}
			if (!s1.isEmpty()) {
				p = s1.pop();
				p = p.leftNode;
			}
		}

		while (!s2.isEmpty()) // 打印全部数据
			System.out.print(s2.pop().data + " ");

	}



层次遍历 (广度优先搜索BFS) 遍历思想

  除了先序遍历、中序遍历、后序遍历外,还可以对二叉树进行层序遍历。设二叉树的根节点所在层数为1,层序遍历就是从所在二叉树的根节点出发,首先访问第一层的树根节点,然后从左到右访问第2层上的节点,接着是第三层的节点,以此类推,自上而下,自左至右逐层访问树的结点的过程就是层序遍历。

  二叉树层次遍历所用到的算法是广度优先搜索(Breadth First Search),广度优先搜索使用**队列(queue)**来实现,首先将把根节点放到队列的末尾;其次每次从队列的头部取出一个元素,查看这个元素所有的下一级元素(左右子树),把它们放到队列的末尾,直到完成遍历。

在这里插入图片描述

按照上图以此类推,直到队列为空。层次遍历:1 2 3 4 5 6 7 8。

源代码如下:

public static void LevelOrderTraversal(Node root) { // 层次遍历
		Queue<Node> q = new LinkedList<Node>();
		if (root == null)
			return;
		Node n = root;
		q.offer(n);

		while (!q.isEmpty()) {
			n = q.poll();
			System.out.print(n.data + " ");

			if (n.leftNode != null)
				q.offer(n.leftNode);
			if (n.rightNode != null)
				q.offer(n.rightNode);
		}
	}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值