二叉树的先序、中序、后序、层次遍历的递归和非递归解法

二叉树的先序、中序、后序、层次遍历的递归和非递归解法

package tree;

import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;

public class TreeTraverse {
	/**
	 * 先序递归
	 * @param root
	 */
	public static void preOrderTraverse(TreeNode root) {
		if (root == null) {
			return;
		}

		System.out.print(root.val + " ");
		preOrderTraverse(root.left);
		preOrderTraverse(root.right);
	}

	/**
	 * 先序非递归
	 * @param root
	 */
	public static void preOrderTraverseNoR(TreeNode root) {
		if (root == null) {
			return;
		}

		Stack<TreeNode> st = new Stack<TreeNode>();
		TreeNode pNode = root;

		while (pNode != null || !st.isEmpty()) {
			if (pNode != null) {
				System.out.print(pNode.val + " ");
				st.push(pNode);
				pNode = pNode.left;
			} else {
				pNode = st.pop();
				pNode = pNode.right;
			}
		}
	}

	/**
	 * 中序递归
	 * @param root
	 */
	public static void inOrderTraverse(TreeNode root) {
		if (root == null) {
			return;
		}

		inOrderTraverse(root.left);
		System.out.print(root.val + " ");
		inOrderTraverse(root.right);
	}

	/**
	 * 中序非递归
	 * @param root
	 */
	public static void inOrderTraverseNoR(TreeNode root) {
		if (root == null) {
			return;
		}

		Stack<TreeNode> st = new Stack<TreeNode>();
		TreeNode pNode = root;

		while (pNode != null || !st.isEmpty()) {
			if (pNode != null) {
				st.push(pNode);
				pNode = pNode.left;
			} else {
				pNode = st.pop();
				System.out.print(pNode.val + " ");
				pNode = pNode.right;
			}
		}
	}

	/**
	 * 中序递归
	 * @param root
	 */
	public static void postOrderTraverse(TreeNode root) {
		if (root == null) {
			return;
		}

		postOrderTraverse(root.left);
		postOrderTraverse(root.right);
		System.out.print(root.val + " ");
	}

	/**
	 * 后序非递归
	 * @param root
	 */
	public static void postOrderTraverseNoR(TreeNode root) {
		if (root == null) {
			return;
		}

		Stack<TreeNode> st = new Stack<TreeNode>();
		st.push(root);
		TreeNode pNode = null;
		TreeNode preNode = null;
		while (!st.isEmpty()) {
			pNode = st.peek();
			// 如果当前节点没有子结点或者子结点被访问过
			if ((pNode.left == null && pNode.right == null) || (preNode != null && (pNode.left == preNode || pNode.right == preNode))) {
				System.out.print(pNode.val + " ");
				preNode = st.pop();
			} else {
				if (pNode.right != null) {
					st.push(pNode.right);
				} 

				if (pNode.left != null) {
					st.push(pNode.left);
				}
			}
		}
	}

	/**
	 * 层次遍历
	 * @param root
	 */
	public static void levelOrderTraverse(TreeNode root) {
		if (root == null) {
			return;
		}

		Queue<TreeNode> q = new LinkedList<TreeNode>();
		q.offer(root);
		TreeNode pNode = null;
		while (!q.isEmpty()) {
			pNode = q.poll();
			System.out.print(pNode.val + " ");
			if (pNode.left != null) {
				q.offer(pNode.left);
			}
			if (pNode.right != null) {
				q.offer(pNode.right);
			}
		}
	}

	public static void main(String[] args) {
		TreeNode node0 = new TreeNode(0);
		TreeNode node1 = new TreeNode(1);
		TreeNode node2 = new TreeNode(2);
		TreeNode node3 = new TreeNode(3);
		TreeNode node4 = new TreeNode(4);
		TreeNode node5 = new TreeNode(5);
		TreeNode node6 = new TreeNode(6);
		TreeNode node7 = new TreeNode(7);
		TreeNode node8 = new TreeNode(8);
		node1.left = node0;
		node4.left = node2;
		node4.right = node6;
		node2.left = node1;
		node2.right = node3;
		node6.left = node5;
		node6.right = node7;
		node7.right = node8;

		preOrderTraverse(node4);
		System.out.println();
		preOrderTraverseNoR(node4);
		System.out.println();
		inOrderTraverse(node4);
		System.out.println();
		inOrderTraverseNoR(node4);
		System.out.println();
		postOrderTraverse(node4);
		System.out.println();
		postOrderTraverseNoR(node4);
		System.out.println();
		levelOrderTraverse(node4);
	}
}
时间: 2024-10-12 07:40:39

二叉树的先序、中序、后序、层次遍历的递归和非递归解法的相关文章

数据结构:二叉树(前,中,后,层次)非递归遍历。

