NC123 序列化二叉树
-
str 返回最终遍历的字符串序列,空节点用
#
表示,非空节点用节点的val
表示 -
每个节点之间使用
!
隔开,因为Serialize
返回的是字符串,所以需要一个分隔符,便于Deserialize
来拆分字符串得到各个节点 -
Serialize
- 特判一下空树返回空字符串
- 借助队列层次遍历二叉树:将根节点放入队列 queue
- 当队列不为空时:取出队头元素,如果队头有左节点,左节点 + ! 拼接到str,如果左节点不存在 #! 拼接到str,右节点也一样。
- 最后返回 str
-
Deserialize
- 将字符串拆分为数组,使用 split ,传入参数为
!
- 注意:s.split(‘!’) 转换数组,最后会多出一个空字符串元素,比如
1!2!#!
最终变成了['1','2','#','']
,最后这个空字符串不需要判断,应该pop()掉。还有就是此时数组中的元素是字符串类型,在new节点的时候,需要转换成Number类型。 - 借助队列 queue 来还原二叉树:
- 先构建根节点 root,放入queue
- 使用指针 i ,遍历数组s ,每两个为一组,为队头元素的左右节点,如果左右节点不为空,左右节点分别入队,直到数组s遍历结束。
- 返回 root
- 将字符串拆分为数组,使用 split ,传入参数为
function TreeNode(x) {
this.val = x;
this.left = null;
this.right = null;
}
function Serialize(pRoot)
{
if(pRoot === null) return ''
let str = ''
let queue = []
queue.push(pRoot)
str += pRoot.val + '!'
while(queue.length !== 0){
let font = queue.shift()
if(font.left){
str += font.left.val + '!'
queue.push(font.left)
}else{
str += '#!'
}
if(font.right){
str += font.right.val + '!'
queue.push(font.right)
}else{
str += '#!'
}
}
console.log(str)
return str
}
function Deserialize(s)
{
if(s === '') return null
s = s.split('!')
s.pop()//将最后一个空字符串元素pop出去
console.log(s)
let i = 1
let root = new TreeNode( Number(s[0]) )
let queue = [root]
while(i < s.length ){
let font = queue.shift()
if(s[i] !== '#'){
font.left = new TreeNode(Number(s[i]))
queue.push(font.left)
}
i ++
if(s[i] !== '#'){
font.right = new TreeNode(Number(s[i]))
queue.push(font.right)
}
i ++
}
return root
}
module.exports = {
Serialize : Serialize,
Deserialize : Deserialize
};