用前序遍历和Java语言创建二叉树

给定一个树结点值的字符数组,要求利用它的前序遍历创建一棵二叉树。

注意:不能用普通的前序遍历创建,要用带空结点的前序遍历创建二叉树。

如:preOrder=ABC#D###E,创建的二叉树形态为:

思路:根据前序遍历,很容易找到根的值。(下标为0的位置处)。因此每次创建左子树时,传的是原数组长度-1(从原数组下标-1处开始);创建右子树时,应该使用原数组长度-1-左子树创建时所用的个数。因此创建一棵树应该返回两个值,一个是根结点,一个是创建过程中使用的结点数。那么怎么让一个函数返回两个值呢?用类来解决。终止条件:数组为null,返回(null,0)。我们使用'#‘来表示数组中的空结点的值,特殊情况:如果遇到根结点值为'#',空结点没有子树,因此直接返回(null,1)。

具体步骤:

1.先判断是否是终止条件。是,则返回(null,0);不是,继续下一步。

2.然后取根结点的值,就是preOrder[0]的值。

3.判断是否是特殊情况(空结点)。是,则直接返回(null,1)。如果不是,则创建根结点,执行第4步。

4.递归创建根结点的左子树。利用preOrder,找到左子树的前序遍历数组,去掉第一个值。这里传数组,我们使用数组拷贝去实现。Arrays.copyOfRange(原数组名,起始索引,最终索引),复制的数组不包括最后索引的元素。对于左子树,就是Arrays.copyOfRange(preOrder,1,preOrder.length).

5.递归创建根结点的右子树。利用preOrder,找到右子树的前序遍历数组,去掉第一个值,去掉左子树使用的值。Arrays.copyOfRange(preOrder,1+left.used,preOrder.length).其中,left为创建左子树时返回的类。

6.将根、左子树和右子树关联起来。root.left=left.root;root.right=right.root;

7.返回创建好的树和使用的结点数。

使用到的类有:

//结点类  
  public static class Node{
        char val;//值
        Node left;//左子树
        Node right;//右子树
        Node(char val){
            this.val=val;
        }
    }
//返回值类
class CreateTreeResult{
    public TreeMethod.Node root;
    public int used;

    public CreateTreeResult(TreeMethod.Node root, int used) {
        this.root = root;
        this.used = used;
    }
}

完整代码:

package com.xunpu.datastruct.tree;



import java.util.Arrays;
class CreateTreeResult{
    public TreeMethod.Node root;
    public int used;

    public CreateTreeResult(TreeMethod.Node root, int used) {
        this.root = root;
        this.used = used;
    }
}


public class TreeMethod {
    private static int count=0;
    public static class Node{
        char val;//值
        Node left;//左子树
        Node right;//右子树
        Node(char val){
            this.val=val;
        }
    }

    //创建树
    static CreateTreeResult createTree(char[] preOrder){
        //1.判断是否是终止条件
        if(preOrder.length==0){//终止条件  E或E##
            return new CreateTreeResult(null,0);
        }
        //2.获取根结点的值
        char rootValue=preOrder[0];
        //3.判断是否为空结点
        if(rootValue=='#'){
            return new CreateTreeResult(null,1);
        }
        //创建根结点
        Node root=new Node(rootValue);

        //4.创建左子树 利用递归
        char[] leftPreorder=new char[preOrder.length-1];
        leftPreorder= Arrays.copyOfRange(preOrder,1,preOrder.length);
        CreateTreeResult left=createTree(leftPreorder);
//        left.used;//左子树创建过程中使用的个数
//        右子树使用的个数为preOrder.length-1-left.used
        //5.创建右子树  利用递归
        char[] rightPreorder=new char[preOrder.length-1-left.used];
        rightPreorder= Arrays.copyOfRange(preOrder,1+left.used,preOrder.length);
        CreateTreeResult right=createTree(rightPreorder);
        //6.将根、左子树和右子树关联起来
        root.left=left.root;
        root.right=right.root;
        //7.返回树和使用的结点树
        return new CreateTreeResult(root,1+left.used+right.used);
    }
    public static void main(String[] args) {
       char[] array=new char[]{'A','B','C','#','D','#','#','#','E'};
        CreateTreeResult result=createTree(array);
        System.out.println(result.used);
        System.out.println(result.root.left.left.right.val);
        System.out.println(result.root.right.val);
    }
}

 

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值