根据先序及中序,或根据后序和中序确定二叉树 【java】【递归实现】

在学习树中有这样一个问题,如何根据一颗二叉树的先序序列及中序序列确定二叉树,或是根据后序序列和中序序列确定二叉树。(只有先序和后序是无法唯一确定一颗二叉树的)

在网上查资料的时候很少看到将两个合起来写的,但其实其过程有相似性,用结构相似的代码更能体现其算法本质。书中给出了先序加中序的解法,解法的思想是递归,基本上就是模拟人思维解这个问题,重点在于角标的确定。

先序+中序

调用时传入的参数为:先序序列,中序序列,先序起点,先序终点,中序起点,中序终点,下一步的根节点位置

public void reConstructBinaryTreeCore_xianxu(int[] pre, int[] in, int preStart, int preEnd, int inStart, int inEnd,Node tree) {
        //创建当前节点
        tree = new Node(pre[preStart]);
        int m = inStart;
        //在中序中定位根
        while (in[m] != pre[preStart]){
            m++;
        }
        //递归建立左子树
        if (m == inStart){
            tree.leftchild = null;
        }else {
            reConstructBinaryTreeCore_xianxu(pre,in,preStart+1,preStart+m-inStart,inStart,m-1,tree.leftchild);
        }
        //递归建立右子树
        if (m == inEnd){
            tree.rightchild = null;
        }else {
            reConstructBinaryTreeCore_xianxu(pre,in,preStart+m-inStart+1,preEnd,m+1,inEnd,tree.rightchild);
        }
    }

中序加后序

可以看到只有脚标不同,程序结构完全相同,参数意义相同,理解脚标时根据人工过程来模拟就比较好理解

    public void reConstructBinaryTreeCore(int[] pre, int[] in, int preStart, int preEnd, int inStart, int inEnd,Node tree) {
        tree = new Node(pre[preEnd]);
        int m = inStart;
        //在中序中定位根
        while (in[m] != pre[preEnd]){
            m++;
        }
        //递归建立左子树
        if (m == inStart){
            tree.leftchild = null;
        }else {
            reConstructBinaryTreeCore(pre,in,preStart,preStart+m-inStart-1,inStart,m-1,tree.leftchild);
        }
        //递归建立右子树
        if (m == inEnd){
            tree.rightchild = null;
        }else {
            reConstructBinaryTreeCore(pre,in,preStart+m-inStart,preEnd-1,m+1,inEnd,tree.rightchild);
        }
    }

我实现的树的结构如下:

class Node{//节点的数据结构
    int data;
    Node leftchild;
    Node rightchild;
    public Node(int num){
        this.data = num;
        this.leftchild = null;
        this.rightchild = null;
    }
}

class mytree_Linkedlist{//树的结构就是一个头指针就够了,没有采用递归的方式定义树
    private Node head;
    public mytree_Linkedlist(){
        this.head = null;
    } ...//后续就是一些方法,详细见我另一篇博客(目前还在写)

正确性通过先序遍历,中序遍历,后续遍历等可以验证。



猜你喜欢

转载自blog.csdn.net/u011010851/article/details/79705022