已知先序中序求后序-已知后序中序求先序-JAVA

通过递归遍历的方法扫描先序中序,构造二叉树;
通过递归遍历的方法扫描后序中序,构造二叉树;
方法理解起来很简单,在纸上自己画画就知道如何去做了,该算法难点在于遍历中需要精确的数学计算,还需要清晰的判断逻辑。

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();
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值