
【数据结构系列】——二叉树的各个遍历及序列化与反序列化
发布日期:2021-05-07 21:21:37
浏览次数:13
分类:技术文章
本文共 5576 字,大约阅读时间需要 18 分钟。
二叉树的各种遍历,序列化与反序列化
序列化与反序列化:将变成语言中的结构体序列化成JSON字符串,存入缓存或者通过网络发送给远程服务,消费者接受JSON字符串然后进行范徐丽恶化,就可以得到原始数据了。目的是,已某种固定格式组织字符串,使得数据可以独立于编程语言。
序列化:吧结构化的数据“打平”,其实就是在考察二叉树的遍历方式
反序列化,将字符串还原出二叉树
前序遍历
前序遍历框架:
void traverse(TreeNode root){ if(root == null) return; //前序遍历的代码 traverse(root.left); traverse(root.right);}
序列化,需要将一颗二叉树打平成一个字符串
//代表分割符的字符 String SEP = ","; //代表null空指针的字符 String NULL = "#"; /** * 主函数,将二叉树序列化为字符串 */ String serialize(TreeNode root){ //用于拼接字符串 StringBuilder sb = new StringBuilder(); serialize(root,sb); return sb.toString(); } /** * 将二叉树打平为字符串 */ void serialize(TreeNode root,StringBuilder sb){ if (root == null){ sb.append(NULL).append(SEP); return; } /** * 前序遍历 */ sb.append(root.val).append(SEP); serialize(root.left,sb); serialize(root.right,sb); }
反序列化
先确定根节点root,然后根据前序遍历的规则,递归生成左右子树
/** * 主函数,将字符串反序列化为二叉树结构 * @param data * @return */ TreeNode deserialize_pre(String data){ //将字符串转化为列表 LinkedListnodes = new LinkedList<>(); for (String s : data.split(SEP)) { nodes.addLast(s); } return deserialize(nodes); } /** * 辅助函数,通过nodes列表构造二叉树 * @param nodes * @return */ private TreeNode deserialize(LinkedList nodes) { if (nodes.isEmpty()) return null; /** * 前序遍历 */ //列表最左侧就是根节点 String first = nodes.removeFirst(); if (first.equals(NULL)) return null; TreeNode root = new TreeNode(Integer.parseInt(first)); root.left = deserialize(nodes); root.right = deserialize(nodes); return root; }
后序遍历
后序遍历框架
void traverse(TreeNode root){ if(root == null) return; traverse(root.left); traverse(root.right);}
序列化:
String SEP=",";String NULL="#";String serialize+post(TreeNode root){ StringBuilder sb = new StringBuilder(); serialize(root,sb); return sb.toString();}void serialize(TreeNode root,StringBuilder sb){ if(root == null){ sb.append(NULL).append(SEP); return; } serialize(root.left,sb); serialize(root.right,sb); sb.append(root.val).append(SEP);}
反序列化:
从后往前取出列表元素,一定要先构造root.right子树,后构造root.left子树
/** * 主函数,将字符串反序列化为二叉树结构 * @param data * @return */ TreeNode deserialize_post(String data){ //将字符串转化为列表 LinkedListnodes = new LinkedList<>(); for (String s : data.split(SEP)) { nodes.addLast(s); } return deserialize(nodes); } /** * 辅助函数,通过nodes列表构造二叉树 * @param nodes * @return */ private TreeNode deserialize(LinkedList nodes) { if (nodes.isEmpty()) return null; //从后往前取出元素 String last = nodes.removeLast(); if (last.equals(NULL)) return null; TreeNode root = new TreeNode(Integer.parseInt(last)); root.right = deserialize(nodes); root.left = deserialize(nodes); return root; }
中序遍历
中序遍历不能反序列化,因为root的值被夹在两颗子树的中间,我们不知道确切的索引位置,无法找到root节点,无法进行反序列化
中序遍历序列化:
void serialize(TreeNode root,StringBuilder sb){ if(root == null){ sb.append(NULL).append(SEP); return; } serialize(root.left,sb); sb.append(root.val).append(SEP); serialize(root.right,sb);}
层序遍历
层序遍历框架:
void traverse(TreeNode root){ if(root == null) return; //初始化列表,将root加入队列 Queueq = new LinkedList<>(); q.offer(root); while(!q.isEmpty()){ TreeNode cur = q.poll(); /** 层序遍历代码位置 */ if(cur == null) continue; System.out.prontlin(cur.val); q.offer(cur.left); q.offer(cur.right); }}
序列化:
//代表分割符的字符 String SEP = ","; //代表null空指针的字符 String NULL = "#"; /** * 主函数,将二叉树序列化为字符串 */ String serialize_level(TreeNode root){ //用于拼接字符串 StringBuilder sb = new StringBuilder(); //初始化队列,将root加入队列 Queueq = new LinkedList<>(); q.offer(root); while (!q.isEmpty()){ TreeNode cur = q.poll(); //层序遍历 if (cur == null){ sb.append(NULL).append(SEP); continue; } sb.append(cur.val).append(SEP); q.offer(cur.left); q.offer(cur.right); } return sb.toString(); }
反序列化
/** * 主函数,将字符串反序列化为二叉树结构 * @param data * @return */ TreeNode deserialize_level(String data){ if (data.isEmpty()) return null; String[] nodes = data.split(SEP); //第一个元素就是root的值 TreeNode root = new TreeNode(Integer.parseInt(nodes[0])); //队列q记录父节点,将root加入队列 Queueq = new LinkedList<>(); q.offer(root); for (int i = 1; i < nodes.length ; i++) { //队列中存的是父节点 TreeNode parent = q.poll(); //父节点对应的左侧子节点的值 String left = nodes[i++]; if (!left.equals(NULL)){ parent.left = new TreeNode(Integer.parseInt(left)); q.offer(parent.left); }else { parent.left = null; } //父节点对应的右侧子节点的值 String right = nodes[i++]; if (!right.equals(NULL)){ parent.right = new TreeNode(Integer.parseInt(right)); q.offer(parent.right); }else { parent.right = null; } } return root; }
发表评论
最新留言
逛到本站,mark一下
[***.202.152.39]2025年03月30日 05时42分29秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
刷题计划1——poj1753
2019-03-04
蓝桥杯备战——刷题(2019)
2019-03-04
未定义的变量“py”或函数“py.command”
2019-03-04
最短路径问题—Dijkstra算法
2019-03-04
A Guide to Node.js Logging
2019-03-04
webwxbatchgetcontact一个神奇的接口
2019-03-04
Edge浏览器:你的的内核我的芯
2019-03-04
git命令升级版用法
2019-03-04
sed常用命令
2019-03-04
checksec未完待续~
2019-03-04
怎么去利用已有的数据做分析?
2019-03-04
【考研高数-高等数学-基础】第四章 不定积分
2019-03-04
【考研英语-基础-简单句】简单句的核心变化_谓语情态
2019-03-04
数据结构 第五章 二叉树-1
2019-03-04
PVE+集客AC+K2T-AP
2019-03-04
Jetson AGX Xavier硬件自启动
2019-03-04
判断移动端(手机)还是客户端(电脑)打开网页并跳转不同页面(首页)
2019-03-04
眼睛跟随鼠标转动的小黄人 html+css+js
2019-03-04
简单的字符串操作(注意要点)
2019-03-04
统计字符数
2019-03-04