• 剑指offer(61):序列化二叉树


    题目描述

    请实现两个函数,分别用来序列化和反序列化二叉树
     
    二叉树的序列化是指:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串,从而使得内存中建立起来的二叉树可以持久保存。序列化可以基于先序、中序、后序、层序的二叉树遍历方式来进行修改,序列化的结果是一个字符串,序列化时通过 某种符号表示空节点(#),以 ! 表示一个结点值的结束(value!)。

    二叉树的反序列化是指:根据某种遍历顺序得到的序列化字符串结果str,重构二叉树。

    例如,我们可以把一个只有根节点为1的二叉树序列化为"1,",然后通过自己的函数来解析回这个二叉树
     
    思路:自己想的思路是采用层次遍历,序列化的时候使用队列,如果结点为空,字符串+“#!”,如果不为空,则字符串+“结点值!”;反序列化过程将字符串按照!分割成字符串数组,然后如果为# ,则为空,否则创建该结点,在反序列化的过程也需要一个队列辅助。
    java层次遍历:
    import java.util.*;
    public class Solution {
        String Serialize(TreeNode root) {
            StringBuffer sb = new StringBuffer();
            //String traverseOrder = "";
            if(root != null){
                Queue<TreeNode> qRoot = new LinkedList<>();
                TreeNode q;
                
                qRoot.add(root);
                while(!qRoot.isEmpty()){
                    q = qRoot.poll();
                    if(q == null) sb.append("#!"); //traverseOrder+="#!";
                    else{
                        sb.append(q.val+"!");
                        //traverseOrder+=q.val+"!";
                        qRoot.add(q.left);
                        qRoot.add(q.right);
                    }
                }
            }
            // return traverseOrder;
            return sb.toString();
      }
        TreeNode Deserialize(String str) {
           if(str.length() == 0) return null;
            
            String[] traverseOrder = str.split("!");
            TreeNode root = new TreeNode(Integer.parseInt(traverseOrder[0]));
            
            Queue<TreeNode> qRoot = new LinkedList<>();
            qRoot.add(root);
            TreeNode p = qRoot.poll();
            for(int i=1;i<traverseOrder.length;i = i+2){
                TreeNode pLeft = null;
                TreeNode pRight = null;
                if(!"#".equals(traverseOrder[i]))
                    pLeft = new TreeNode(Integer.parseInt(traverseOrder[i]));
                if(!"#".equals(traverseOrder[i+1]))
                    pRight = new TreeNode(Integer.parseInt(traverseOrder[i+1]));
                p.left = pLeft;
                p.right = pRight;
                if(p.left != null) qRoot.add(p.left);
                if(p.right != null) qRoot.add(p.right);
                p = qRoot.poll();
            }
            return root;
      }
    }

    思路:参考https://www.nowcoder.com/profile/767712797/codeBookDetail?submissionId=85270378进行先序遍历的实现,一般情况我们需要已知中序遍历和先序遍历或者中序遍历和后序遍历才能构造出二叉树,但是由于我们序列化的过程中引入了空节点(用#代表空节点),因此在反序列化的时候可以通过判断是否为#,而得到终止位置。

    题目中C++提供的是char*类型,使用略有生疏

    class Solution {
    public:
        char* Serialize(TreeNode *root) {   
            if(!root) return "#";
            string res = to_string(root->val);
            res.push_back(',');
            
            char* left = Serialize(root->left);
            char* right = Serialize(root->right);
            
            char* ret = new char[res.length()+strlen(left)+strlen(right)];
            
            strcpy(ret, res.c_str());
            strcat(ret, left);
            strcat(ret, right);
            
            return ret;
        }
       
        TreeNode* Deserialize(char *str) {
            return Deserialize2(str);
            
        }
        
        TreeNode* Deserialize2(char *&s){
            if(*s == '#'){
                s++;
                return nullptr;
            }
            int num = 0;
            while(*s!=','){
                num = num*10+(*s - '0');
                s++;
            }
            ++s;
            TreeNode* root = new TreeNode(num);
            root->left = Deserialize2(s);
            root->right = Deserialize2(s);
            return root;
        }
    };
  • 相关阅读:
    java语法基础
    向linux内核增加一个系统调用-1
    dp-矩阵连乘
    struct和typedef struct
    Ubuntu安装Chrome及hosts修改
    c++primer-p100.用迭代器进行二分法搜索
    c++primer-p101.ex3.24
    c++ vector用法和迭代器
    Bytes和bits的区别(字节和位的区别)
    基于R语言的数据分析和挖掘方法总结——中位数检验
  • 原文地址:https://www.cnblogs.com/ttzz/p/13510672.html
Copyright © 2020-2023  润新知