#include <iostream> #include <stack> #include <map> #include <queue> #include <string.h> using namespace std; struct Node { char data; Node *left; Node *right; Node(char d = char()):data(d),left(NULL),right(NULL){} }; class T

leetcode(144,94,145,102)中迭代版的二叉树的前、中、后、层级遍历

//前序遍历class Solution{ public: vector<int> preorderTraversal(TreeNode *root){ vector<int> res; stack<TreeNode*> s; TreeNode* p = root; if(!p) return res; s.push(p); while(!s.empty()){ p = s.top(); s.pop(); res.push_back(p->val); if(p-&

Java数据结构四之——二叉树的前、中、后序遍历

程序来自Program Creek 前 Preorder binary tree traversal is a classic interview problem about trees. The key to solve this problem is to understand the following: What is preorder? (parent node is processed before its children) Use Stack from Java Core lib

二叉树的前序、中序、后序遍历(递归、非递归)实现

本文部分来源于CSDN兰亭风雨大牛的原创.链接为http://blog.csdn.net/ns_code/article/details/12977901 二叉树是一种非常重要的数据结构,很多其他数据机构都是基于二叉树的基础演变过来的.二叉树有前.中.后三种遍历方式,因为树的本身就是用递归定义的,因此采用递归的方法实现三种遍历,不仅代码简洁且容易理解,但其开销也比较大,而若采用非递归方法实现三种遍历,则要用栈来模拟实现(递归也是用栈实现的).下面先简要介绍三种遍历方式的递归实现,再详细介绍三种遍

【数据结构与算法】二叉树递归与非递归遍历(附完整源码)(转)

转自:http://blog.csdn.net/ns_code/article/details/12977901 二叉树是一种非常重要的数据结构,很多其他数据机构都是基于二叉树的基础演变过来的.二叉树有前.中.后三种遍历方式,因为树的本身就是用递归定义的,因此采用递归的方法实现三种遍历,不仅代码简洁且容易理解,但其开销也比较大,而若采用非递归方法实现三种遍历,则要用栈来模拟实现(递归也是用栈实现的).下面先简要介绍三种遍历方式的递归实现,再详细介绍三种遍历方式的非递归实现. 一.三种遍历方式的递

二叉树遍历算法——包含递归前、中、后序和层次,非递归前、中、后序和层次遍历共八种

首先,要感谢网上的参考资料. http://mengliao.blog.51cto.com/876134/1178079(作者:BlackAlpha) http://blog.csdn.net/fzh1900/article/details/14056735(作者:_云淡风轻) http://blog.csdn.net/stpeace/article/details/8138458(作者:stpeace) 二叉树是使用的比较广泛的一种数据结构,这里我写了二叉树的相关操作,包括初始化.新建.以及遍

算法进化历程之“根据二叉树的先序和中序序列输出后序序列”

巧若拙(欢迎转载,但请注明出处:http://blog.csdn.net/qiaoruozhuo) 前不久在看到一个作业"根据二叉树的先序和中序序列输出后序序列",当时我参考<数据结构与算法(C语言)习题集>上的做法,先根据先中序序列确定一颗二叉树,然后后序遍历二叉树输出后序序列. 函数采用了递归算法,利用函数传入的先序和中序序列的左右边界,确定要处理的序列段,生成相应的二叉树. 基本思路是,把该段先序序列的第一个元素作为当前二叉树的根结点,然后在中序序列找到根结点.根结点

通过二叉树的中序序列和后序序列获取前序序列

二叉树的遍历方式常见的三种是:先序遍历(ABC).中序遍历(BAC).后序遍历(BCA) 先序遍历: 若二叉树为空,则空操作:否则: 访问根结点; 先序遍历左子树: 先序遍历右子树. 中序遍历: 若二叉树为空,则空操作:否则: 中序遍历左子树: 访问根结点: 中序遍历右子树. 后序遍历: 若二叉树为空,则空操作:否则: 后序遍历左子树: 后序遍历右子树: 访问根结点. 在学习到 根据遍历序列确定二叉树 时,知道了:可以通过二叉树的先中或者中后遍历序列唯一确定一棵二叉树. 根据算法描述 使用jav

先序序列和后序序列并不能唯一确定二叉树

数据结构的基础知识中重要的一点就是能否根据两种不同遍历序列的组合(有三种:先序+中序,先序+后序,中序+后序),唯一的确定一棵二叉树.然后就是根据二叉树的不同遍历序列(先序.中序.后序),重构二叉树.显然,这三种组合并不是都能唯一确定二叉树的,其中先序+后序就不能唯一确定一棵二叉树,其他两种组合可以唯一的确定一颗二叉树. 由先序序列和后序序列不能唯一确定一棵二叉树,因无法确定左右子树两部分. 反例:任何结点只有左子树的二叉树和任何结点只有右子树的二叉树,其前序序列相同,后序序列相同,但却是两棵不