二叉树的前序,中序,后序,层序遍历实现(递归,迭代两种方式)

先定义Node节点对象

public class Node{
		public int value;

		public Node left;

		public Node right;

		public Node(int value, Node left, Node right) {
			this.value = value;
			this.left = left;
			this.right = right;
		}
	}

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

1, 递归实现

/**
	 * 前序遍历递归实现
	 * @param root 根节点
	 */
	public static void preorderTraversal(Node root) {
		if(root == null) {
			return;
		}
		// 先遍历当前节点
		System.out.println(root.value);
		// 再遍历左子树
		preorderTraversal(root.left);
		// 再遍历右子树
		preorderTraversal(root.right);
	}

2, 迭代实现

/**
	 * 前序遍历迭代实现(借助栈的数据结构)
	 * @param root 根节点
	 */
	public static void preorderTraversalWithStack(Node root) {
		if (root == null) {
			return;
		}
		Stack<Node> stack = new Stack<>();
		stack.push(root);
		while (!stack.isEmpty()) {
			// 先遍历当前节点
			Node node = stack.pop();
			System.out.println(node);
			// 将右子节点先压栈,后遍历
			if (node.right != null) {
				stack.push(node.right);
			}
			// 将左子节点后压栈,先遍历
			if (node.left != null) {
				stack.push(node.left);
			}
		}
	}

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

1, 递归实现

/**
	 * 中序遍历递归实现
	 * @param root 根节点
	 */
	public static void inorderTraversal(Node root) {
		if(root == null) {
			return;
		}
		// 先遍历左子节点
		inorderTraversal(root.left);
		// 再遍历当前节点
		System.out.println(root.value);
		// 最后遍历右子节点
		inorderTraversal(root.right);
	}

2, 迭代实现

/**
	 * 中序遍历迭代实现(借助栈的数据结构)
	 * @param root 根节点
	 */
	public static void inorderTraversalWithStack(Node root) {
		if (root == null) {
			return;
		}
		Stack<Node> stack = new Stack<>();
		Node node = root;
		while(node != null || !stack.isEmpty()) {
			// 对父节点和左子节点循环压栈
			while(node != null) {
				stack.push(node);
				node = node.left;
			}
			// 先遍历后压栈的左子节点,再遍历先压栈的当前节点
			node = stack.pop();
			// 最后遍历右子节点
			node = node.right;
		}
	}

后续遍历: 先遍历左子节点,再遍历右子节点,最后遍历父节点

1, 递归实现

/**
	 * 后续遍历的递归实现
	 * @param root 根节点
	 */
	public static void postorderTraversal(Node root) {
		if (root == null) {
			return;
		}
		// 先遍历左子节点
		postorderTraversal(root.left);
		// 再遍历右子节点
		postorderTraversal(root.right);
		// 最后遍历当前节点
		System.out.println(root.value);
	}

2, 迭代实现

/**
	 * 后续遍历的迭代实现
	 * @param root 根节点
	 */
	public void postorderTraversalWithStack(Node root) {
		if (root == null) {
			return;
		}
		Stack<Node> stack = new Stack<>();
		// 记录上一次遍历到的节点
		Node prev = null;
		while(root != null || !stack.isEmpty()) {
			// 和中序遍历一样,不断将当前节点及其左子节点入栈
			while(root != null) {
				stack.push(root);
				root = root.left;
			}
			// 先弹出左子节点,并不能立马遍历该节点,只有当该节点没有右子节点或者右子节点已经先于它遍历了才能遍历它自己
			root = stack.pop();
			if (root.right == null || root.right == prev) {
				// 遍历当前节点
				System.out.println(root.value);
				// prev记录上一次遍历到的节点
				prev = root;
				// root置为null,是为了继续弹栈
				root = null;
			} else {
				// 说明之前弹出的节点有右子树,且右子树没有遍历过,先将该弹栈的节点压栈
				stack.push(root);
				// 然后继续该节点的右子树
				root = root.right;
			}
		}

	}

层序遍历: 按照层级关系从上到下依次遍历

/**
	 * 层序遍历的迭代实现(使用队列数据结构)
	 * @param root 根节点
	 */
	public static void levelOrderTraversal(Node root) {
		if (root == null) {
			return;
		}
		Queue<Node> queue = new LinkedList<>();
		queue.offer(root);
		while (!queue.isEmpty()) {
			Node node = queue.poll();
			// 遍历当前节点
			System.out.println(node.value);
			// 当前节点的左子节点入队列
			if(node.left != null) {
				queue.offer(node.left);
			}
			// 当前节点的右子节点入队列
			if (node.right != null) {
				queue.offer(node.right);
			}
		}
	}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值