Algorithms_二叉树的前序遍历、中序遍历、后续遍历(深度优先)


在这里插入图片描述


前序、中序、后序的含义

前序遍历: 先输出父节点,再遍历左子树,最后遍历右子树

中序遍历 : 先遍历左子树,再输出父节点,最后遍历右子树

后序遍历 : 先遍历左子树,再遍历右子树,最后输出父节点

如何区分呢?

输出父节点的顺序 ,就可以确定是 前序、中序、后序


实例

我们先来分析下 将 下面的几个数 放到 二分搜索树中会是怎样的存放 。

注意我们这里用的是二分搜索树来演示二叉树的这个遍历,才会有中序遍历的那个排序的特征。


            5     
          /   \   
         3     6   
        / \      \ 
       2   4      8
       

前序遍历: 5 、3、2、4、6、8

中序遍历: 2、3、4、5、6、8

后序遍历 : 2、4、3、8、6、5

其实 , 前序遍历比较常用。

观察中序遍历,可以看到是排序的 ,这个也很好理解。 毕竟是 左侧的都是小于父节点的,右侧都是大于父节点的。

后序遍历的适用场景,举个例子 为二分搜索树释放内存

前序遍历、中序遍历、后续遍历本质上一种深度遍历


Code (递归)

前序遍历

	/**
	 * 
	 * 
	 * @Title: preOrder
	 * 
	 * @Description: 二分搜索树的前序遍历
	 * 
	 * 
	 * @return: void
	 */
	public void preOrder() {
		preOrder(root);
	}

	/**
	 * 
	 * 
	 * @Title: preOrder
	 * 
	 * @Description: 前序遍历以node为根的二分搜索树, 递归算法
	 * 
	 * @param node
	 * 
	 * @return: void
	 */
	private void preOrder(Node node) {
		if (node == null) // 终止条件
			return;

		System.out.print(node.e + "--"); // 先输出父节点
		preOrder(node.left); // 再遍历左子树
		preOrder(node.right); // 最后遍历又子树
	}


中序遍历

/**
	 * 
	 * 
	 * @Title: inOrder
	 * 
	 * @Description: 二分搜索树的中序遍历
	 * 
	 * 
	 * @return: void
	 */
	public void inOrder() {
		inOrder(root);
	}

	/**
	 * 
	 * 
	 * @Title: inOrder
	 * 
	 * @Description: 中序遍历以node为根的二分搜索树, 递归算法
	 * 
	 * @param node
	 * 
	 * @return: void
	 */
	private void inOrder(Node node) {
		if (node == null) // 终止条件
			return;

		inOrder(node.left);
		System.out.println(node.e);
		inOrder(node.right);
	}

后序遍历

/**
	 * 
	 * 
	 * @Title: postOrder
	 * 
	 * @Description: 二分搜索树的后序遍历
	 * 
	 * 
	 * @return: void
	 */
	public void postOrder() {
		postOrder(root);
	}

	/**
	 * 
	 * 
	 * @Title: postOrder
	 * 
	 * @Description: 后序遍历以node为根的二分搜索树, 递归算法
	 * 
	 * @param node
	 * 
	 * @return: void
	 */
	private void postOrder(Node node) {
		if (node == null) // 终止条件
			return; 

		postOrder(node.left);
		postOrder(node.right);
		System.out.println(node.e);
	}

测试

public static void main(String[] args) {
		BinarySearchTree<Integer> bst = new BinarySearchTree<>();

		int[] nums = { 5, 3, 6, 8, 4, 2 };
		for (int num : nums) {
			bst.add(num);
		}

		bst.preOrder();
		System.out.println("============================");

		bst.inOrder();
		System.out.println("============================");

		bst.postOrder();
	}

在这里插入图片描述

Code (非递归)

不用递归也可以实现,我们要借助Stack来实现这个。 推荐使用递归的方式,代码更简洁。

这里把不用递归的代码也贴一下,供参考

/**
	 * 
	 * 
	 * @Title: preOrderNR
	 * 
	 * @Description: 二分搜索树的前序遍历 非递归的方式 栈是LIFO ,前序遍历(先处理左子树,后处理右子树)
	 *               ,需要先把右节点入栈,这样才能确保后处理
	 * 
	 * @return: void
	 */
	public void preOrderNR() {

		Stack<Node> stack = new Stack<>();
		stack.push(root); // 把root入栈
		while (!stack.isEmpty()) {
			Node currentNode = stack.pop();
			System.out.println(currentNode.e);

			if (currentNode.right != null) {
				stack.push(currentNode.right);
			}

			if (currentNode.left != null) {
				stack.push(currentNode.left);
			}
		}

	}
发布了819 篇原创文章 · 获赞 2030 · 访问量 415万+

猜你喜欢

转载自blog.csdn.net/yangshangwei/article/details/104228405