二叉树按层打印

算法

  1. 准备一个队列

  2. 准备一个二叉树,不一定是完全二叉树

  3. 准备一个变量last,表示当前层的最后一个节点

  4. 准备一个变量next_last,表示下一层的最后一个节点

  5. 将root节点首先放入队列中

  6. 此时last 是root nlast还没有值
  7. 从队列中拿出root节点,并打印
  8. 判断root节点的子节点是否存在,如果存在放入队列中,每次放入节点的时候将子节点赋值给nlast
    • 拆开说明,假设root两个节点分别是A,B
    • 将A节点放入队列中,指定next_last为 A,因为此时并不知道是否有B存在,
    • 将B 节点放入队列中,指定next_last为B ,此时很明确第二层的最后一个节点是B
    • 如果A节点不存在的话,直接放入B即可,每次放入前需要进行判断是否存在
    • 如果没有子节点,队列中将没有节点可以打印,直接跳出循环
  9. 此时判断一件事情,当前打印的节点root 切好等于 当前last存储的节点 root,打印换行'\n'
  10. 并让last 等于 next_last也就说,当前层已经换成了第二层了。next_last目前保持不变
  11. 梳理变量:last为节点B,next_last为节点B,队列中有A,B
  12. 假设A 有一个左节点C ,B有一个有节点D
  13. 由于放入了A B 两个节点循环继续,拿出A,并打印,将A的子节点C放入队列中,并使得next_last等于C
  14. 此时还是判断当前打印的节点A与last中存储的节点B不相同,所以不换行,由于队列有值循环继续
  15. 最终循环会因为队列中没有节点而停止

代码准备工作

注:测试代码使用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

二叉树序列化

算法

  1. 前序遍历:按照 根-左-右,中序遍历 左-根-右,后序遍历 左-右-根
  2. 定义一个空字符串,
  3. 取出根节点Value+‘!’,拼接字符串,‘!’是每个节点value的结束标志
  4. 先判断左节点是否存在,存在如3的方式同样拼接
  5. 不存在拼接 '#!'
  6. 依次下去,直到遍历完毕所有的节点

代码准备工作

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!"

二叉树反序列化

算法

  1. 将序列化好的字符串按照节点结束符拆分成数组
  2. 根据前序、中序、后序的规则,将数组数据重新组成二叉树
  3. 为# 的时候为空节点,赋值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

二叉树【按层打印、序列化、反序列化】相关推荐

  1. 二叉树的深度优先搜索c语言,C语言 二叉树按层打印、深度优先遍历、二叉树是否对称...

    #include//二叉树节点 typedef struct tree{ int data; struct tree *pLeft; struct tree *pRight; }Tree; //队列 ...

  2. leetcode 637. Average of Levels in Binary Tree | 637. 二叉树的层平均值(Java)

    题目 https://leetcode-cn.com/problems/average-of-levels-in-binary-tree/ 题解 1.参考"二叉树按层打印"写的解法 ...

  3. 左神算法:二叉树的按层打印与ZigZag打印(Java版)

    本题来自左神<程序员代码面试指南>"二叉树的按层打印与ZigZag打印"题目. 题目 给定一棵二叉树的头节点 head,分别实现 按层 和 ZigZag 打印 二叉树的 ...

  4. 95-268-280-源码-Flink通信层的序列化与反序列化

    文章目录 1.概述 2.Flink通信层的序列化 3.Flink 序列化过程 1.概述 当两个进程在进行远程通信时,彼此可以发送各种类型的数据.无论是何种类型的数据,都会以二进制序列的形式在网络上传送 ...

  5. 【Java】用Jackson进行JSON序列化/反序列化操作

    Java类和JSON Speaker类: import java.util.ArrayList; import java.util.Arrays; import java.util.List;publ ...

  6. 一个更好的C++序列化/反序列化库Kapok

    1.Kapok的特点 简单,易用,header-only,只需要引用Kapok.hpp即可:高效,初步测试性和messagepack相当. 它是纯c++11实现,因此需要支持C++11的编译器. 2. ...

  7. Python数据结构与算法题目 打印二叉树的左视图 打印二叉树的右视图 树的左视图 树的右视图

    阅读目录 题目描述 思路与Python实现 题目描述 输入一棵二叉树,求出树的左视图,或者右视图,如下图所示,的两种情况 思路与Python实现 如果可以用非递归的方式写出二叉树的深度遍历或者广度遍历 ...

  8. 二叉树的ZigZag打印-Java

    分享一个大牛的人工智能教程.零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请轻击http://www.captainbed.net package live.every.day.Pro ...

  9. json序列化c语言,C语言JSON序列化/反序列化

    最近想找一个C语言处理嵌套结构体和结构体数组的json库,理想的是能够很容易处理复杂结构体嵌套,并且使用简单的,但是没找到比较合适的,于是打算自己封装一个: 两个问题: C语言结构体本身没有元数据,这 ...

最新文章

  1. Go 语言 Session机制和 Cookie机制
  2. 《ASP.NET Web 站点高级编程》勘误 Part 3
  3. Python 怎么样在函数内部对全局变量进行修改
  4. 微信公众号授权步骤详细步骤介绍和整合springboot开发(java版)
  5. “面试不败计划”:面试题基础二
  6. 【高速接口-RapidIO】Xilinx SRIO IP 核详解
  7. ac算法 有什么用 Java_AC算法使用例子
  8. struts2--java.lang.IllegalAccessException: Class ognl.OgnlRuntime can not access a member of
  9. gin+vue的前后端分离开源项目
  10. maven 整体打包_Maven打包方式整理
  11. 促销海报灵感素材,不卖出去都难
  12. BERT-BiLSTM-CRF基于BERT预训练的中文命名实体识别TensorFlow实现
  13. 关于团队合作开发项目时的沟通问题!(不仅要注意【相关机能】,还要注意【相似功能】)
  14. [转载] Python数据可视化库-Matplotlib——折线图绘制
  15. 【译】AS3利用CPU缓存
  16. Stream介绍及简单操作!
  17. agax分页查询必知知识,分页必须参数详解
  18. 网吧软件经典大集合.各种网管工具
  19. 企业开票信息税号查询API接口服务
  20. 云计算对传统软件工程的影响

热门文章

  1. cs架构交互_架构,功能和交互
  2. 基于Springboot的社区志愿者服务管理系统
  3. 小程序:浅谈小程序更新机制,发版后多久能全覆盖
  4. 和诸君学习做一个黑客 内网ARP欺骗[上]外接网卡的安装和启动(3)
  5. 微信小程序自定义顶部栏、等十个重要的常见功能总结
  6. 计算机房电源引入方式,(完整版)通信机房电源计算公式.pdf
  7. C++:实现量化CPI债券交换测试实例
  8. 360极速浏览器屏蔽百度广告
  9. STM32之Bit-Banding
  10. 华为应用市场AGC研习社|如何提升投放转化,实现获量增长?