前言

               我们知道遍历一颗二叉树一般有三种方式:先序、中序、后序。而且每一颗二叉树的三种遍历

          方式的结果各自都是唯一的。但是有可能一颗二叉树的先序遍历结果和另一个不同的二叉树的中

          序遍历结果是相同的。我们能够有二叉树求得其三种遍历结果,那么我们有可能根据三种遍历结果

          去确定一颗二叉树么?

      二叉树的确定

               1、三种单独的遍历方式无法确定二叉树。

         略微思考一下就可以明白,先序遍历只能确定其根节点,对于之后的情况是完全无法确定的,同样

         的对于中序,后序遍历就也会存在这种情况.。证明不好说,我们直接用一个反例来说明。

                假设先序遍历的结果为ABCD。可以看出的是对于其结果会存在不同的二叉树的先序遍历都为

         ABCD。因此只是先序遍历是无法确定一棵二叉树的。

                            

                    至于后序和中序的情况就不在反证了。

               既然单个的遍历情形无法确定二叉树那么我们来通过组合看能否确定一棵二叉树。

                    2、已知先序和中序可以确定一棵二叉树。

                         ● 如果先序和中序遍历都是空的,这确定一棵空二叉树。

                         ● 对于有n(n>=2)个结点的情况先序遍历中的第一个结点必然是二叉树的根结点,然后在

               中序遍历中找到根结点,这样就唯一确定了根结点了。在中序遍历序列中根结点前面的序列就是

               根结点的左子树的中序遍历序列。同理在先序遍历中根结点之后到中序遍历中的根节点的那部分

               序列就是根节点的做子树的先序遍历。这样递归下去就可以确定唯一确定左子树。根节点的右子

               树的分析同理。

                   3、中序遍历和后序遍历可以唯一确定一颗二叉树。

                          具体的分析参见2.

                   4、先序遍历和后序遍历无法确定一颗二叉树。

                          略微思考一下就明白了,此种情况只能确定根节点,但是根节点的左子树,右子树序列根

                本无法确定。

          先序、中序确定二叉树实现

                  进过上述分析,我们知道了二叉树的确定可以通过两种情况来确定,也就是先序和中序组合,后序

              中序组合。这里我们对前者的组合方式做一个实现,下面是代码部分。 

package com.kiritor;

public class TestBinaryTree {

	public static void main(String[] args) {
		BinaryTree bt = new BinaryTree();
		bt.root = BinaryTree.createBT("ABDCEGFHI", "DBAEGCHFI");
		System.out.println("PreOrder:");// 先序输出
		bt.preOrder(bt.root);
		System.out.println("\n");
		System.out.println(" Inorder:");// 中序输出
		bt.inOrder(bt.root);
		System.out.println("\n");
		System.out.println(" PostOrder:");// 后序输出
		bt.postOrder(bt.root);

	}

}

class BinaryTree {
	protected BinaryTreeNode root;

	public BinaryTree() {
		root = null;
	}

	public BinaryTree(char element) {
		root = new BinaryTreeNode(element);
	}

	public BinaryTree(char element, BinaryTree leftTree, BinaryTree rightTree) {
		root = new BinaryTreeNode(element);
		if (leftTree != null) {
			root.left = leftTree.root;
		}
		if (rightTree != null) {
			root.right = rightTree.root;
		}
	}

	public void preOrder(BinaryTreeNode node) {
		if (node != null) {
			System.out.print(node.element);
			preOrder(node.left);
			preOrder(node.right);
		}
	}

	public void inOrder(BinaryTreeNode node) {
		
		if (node != null) {
			inOrder(node.left);
			System.out.print(node.element);
			inOrder(node.right);
		}
	}

	public void postOrder(BinaryTreeNode node) {
	
		if (node != null) {
			postOrder(node.left);
			postOrder(node.right);
			System.out.print(node.element);
		}
	}

	// 利用先序表达式和中序表达式构建一棵字符二叉树
	public static BinaryTreeNode createBT(String pres, String ins) {
		int inpos = 0;
		BinaryTreeNode root;
		String leftPres, leftIns, rightPres, rightIns;
		if (pres.length() == 0 || ins.length() == 0) {
			return null;
		} else {
			root = new BinaryTreeNode(pres.charAt(0));//首先就可以确定根结点了
			//之后确定中序遍历中的根结点的位置
			while (((Character) ins.charAt(inpos)) != root.element)
				inpos++;
            //递归确定左结点
			leftPres = pres.substring(1, inpos + 1);
			leftIns = ins.substring(0, inpos);
			root.left = createBT(leftPres, leftIns);
            //递归生成右结点
			rightPres = pres.substring(inpos + 1, pres.length());
			rightIns = ins.substring(inpos + 1, ins.length());
			root.right = createBT(rightPres, rightIns);
		}
		return root;
	}

}

class BinaryTreeNode {

	protected char element;
	protected BinaryTreeNode left, right;

	BinaryTreeNode(char obj) {
		element = obj;
		left = null;
		right = null;
	}
}
           输出结果:

                         

       

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