每日一题 -- 树
序列化与反序列化
序列化与反序列化
思考:
- 这道题其实就是让你了解一下,为啥我们做树题的时候,明明在做树题(或者链表)这些题目的时候,控制台的例子都是数组,而不是一个可视化的树结构的数据,之前我一直很难理解,直到了解到序列化和反序列化之后。
- 个人理解这是为了兼容不同语言内置数据结构的不同而做出来的优化策略,比方说 JS 就没有树这种结构,所以我们在做树的时候,需要自己构建一个类,然后用我们常用的数据结构转成树,然后再进行运算,而这个过程,其实就是树的反序列化。而数组,字符串这些作为基本数据结构,几乎在常用语言中都会内置,所以就成了树这些结构序列化结构的优先选择。
- 其实最开始我是不知道这叫做序列化,但是我们肯定有尝试在本地中进行测试,而如果入参树结构是一个脑壳痛的问题,所以一般都是写好 utils 方法,通过数组转成树,然后再作为实参传进去。如下:
class TreeNode {
constructor(val) {
this.val = val
this.left = null
this.right = null
}
}
class Tree {
constructor(arr) {
let nodeList = []
let length = arr.length
let root
for (let i = 0; i < length; i++) {
const node = new TreeNode(arr[i])
nodeList.push(node)
if (i > 0) {
let parentIndex = Math.floor((i - 1) / 2)
const parent = nodeList[parentIndex]
if (parent.left) {
parent.right = node
} else {
parent.left = node
}
}
}
root = nodeList.shift()
nodeList.length = 0
return root
}
}
module.exports = {
Tree,
TreeNode
}
const { Tree } = require('./util/Tree')
const root = new Tree([1, null, 2, 3])
const result = preTravel(root)
console.log(result)
- 同时序列化和反序列化是一组函数,也就是我用数组转成树,我得有一个方法,将树重新转回数组才行。
- 这就是我在序列化和反序列学习中的一点点感悟
正文:
- 这道题参考学习了 leetcode-solution-leetcode-pp.gitbook.io/leetcode-so…
- 题目给的例子都是返回数组字符串,这很直观,但是 JS 中数组其实不属于基本数据类型,所以如果用数组存储,然后还得用 JSON.stringify 来转,反序列化的时候还得 parse 一下,感觉不太好,所以还得沿用字符串这种基本数据类型比较 nice
- 这里用到了完全二叉树中,根节点与左右节点下标的关系,只是使用的时候是直接将 i 进行累加,不喜欢的可以按照 2n+1 的方式去写,只需要循环的终止条件要注意一下。
var serialize = function (root) {
if (!root) return ''
let res = ''
const queue = []
queue.push(root)
while (queue.length) {
let len = queue.length
const temp = ''
const flag = false
while (len--) {
const root = queue.shift()
if (!root) {
temp += 'null,'
} else {
flag = true
temp += root.val + ','
queue.push(root.left)
queue.push(root.right)
}
}
if(flag) res+=temp
}
return res.slice(0, -1)
};
var deserialize = function (data) {
if (!data) return null
const nodes = data.split(',')
const root = new TreeNode(nodes[0])
const queue = []
queue.push(root)
let i = 0
while (queue.length && i < nodes.length - 2) {
const root = queue.shift()
lv= nodes[i+1]
rv= nodes[i+2]
i+=2
if(lv!=='null'){
const ln = new TreeNode(lv)
root.left = ln
queue.push(ln)
}
if(rv!=='null'){
const rn = new TreeNode(rv)
root.right = rn
queue.push(rn)
}
}
return root
};