您的位置:首页 > 编程语言 > Python开发

二叉树序列化、反序列化、层次遍历python

2018-07-22 15:41 309 查看

一、二叉树的分层遍历

给定一棵二叉树,要求进行分层遍历,每层的节点值单独打印一行,下图给出事例结构:

思路:

增加两个TreeNode:last和nlast

  • last:表示当前遍历层最右结点
  • nlast:表示下一层最右结点

(本质,就是每当某个节点的左右孩子进入队列,该节点被弹出,如果该节点等于last值,默认遍历完该层节点,之后另last=nlast,之后再碰到弹出的值与last值相等,继续上述操作)

从根结点开始,将根结点放入队列①,之后弹出根结点①,每弹出一个结点就先后将其左右结点②③放入队列中,由于队列先进先出,因此先取出的是②,然后将④⑤放入到队列中,然后从队列中取出一个结点,由于队列先进新出,此时取出的是之前放入的③,再将⑤⑥放入队列,再将⑦8放入队列中,此时弹出的是⑤,由于从第二层开始总是从左到右放入队列,下一层的结点一定是在当前层的结点之后才放入并且也是从左到右放入的,因此总体顺序必然是从上到下,从左到右的。

白话描述:last=1,nlast=2,3即其左右孩子,输出左右孩子后,队列中弹出1,1==last,此时last=nlast=3(赋值操作),因为2先进入队列,队列中进入其左孩子,弹出2,再进入3的左右孩子,nlast=5,6,弹出3,此时弹出的3==last,故新last=nlast=6(赋值操作),nlast=7,8,弹出5,又6没有左右孩子,弹出6==last,此时last=nlast=8(赋值操作),7没有孩子节点,弹出7,再弹出8=last=nlast,打印完毕(即last=nlast完全相等时说明打印完毕) 。

二、二叉树的序列化与反序列化

(1)二叉树序列化(持久化)

即:二叉树–》字符串
二叉树的序列化是指:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串,从而使得内存中建立起来的二叉树可以持久保存。

序列化可以基于 先序、中序、后序、按层 的二叉树遍历方式来进行修改。原理都是一样的(即遍历顺序不同而已,对每个结点的处理都是一样的),序列化的结果是一个字符串,序列化时通过 某种符号表示空节点(#),以 ! 表示一个结点值的结束(value!)。
先序序列化二叉树==定义一个stringbuilder保存序列过程中的结果:按照先序遍历方式遍历二叉树,若结点非空则把 “结点值!” append到builder中;若结点空则把 “#!” append到builder中;最后用builder生成字符串就是序列化结果。

(2)二叉树反序列化

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

三、python代码实现

class bintree(object):
def __init__(self,x):
self.val=x
self.left=None
self.right=None
class solution(object):
#二叉树的反序列化:
#通过对一个列表的处理,来完成反序列化,即从根节点开始,每完成一个节点的左右孩子处理,即删除该点,同时列表添加该点的左右孩子节点,
#依次类推,直到所有节点被处理完,此时,列表中应当没有节点,因此while条件是列表长度不为0
def strtotree(self,strlist):
if len(strlist)==0 or strlist==None:
return None

first=strlist.pop(0)
#找到根节点
root=bintree(first)
re_list=[]
re_list.append(root)

while len(re_list)!=0:
left=strlist.pop(0)
right=strlist.pop(0)

if left!='#!'and right!='#!':
binleft=bintree(left)
binright=bintree(right)
re_list[0].left=binleft
re_list[0].right=binright

re_list.append(binleft)
re_list.append(binright)
re_list.pop(0)

elif left=='#!'and right!='#!':
binright=bintree(right)
re_list[0].right=binright

re_list.append(binright)
re_list.pop(0)
elif left!='#!'and right=='#!':
binleft=bintree(left)
re_list[0].left=binleft

re_list.append(binleft)
re_list.pop(0)
else:
re_list.pop(0)
return root
#二叉树的序列化(思想是有两个列表,把放树的那个列表依次移到新的列表中并删除原来对应的部分,
#其中也转化形式,直到放树的列表中所有参数移完为止,因此列表的循环条件是原来放树的列表长度不为0)
def seralize(self,root):
temp,ch=[root],[]
while len(temp)!=0:
m=temp.pop(0)
if m==None:
ch.append('#!')
else:
temp.append(m.left)
temp.append(m.right)
ch.append(m.val+'!')
return ch

#二叉树的层次遍历打印输出:
#方法一(23ms.5708K):
def Print(self, root):
# write code here
last,nlast=root,root
queue,xiangtaoqueue=[root],[]
newqueue=[]
while len(queue)!=0:
m=queue.pop(0)
newqueue.append(m.val)
if m.left!=None:

nlast=m.left
queue.append(nlast)
if m.right!=None:
nlast=m.right
queue.append(nlast)
if m==last:
last=nlast
xiangtaoqueue.append(newqueue)
newqueue=[]
return xiangtaoqueue
#方法二:(29ms,5604k)

def Print(self, root):
if not root:
return []
nodeStack = [root]
result = []
while nodeStack:
res = []
nextStack = []
for i in nodeStack:
res.append(i.val)
if i.left:
nextStack.append(i.left)
if i.right:
nextStack.append(i.right)
nodeStack = nextStack
result.append(res)
return result
s = solution()
root = s.strtotree(strlist =['A!', 'B!', 'C!', '#!', 'D!', '#!', 'E!', 'F!', '#!', '#!', '#!', '#!', '#!'])
s.cengciprint(root)
阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: