用Java实现二叉链表方式存储的二叉树

给定一颗二叉树的遍历顺序,创建相应的二叉树链表。这里所说的遍历顺序是一种“扩展的遍历序列”,即用“.”来表示空的子树。下面,我们来构建先序遍历序列为AB.DF..G..C.E.H..的二叉链表。


先看书上面使用C语言的实现:

 void CreateBiTree(BiTree *bt){
        char ch;
        ch = getchar();
        if('.' == ch) *bt = NULL;
        else{
            *bt = (BiTree)malloc(sizeof(BiTNode));
            (*bt)->data = ch;
            CreatBiTree(&((*bt)->LChild));
            CreatBiTree(&((*bt)->RChild));
    }
 }

下面用Java来实现上述内容
首先定义二叉树的存储结构

class MyBiTree {
    private Node root;

    public Node getRoot() {
        return root;
    }

    public void setRoot(Node root) {
        this.root = root;
    }

    public MyBiTree() {
        root = new Node();
    }

    static class Node {
        T data;
        Node lChild;
        Node rChild;

        Node() {
            this.lChild = null;
            this.rChild = null;
        }

        Node(T data) {
            this.data = data;
            this.lChild = null;
            this.rChild = null;
        }

        Node(T data, Node lChild, Node rChild) {
            this.lChild = lChild;
            this.rChild = rChild;
        }
    }

    // 树的先序遍历
    public void rootLR(Node root) {
        if (root != null) {
            System.out.println(root.data);
            rootLR(root.lChild);
            rootLR(root.rChild);
        }
    }
}

然后开始构建二叉树

/**
 * 输入树的先序串,构建出一棵树
 * 测试用例:a b . d f . . g . . c . e . h . .
 * */
public class TreeDemo1 {
    //由于使用递归的方式来构建,所以Scanner类不能定义到方法内,而方法内要使用,所以定义为静态
    static Scanner sc = new Scanner(System.in);
    static MyBiTree tree = new MyBiTree<>();

    public static void main(String[] args) {
        CreatTree(tree.getRoot());
        tree.rootLR(tree.getRoot());
    }

    private static Node CreatTree(Node node) {
        String str = sc.next();

        if(str.equals(".")){
            return null;
        }else{
            Node newNode = new Node<>(str);
            node.data = newNode.data;
            node.lChild = CreatTree(new Node());
            node.rChild = CreatTree(new Node());
            return node;
        }
    }
}

我尝试过用书上类似的代码用Java实现,但是发现行不通。深入思考以后才了解,如果使用node = new Node<>(str); 只是将栈内存中方法内的引用指向了一个新的堆内存创建的对象上,没有改变堆内root节点对象,所以应该直接改变堆内存的对象。
所以可以写下:

node.data = newNode.data;
node.lChild = CreatTree(new Node());
node.rChild = CreatTree(new Node());
这样每层迭代构建一个新的节点,将新节点的数据赋值给迭代进来的node,然后将node的左右节点分别迭代,最后返回构建的节点。

为什么在构建左右子树的时候要创建新的节点对象作为参数,而不能直接把newNode作为参数?测试发现不可行。原因有待进一步思考。

你可能感兴趣的:(查漏补缺之数据结构)