二叉树的遍历

树(tree)是n个结点的有限集。n=0时表示树为空树。在任意一棵非空树中,有且只有一个结点为根结点(root),当n>1时,其余结点可以分为许多个互不相交的有限集T1、T2···,其中每一个集合本身也是一棵树,并且成为根结点的子树。

如果把上述中的很多集合换为两个集合,就成了树中一种实用价值比较高的树,成为二叉树。这样二叉树最多有两棵子树,分别是左子树和右子树。下面简单说下二叉树的一些规律:

性质一:在二叉树的第i层上至多有2的i-1次方个结点;
性质二:深度为k的二叉树至多有2的k次方减1个结点;
性质三:对于任意一棵二叉树,其叶子结点数为n0,度为2的结点数为n2,度为1的结点数为n1,则有n0=n2+1;
性质四:就有n个结点的完全二叉树的深度为对log2(n)取下限+1;
性质五:对有n个结点的完全二叉树按层序排序,则有:(1)i=1,根结点,无双亲;i>1,根节点为对i/2取下限。(2)如果存在,则i结点的左孩子为2i,右孩子为2i+1。

二叉树的遍历方法一般有四种:前序遍历、中序遍历、后序遍历、层序遍历。前三种是根据根结点在左结点和右结点之间的位置决定的,“根左右”就是前序遍历,“左根右”就是中序遍历,“左右根”就是后序遍历。而层序遍历字如其义,就是简单的从上到下,从左到右的依次遍历。层序遍历用的较少,此处不做研究。但是我们应该清楚前三种遍历方法的实现及根据前序(后序)和中序重新构建树,或者得到后序(前序)遍历的结果,下面就以上几个问题作如下实现。

结点结构:

class TreeNode {
    int value;
	TreeNode left;
	TreeNode right;

	public TreeNode(int value) {
		this.value = value;
	}

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

前序遍历:

public void prePrint(TreeNode root) {
	if (root != null) {
			System.out.print(root.value + " ");
			prePrint(root.left);
			prePrint(root.right);
    }
}

中序遍历:

public void midPrint(TreeNode root) {
		if (root != null) {
			midPrint(root.left);
			System.out.print(root.value + " ");
			midPrint(root.right);
		}
}

后序遍历:

public void backPrint(TreeNode root) {
	    if (root != null) {
		    backPrint(root.left);
		    backPrint(root.right);
		    System.out.print(root.value + " ");
	    }
}

由前序、中序重建二叉树:

public TreeNode treeConstruct(int[] pre, int[] mid) {
	if (pre == null || mid == null || pre.length == 0 || mid.length == 0)
		return null;
	else
		return treeCons(pre, mid, 0, pre.length - 1, 0, mid.length - 1);
 }

 private TreeNode treeCons(int[] pre, int[] mid, int preStart, int preEnd,
	int midStart, int midEnd) {
	int rootValue = pre[preStart];
	TreeNode root = new TreeNode(rootValue);
	if (preStart == preEnd) {
		if (midStart == midEnd && pre[preStart] == mid[midEnd])
			return root;
		else
			throw new IllegalArgumentException(
					"pre[] and mid[] can't match");
	}
	int rootIndex = midStart;
	while (rootIndex <= midEnd && mid[rootIndex] != rootValue) {
		rootIndex++;
	}
	if (rootIndex == midEnd && mid[rootIndex] != rootValue)
		throw new IllegalArgumentException();
	int offset = rootIndex - midStart;
	int preLeftRight = preStart + offset;
	if (offset > 0)
		root.left = treeCons(pre, mid, preStart + 1, preLeftRight,
				midStart, rootIndex - 1);
	if (preLeftRight < preEnd - preStart)
		root.right = treeCons(pre, mid, preLeftRight + 1, preEnd,
				rootIndex + 1, midEnd);
	return root;
 }
posted @ 2015-09-21 19:52  torresliang  阅读(214)  评论(0编辑  收藏  举报