通过递归遍历的方法扫描先序中序,构造二叉树;
通过递归遍历的方法扫描后序中序,构造二叉树;
方法理解起来很简单,在纸上自己画画就知道如何去做了,该算法难点在于遍历中需要精确的数学计算,还需要清晰的判断逻辑。
public class BinaryTree {
//内部Node类
private static class Node {
private Node left;
private Node right;
private char value;
public Node(char value) {
this.value = value;
}
public Node() {
}
public void setLeft(Node left) {
this.left = left;
}
public void setRight(Node right) {
this.right = right;
}
public void setValue(char value) {
this.value = value;
}
public char getValue() {
return value;
}
public Node getLeft() {
return left;
}
public Node getRight() {
return right;
}
}
public BinaryTree() {
// TODO Auto-generated constructor stub
}
//已知a为一个先序字符数组,b为一个中序字符数组,a1为a的起始点,b1为b的起始点,size为两个数组的大小
public void build(Node node, char[] a, int a1, char[] b, int b1, int size) {
node.setValue(a[a1]);
//寻找中序数组中的值与 先序数组的首个值 相等的位置i
for(int i = b1; i < b1 + size; i++) {
if(b[i] == a[a1] ) {
//如果位置i左半部分还有值,寻找先序中与左半部分对应的部分,之后build左半部分
if(i - 1 >= b1) {
Node left = new Node();
node.setLeft(left);
build(left, a, a1 + 1, b, b1, i - b1);
}
//如果位置i右半部分还有值,寻找先序中与右半部分对应的部分,之后build右半部分
if(i + 1 <= b1 + size - 1) {
Node right = new Node();
node.setRight(right);
build(right, a, a1 + 1 + i - b1, b, i + 1, size - (i - b1) - 1);
}
break;
}
}
}
//已知a为一个后序字符数组,b为一个中序字符数组,a1为a的起始点,b1为b的起始点,size为两个数组的大小
public void build2(Node node, char[] a, int a1, char[] b, int b1, int size) {
node.setValue(a[a1 + size - 1]);
//寻找中序数组中的值与 后序数组的最后一个值 相等的位置i
for(int i = b1; i < b1 + size; i++) {
//如果位置i左半部分还有值,寻找后序中与左半部分对应的部分,之后build左半部分
if(b[i] == a[a1 + size - 1]) {
if(b1 <= i - 1) {
Node left = new Node();
node.setLeft(left);
build2(left, a, a1, b, b1, i - b1);
}
//如果位置i右半部分还有值,寻找后序中与右半部分对应的部分,之后build右半部分
if(i + 1 <= b1 + size - 1) {
Node right = new Node();
node.setRight(right);
build2(right, a, a1 + i -b1, b, i + 1, b1 + size - 1 - i);
}
break;
}
}
}
public void sayPre(Node node) {
System.out.print(node.getValue());
if(node.getLeft() != null) sayPre(node.getLeft());
if (node.getRight() != null) sayPre(node.getRight());
}
public void sayMid(Node node) {
if(node.getLeft() != null) sayMid(node.getLeft());
System.out.print(node.getValue());
if (node.getRight() != null) sayMid(node.getRight());
}
public void sayAfter(Node node) {
if(node.getLeft() != null) sayAfter(node.getLeft());
if (node.getRight() != null) sayAfter(node.getRight());
System.out.print(node.getValue());
}
public static void main(String[] args) {
Node node = new Node();
BinaryTree binaryTree = new BinaryTree();
char a[] = {'G','D','A','F','E','M','H','Z'};
char b[] = {'A','D','E','F','G','H','M','Z'};
binaryTree.build(node, a, 0, b, 0, a.length);
System.out.print("sayPre:");
binaryTree.sayPre(node);
System.out.println();
System.out.print("sayMid:");
binaryTree.sayMid(node);
System.out.println();
System.out.print("sayAfter:");
binaryTree.sayAfter(node);
System.out.println();
char c[] = {'A','E','F','D','H','Z','M','G'};
char d[] = {'A','D','E','F','G','H','M','Z'};
Node node2 = new Node();
binaryTree.build2(node2, c, 0, d, 0, c.length);
System.out.print("sayPre:");
binaryTree.sayPre(node2);
System.out.println();
System.out.print("sayMid:");
binaryTree.sayMid(node2);
System.out.println();
System.out.print("sayAfter:");
binaryTree.sayAfter(node2);
System.out.println();
}
}