数据结构-二叉树(先序+中序,中序+后序建立二叉树递归实现)

 

文章目录

 

思路

为何先序+中序,或者中序+后序能够创造一颗二叉树?java

由于先序能够知道这颗树的根,后序也能够知道这颗树的根,那么再去看中序,中序的根就找到了,中序根左边的子树是左子树,中序根右边的是右子树,也就是说经过先序先肯定根,而后中序找到根与左右子树,而后对左子树递归找根,对右子树递归找根,一直找不到为止node

递归的思路是什么呢?数组

以先序+中序举例,先序先找到根,而后中序能够划分出左子树+根+右子树的形式,而后咱们能够轻松拿到中序左子树的数组和中序右子树的数组,咱们知道根据一个树的先序+中序能够很快在中序中肯定根在哪,因此咱们如今已经有了中序的左子树和右子树,而且他们都是按照中序的规则,那先序的根的左子树和右子树序列在哪呢?依然在原先序序列中找,既然咱们已经在中序中找到了左子树和右子树序列,那么在先序中就很容易找出,由于要知道先序序列知足前面是根,中间一部分是左子树,最后一块是右子树的形式,中序知足最左边一块是左子树,中间根,右边右子树,后序的话左边是左子树,中间右子树,最后是根。
咱们经过对中序的左子树递归找根,中序的右子树递归找根,一直到结点为 null 返回为止ide

Java 实现
// 结点
class Node {
    int data;
    Node left = null;
    Node right = null;
}

// 二叉树
public class BinaryTree {
    // 根结点
    private Node root;
    // 输入的数组
    private int[] arr_in;
    // 输出的数组
    private int[] arr_out;
    // 记录数组下标
    private static int index;
    
    // 初始化
    public BinaryTree(int[] arr) {
        root = new Node();
        this.arr_in = arr;
        arr_out = new int[arr.length];
        index = 0;
    }

	// 根据先序遍历和中序遍历建立二叉树
    public Node createByPreAndIn(int[] preArr, int[] inArr) {
        if (preArr.length > 0) {
            Node node = new Node();
            node.data = preArr[0];

            int i;
            for (i = 0; preArr[0] != inArr[i]; i++) ;

            // 中序左子树
            int[] leftInArr = new int[i];
            // 中序右子树
            int[] rightInArr = new int[inArr.length - i - 1];
            // 先序左子树
            int[] leftPreArr = new int[i];
            // 先序右子树
            int[] rightPreArr = new int[inArr.length - i - 1];

            System.arraycopy(inArr, 0, leftInArr, 0, leftInArr.length - 1);
            System.arraycopy(inArr, i + 1, rightInArr, 0, rightInArr.length - 1);
            System.arraycopy(preArr, 1, leftPreArr, 0, leftPreArr.length - 1);
            System.arraycopy(preArr, i + 1, rightInArr, 0, rightPreArr.length - 1);

            node.left = createByPreAndIn(leftPreArr, leftInArr);
            node.right = createByPreAndIn(rightPreArr, rightInArr);
            
            return node;
        }
        else
            return null;
    }

    // 根据中序遍历和后序遍历建立二叉树
    public Node createByInAndPost(int[] inArr, int[] postArr) {
        if (inArr.length > 0) {
            Node node = new Node();
            node.data = postArr[postArr.length];

            int i;
            for (i = 0; postArr[postArr.length] != inArr[i]; i++) ;

            // 中序左子树
            int[] leftInArr = new int[i];
            // 中序右子树
            int[] rightInArr = new int[inArr.length - i - 1];
            // 后序左子树
            int[] leftPostArr = new int[i];
            // 后序右子树
            int[] rightPostArr = new int[inArr.length - i - 1];

            System.arraycopy(inArr, 0, leftInArr, 0, leftInArr.length - 1);
            System.arraycopy(inArr, i + 1, rightInArr, 0, rightInArr.length - 1);
            System.arraycopy(postArr, 0, leftPostArr, 0, leftPostArr.length - 1);
            System.arraycopy(postArr, i, rightPostArr, 0, rightPostArr.length - 1);

            node.left = createByInAndPost(leftInArr, leftPostArr);
            node.right = createByInAndPost(rightInArr, rightPostArr);

            return node;
        }
        else
            return null;
    }