模拟Leetcode通过字符串生成二叉树

二叉树的反序列化

通过一个字符串来实现构造一棵二叉树, 方便在leetcode刷题时进行本地调试

例题

297. 二叉树的序列化与反序列化

实现方案

代码逻辑:

  1. 将字符串中的数据提取出来, 存放到vector容器中
  2. 使用索引i来控制遍历容器中的数据
  3. 使用queue来辅助层次遍历, 每次在加入队列的时候创建节点, 在弹出队列的时候为该节点的left指针right指针赋值

注意事项:

  • vector中会保存"null"字符串, 但是queue中只保存非"null"对应的节点
  • queue每次弹出节点时, 索引i指向的为当前节点的左子节点对应的字符串, 可能为"null". 在执行i++之后便会对应到当前节点的右子节点.
  • 经过两次i++后, 索引i对应的正好是下一个弹出节点的左子节点
  • 给出的字符串可能省略了最后的一堆连续的"null", 所以使用if(i < vec_string.size())进行判断

C++版本


struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;

    TreeNode() : val(0), left(nullptr), right(nullptr) {}

    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}

    TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};



TreeNode *deserialize(const vector<string> &vec_string) {

    const string FLAG = "null";
    /**
     * 队列中保存的值都是非null节点
     */
    queue<TreeNode *> queue;
    TreeNode *root = new TreeNode(stoi(vec_string[0]));
    queue.push(root);
    int i = 1;
    while (!queue.empty()) {
        int size = queue.size();
        while (size--) {
            TreeNode *peek = queue.front();
            queue.pop();
            if (i < vec_string.size()) {
                //左子节点
                if (vec_string[i] != FLAG) {
                    queue.push(new TreeNode(stoi(vec_string[i])));
                    peek->left = queue.back();
                }
                i++;
            }
            if (i < vec_string.size()) {
                //由于上面i++,因此此时指向右子节点
                if (vec_string[i] != FLAG) {
                    queue.push(new TreeNode(stoi(vec_string[i])));
                    peek->right = queue.back();
                }
                i++;
            }

        }
    }
    return root;
}



TreeNode *deserialize(string data) {
    vector<string> vec_string;
    string word;
    for (int i = 0; i <= data.size(); i++) {
        if (i == data.size() || data[i] == ',') {
            vec_string.push_back(word);
            word.clear();
        } else {
            word += data[i];
        }
    }
    return deserialize(vec_string);
}

Java版本

import java.util.ArrayList;
import java.util.Deque;
import java.util.LinkedList;
import java.util.Queue;


/**
 * 二叉树
 *
 */
public class BinaryTree implements Order {

	//测试案例
    public static void main(String[] args) {
        String s = "1,2,#,#,3";
        BinaryTree binaryTree = new BinaryTree(s);
        binaryTree.preOrder();
    }
    
    /**
     * 二叉树的节点, 内部类
     */
    class Node {
        public int val;
        public Node left;
        public Node right;
        public Node next;

        public Node() {
        }

        public Node(int val) {
            this.val = val;
        }

        public Node(int val, Node left, Node right, Node next) {
            this.val = val;
            this.left = left;
            this.right = right;
            this.next = next;
        }
    }

    Node root;

    public BinaryTree(String data) {
        this.root = deserialize(data);
    }

    private Node deserialize(ArrayList<String> words) {
        final String FLAG = "#";
        Deque<Node> queue = new LinkedList<>();
        Node root = new Node(Integer.parseInt(words.get(0)));
        queue.add(root);
        int i = 1;
        while (!queue.isEmpty()) {
            int size = queue.size();
            while (size-- > 0) {
                Node peek = queue.peek();
                assert peek != null;
                queue.poll();
                if (i < words.size()) {
                    //左子节点
                    if (!words.get(i).equals(FLAG)) {
                        queue.add(new Node(Integer.parseInt(words.get(i))));
                        peek.left = queue.getLast();
                    }
                    i++;
                }
                if (i < words.size()) {
                    //由于上面i++,因此此时指向右子节点
                    if (!words.get(i).equals(FLAG)) {
                        queue.add(new Node(Integer.parseInt(words.get(i))));
                        peek.right = queue.getLast();
                    }
                    i++;
                }

            }
        }
        return root;
    }

    private Node deserialize(String data) {
        ArrayList<String> words = new ArrayList<>();
        StringBuilder word = new StringBuilder();
        for (int i = 0; i <= data.length(); i++) {
            if (i == data.length() || data.charAt(i) == ',') {
                words.add(word.toString());
                word = new StringBuilder();
            } else {
                word.append(data.charAt(i));
            }
        }
        return deserialize(words);
    }

	private void preOrder(Node root) {
        if (root == null) {
            return;
        }
        System.out.println(root.val);
        preOrder(root.left);
        preOrder(root.right);
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值