二叉树【按层打印、序列化、反序列化】
二叉树按层打印
算法
准备一个队列
准备一个二叉树,不一定是完全二叉树
准备一个变量last,表示当前层的最后一个节点
准备一个变量next_last,表示下一层的最后一个节点
将root节点首先放入队列中
- 此时last 是root nlast还没有值
- 从队列中拿出root节点,并打印
- 判断root节点的子节点是否存在,如果存在放入队列中,每次放入节点的时候将子节点赋值给nlast
- 拆开说明,假设root两个节点分别是A,B
- 将A节点放入队列中,指定next_last为 A,因为此时并不知道是否有B存在,
- 将B 节点放入队列中,指定next_last为B ,此时很明确第二层的最后一个节点是B
- 如果A节点不存在的话,直接放入B即可,每次放入前需要进行判断是否存在
- 如果没有子节点,队列中将没有节点可以打印,直接跳出循环
- 此时判断一件事情,当前打印的节点root 切好等于 当前last存储的节点 root,打印换行'\n'
- 并让last 等于 next_last也就说,当前层已经换成了第二层了。next_last目前保持不变
- 梳理变量:last为节点B,next_last为节点B,队列中有A,B
- 假设A 有一个左节点C ,B有一个有节点D
- 由于放入了A B 两个节点循环继续,拿出A,并打印,将A的子节点C放入队列中,并使得next_last等于C
- 此时还是判断当前打印的节点A与last中存储的节点B不相同,所以不换行,由于队列有值循环继续
最终循环会因为队列中没有节点而停止
代码准备工作
注:测试代码使用Python,Python版本3.6
节点类:Node
# 每个节点需要的东西,
# 1.节点存储的值
# 2.节点的左子节点
# 3.节点的右子节点
class Node():def __init__(self,value):self.value = valueself.left_node=Noneself.right_node=None
队列类:Queue
# 队列即先进先出的list,队列类需要的属性
# 1.队列大小
# 2.队列中的值,用list表示
# 3.队列的尾部
# 4.在队列尾部插入数据
# 5.在队列头部读取数据
# 6.队列是否为空
# 7.队列是否被塞满
class Queue():def __init__(self,size):self.size = sizeself.queue=[]self.end=-1def in_queue(self,value):if self.queue_is_full():print('Queue full')else:# append 在list尾端插入数据self.queue.append(value)# 插入一个后top变成了0,依次+1self.end = self.end+1def out_queue(self):if self.queue_is_empty():print('No data')else:# pop(0) 从list的头部拿出一个数据data = self.queue.pop(0)self.end=self.end-1return datadef queue_is_full(self):# end 是顶部的index +1后等于size就证明没有位置了if self.end+1 == self.size:return Trueelse:return Falsedef queue_is_empty(self):if self.end == -1:return Trueelse:return False
代码实现
main函数
if __name__ == "__main__":# 创建二叉树rootNode = Node('root')A = Node('A')B = Node('B')# 跟节点 有两个子节点 A BrootNode.left_node = ArootNode.right_node = BC = Node('C')D = Node('D')# A有左子节点CA.left_node = C# B有有子节点DB.right_node = D# 按层打印上面的二叉树last = rootNode # 初始nlast = rootNode # 初始store_queue = Queue(5)#创建一个大小为5的队列store_queue.in_queue(rootNode)# 初始放入rootNodewhile store_queue.queue:# 取出nodetmp_node = store_queue.out_queue()# 打印print(tmp_node.value,end=' ')# 放入子节点if tmp_node.left_node is not None:store_queue.in_queue(tmp_node.left_node)nlast = tmp_node.left_nodeif tmp_node.right_node is not None: store_queue.in_queue(tmp_node.right_node)nlast = tmp_node.right_node# 判断是否换行if tmp_node == last:print("\n")last = nlast
#### 结果
rootA BC D
快速创建二叉树,通过list进行创建
def make_binary_tree(list):if list is None:list = ['root',['A',['C'],None],['B',None,['D']]]rootNode = Node(list[0])if len(list) >= 2 :if list[1] is not None:rootNode.left_node = make_binary_tree(list[1])if len(list) >= 3 :if list[2] is not None :rootNode.right_node = make_binary_tree(list[2])return rootNode
二次测试
if __name__ == "__main__":# make binary tree data'''rootNode = Node('root')A = Node('A')B = Node('B')rootNode.left_node = ArootNode.right_node = BC = Node('C')D = Node('D')A.left_node = CB.right_node = D'''list = ['root',['A',['C',['E'],['F']],['D',['G',['H'],None],None]],['B',['I',None,['J']],['K',['L'],None]]]rootNode = make_binary_tree(list)# 按层打印上面的二叉树last = rootNode # 初始nlast = rootNode # 初始store_queue = Queue(5)#创建一个大小为5的队列store_queue.in_queue(rootNode)# 初始放入rootNodewhile store_queue.queue:# 取出nodetmp_node = store_queue.out_queue()# 打印print(tmp_node.value,end=' ')# 放入子节点if tmp_node.left_node is not None:store_queue.in_queue(tmp_node.left_node)nlast = tmp_node.left_nodeif tmp_node.right_node is not None: store_queue.in_queue(tmp_node.right_node)nlast = tmp_node.right_node# 判断是否换行if tmp_node == last:print("\n")last = nlast
## 结果
rootA BC D I KE F G J LH
二叉树序列化
算法
- 前序遍历:按照 根-左-右,中序遍历 左-根-右,后序遍历 左-右-根
- 定义一个空字符串,
- 取出根节点Value+‘!’,拼接字符串,‘!’是每个节点value的结束标志
- 先判断左节点是否存在,存在如3的方式同样拼接
- 不存在拼接 '#!'
- 依次下去,直到遍历完毕所有的节点
代码准备工作
Node类
同上
创建二叉树方法
同上
序列化方法
# 前序
def pre_serialize_binary_tree(node):string = ''string = string + str(node.value)+'!'if node.left_node is not None:string = string + serialize_binary_tree(node.left_node)else:string = string + "#!"if node.right_node is not None:string = string + serialize_binary_tree(node.right_node)else:string = string + "#!"return string
# 中序
def mid_serialize_binary_tree(node):string = ''#string = string + str(node.value)+'!'if node.left_node is not None:string = string + mid_serialize_binary_tree(node.left_node)else:string = string + "#!"string = string + str(node.value)+'!'if node.right_node is not None:string = string + mid_serialize_binary_tree(node.right_node)else:string = string + "#!"return string
# 后序
def back_serialize_binary_tree(node):string = ''if node.left_node is not None:string = string + back_serialize_binary_tree(node.left_node)else:string = string + "#!"if node.right_node is not None:string = string + back_serialize_binary_tree(node.right_node)else:string = string + "#!"string = string + str(node.value)+'!'return string
代码实现
main函数
if __name__ == "__main__":list = ['root',['A',['C',['E'],['F']],['D',['G',['H'],None],None]],['B',['I',None,['J']],['K',['L'],None]]]rootNode = make_binary_tree(list)result1 = pre_serialize_binary_tree(rootNode)print("前序遍历")print(result1)#rootNode = ascertain_root_node(rootNode)print("中序遍历")result2 = mid_serialize_binary_tree(rootNode)print(result2)print("后序遍历")result3 = back_serialize_binary_tree(rootNode)print(result3)
## 结果
前序遍历
"root!A!C!E!#!#!F!#!#!D!G!H!#!#!#!#!B!I!#!J!#!#!K!L!#!#!#!"
中序遍历
"#!E!#!C!#!F!#!A!#!H!#!G!#!D!#!root!#!I!#!J!#!B!#!L!#!K!#!"
后序遍历
"#!#!E!#!#!F!C!#!#!H!#!G!#!D!A!#!#!#!J!I!#!#!L!#!K!B!root!"
二叉树反序列化
算法
- 将序列化好的字符串按照节点结束符拆分成数组
- 根据前序、中序、后序的规则,将数组数据重新组成二叉树
- 为# 的时候为空节点,赋值None
代码准备工作
Node类
同上
按层打印二叉树的方法
同上
反序列化函数
# 前序
def pre_deserialize_binary_tree(node_list):tmp_node = node_list.pop(0)rootNode = Node(tmp_node)if tmp_node != "#":rootNode.left_node = pre_deserialize_binary_tree(node_list)rootNode.right_node = pre_deserialize_binary_tree(node_list)else:return Nonereturn rootNode
# 中序
# 注:实在没找到中序反序列化的方法,望大神指点一下
按层打印二叉树方法
# 抽成方法 以备使用
def print_tree(rootNode):# 按层打印上面的二叉树last = rootNode # 初始nlast = rootNode # 初始store_queue = Queue(100)#创建一个大小为5的队列store_queue.in_queue(rootNode)# 初始放入rootNodewhile store_queue.queue:# 取出nodetmp_node = store_queue.out_queue()# 打印print(tmp_node.value,end=' ')# 放入子节点if tmp_node.left_node is not None:store_queue.in_queue(tmp_node.left_node)nlast = tmp_node.left_nodeif tmp_node.right_node is not None: store_queue.in_queue(tmp_node.right_node)nlast = tmp_node.right_node# 判断是否换行if tmp_node == last:print("\n")last = nlast
代码实现
main函数
if __name__ == "__main__":# make binary tree datalist = ['root',['A',['C',['E'],['F']],['D',['G',['H'],None],None]],['B',['I',None,['J']],['K',['L'],None]]]rootNode = make_binary_tree(list)result1 = pre_serialize_binary_tree(rootNode)print("前序遍历")print(result1)#rootNode = ascertain_root_node(rootNode)print("中序遍历")result2 = mid_serialize_binary_tree(rootNode)print(result2)print("后序遍历")result3 = back_serialize_binary_tree(rootNode)print(result3)# 直接使用上面序列化的结果tree_list1 = result1.strip(" ").split('!')tree_list1.pop()de_result1 = pre_deserialize_binary_tree(tree_list1)# 按层打印print_tree(de_result1)# 继续序列化进行对比test = pre_serialize_binary_tree(de_result1)print(test)print(result1)
# ----------------------------Result----------------------------
rootA BC D I KE F G J LH"root!A!C!E!#!#!F!#!#!D!G!H!#!#!#!#!B!I!#!J!#!#!K!L!#!#!#!"
"root!A!C!E!#!#!F!#!#!D!G!H!#!#!#!#!B!I!#!J!#!#!K!L!#!#!#!"
转载于:https://www.cnblogs.com/primadonna/p/10443569.html
二叉树【按层打印、序列化、反序列化】相关推荐
- 二叉树的深度优先搜索c语言,C语言 二叉树按层打印、深度优先遍历、二叉树是否对称...
#include//二叉树节点 typedef struct tree{ int data; struct tree *pLeft; struct tree *pRight; }Tree; //队列 ...
- leetcode 637. Average of Levels in Binary Tree | 637. 二叉树的层平均值(Java)
题目 https://leetcode-cn.com/problems/average-of-levels-in-binary-tree/ 题解 1.参考"二叉树按层打印"写的解法 ...
- 左神算法:二叉树的按层打印与ZigZag打印(Java版)
本题来自左神<程序员代码面试指南>"二叉树的按层打印与ZigZag打印"题目. 题目 给定一棵二叉树的头节点 head,分别实现 按层 和 ZigZag 打印 二叉树的 ...
- 95-268-280-源码-Flink通信层的序列化与反序列化
文章目录 1.概述 2.Flink通信层的序列化 3.Flink 序列化过程 1.概述 当两个进程在进行远程通信时,彼此可以发送各种类型的数据.无论是何种类型的数据,都会以二进制序列的形式在网络上传送 ...
- 【Java】用Jackson进行JSON序列化/反序列化操作
Java类和JSON Speaker类: import java.util.ArrayList; import java.util.Arrays; import java.util.List;publ ...
- 一个更好的C++序列化/反序列化库Kapok
1.Kapok的特点 简单,易用,header-only,只需要引用Kapok.hpp即可:高效,初步测试性和messagepack相当. 它是纯c++11实现,因此需要支持C++11的编译器. 2. ...
- Python数据结构与算法题目 打印二叉树的左视图 打印二叉树的右视图 树的左视图 树的右视图
阅读目录 题目描述 思路与Python实现 题目描述 输入一棵二叉树,求出树的左视图,或者右视图,如下图所示,的两种情况 思路与Python实现 如果可以用非递归的方式写出二叉树的深度遍历或者广度遍历 ...
- 二叉树的ZigZag打印-Java
分享一个大牛的人工智能教程.零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请轻击http://www.captainbed.net package live.every.day.Pro ...
- json序列化c语言,C语言JSON序列化/反序列化
最近想找一个C语言处理嵌套结构体和结构体数组的json库,理想的是能够很容易处理复杂结构体嵌套,并且使用简单的,但是没找到比较合适的,于是打算自己封装一个: 两个问题: C语言结构体本身没有元数据,这 ...
最新文章
- Go 语言 Session机制和 Cookie机制
- 《ASP.NET Web 站点高级编程》勘误 Part 3
- Python 怎么样在函数内部对全局变量进行修改
- 微信公众号授权步骤详细步骤介绍和整合springboot开发(java版)
- “面试不败计划”:面试题基础二
- 【高速接口-RapidIO】Xilinx SRIO IP 核详解
- ac算法 有什么用 Java_AC算法使用例子
- struts2--java.lang.IllegalAccessException: Class ognl.OgnlRuntime can not access a member of
- gin+vue的前后端分离开源项目
- maven 整体打包_Maven打包方式整理
- 促销海报灵感素材,不卖出去都难
- BERT-BiLSTM-CRF基于BERT预训练的中文命名实体识别TensorFlow实现
- 关于团队合作开发项目时的沟通问题!(不仅要注意【相关机能】,还要注意【相似功能】)
- [转载] Python数据可视化库-Matplotlib——折线图绘制
- 【译】AS3利用CPU缓存
- Stream介绍及简单操作!
- agax分页查询必知知识,分页必须参数详解
- 网吧软件经典大集合.各种网管工具
- 企业开票信息税号查询API接口服务
- 云计算对传统软件工程的影响