将 N 叉树编码为二叉树

作者:Grey

原文地址:

博客园:将 N 叉树编码为二叉树

CSDN:将 N 叉树编码为二叉树

题目描述

将一棵n叉树编码为一棵二叉树,并对二叉树进行解码,得到原始的n叉树。 n叉树是一棵有根树,其中每个节点的子树不超过n个。 类似地,二叉树是一棵有根树,其中每个节点的子树不超过2个。 编码/解码算法的工作方式不受限制。 您只需要确保一个n叉树可以被编码为一个二叉树,并且这个二叉树可以被解码为原始的n叉树结构。

题目链接:LintCode 1530 · Encode N-ary Tree to Binary Tree

一棵 N 叉树的示例如下

二叉树的数据结构如下

class TreeNode {
public int val;
public TreeNode left, right; public TreeNode(int val) {
this.val = val;
this.left = this.right = null;
}
}

N 叉树的数据结构如下

class UndirectedGraphNode {
int label;
List<UndirectedGraphNode> neighbors;
UndirectedGraphNode(int x) {
label = x;
neighbors = new ArrayList<UndirectedGraphNode>();
}
}

每个节点有属于自己的 label 值,也有若干个孩子节点,即List<UndirectedGraphNode> neighbors

我们需要实现如下两个方法

// N 叉树编码成 二叉树
TreeNode encode(UndirectedGraphNode root)
// 二叉树编码成 N 叉树
UndirectedGraphNode decode(TreeNode root)

主要思路

N 叉树编码成二叉树的方法是将 N 叉树中每个节点的子节点转换成自己左树的右边界或者右树的左边界,示例图如下

二叉树编码成 N 叉树的方法就是把每个节点的左树右边界存到一个 List 里面,作为这个节点的子节点列表即可,就是上述示例图的逆过程。

N 叉树编码成二叉树的过程就是一个深度优先遍历,首先

TreeNode head = new TreeNode(root.label);

表示二叉树的根节点就是 N 叉树的根节点,

然后将根节点的孩子节点,调用递归,进行深度优先遍历,代码如下

// 将某个节点的孩子节点挂在其右树的左边界上
// 将 N 叉树的根节点的孩子节点做深度优先遍历
// 并将其挂在根节点的右树上
head.right = en(root.neighbors); // 深度优先遍历
private TreeNode en(List<UndirectedGraphNode> neighbors) {
TreeNode c = null;
TreeNode head = null;
for (UndirectedGraphNode neighbor : neighbors) {
TreeNode node = new TreeNode(neighbor.label);
if (head == null) {
// 头节点为空,建出来
head = node;
} else {
// 否则挂在当前节点的右树的左边界上
c.left = node;
}
c = node;
c.right = en(neighbor.neighbors);
}
return head;
}

将二叉树转换成 N 叉树的逻辑如下:

首先

UndirectedGraphNode node = new UndirectedGraphNode(root.val);

表示:N 叉树的根节点也是二叉树的根节点。

接着调用递归,将二叉树的右树构造出 N 叉树当前节点的孩子节点。

// 将二叉树的右树构造出 N 叉树当前节点的孩子节点
node.neighbors = de(root.right); public ArrayList<UndirectedGraphNode> de(TreeNode root) {
ArrayList<UndirectedGraphNode> children = new ArrayList<>();
while (root != null) {
UndirectedGraphNode cur = new UndirectedGraphNode(root.val);
cur.neighbors = de(root.right);
children.add(cur);
root = root.left;
}
return children;
}

其中 while 循环中就是不断的把当前节点的左树右边界加入到一个 List 中,最后返回。

完整代码如下

public class Solution {
public UndirectedGraphNode decode(TreeNode root) {
if (root == null) {
return null;
}
UndirectedGraphNode node = new UndirectedGraphNode(root.val);
node.neighbors = de(root.right);
return node;
} public ArrayList<UndirectedGraphNode> de(TreeNode root) {
ArrayList<UndirectedGraphNode> children = new ArrayList<>();
while (root != null) {
UndirectedGraphNode cur = new UndirectedGraphNode(root.val);
cur.neighbors = de(root.right);
children.add(cur);
root = root.left;
}
return children;
} // 每个子节点转换成自己左树的右边界或者右树的左边界 + 深度优先遍历
// 编码
public TreeNode encode(UndirectedGraphNode root) {
if (root == null) {
return null;
}
TreeNode head = new TreeNode(root.label);
// 右树的左边界
head.right = en(root.neighbors);
return head;
} private TreeNode en(List<UndirectedGraphNode> neighbors) {
TreeNode c = null;
TreeNode head = null;
for (UndirectedGraphNode neighbor : neighbors) {
TreeNode node = new TreeNode(neighbor.label);
if (head == null) {
// 头节点为空,建出来
head = node;
} else {
// 否则挂在当前节点的右树的左边界上
c.left = node;
}
c = node;
c.right = en(neighbor.neighbors);
}
return head;
}
}

本文涉及到的所有图例见:二叉树与N叉树的互相转换

更多

算法和数据结构笔记

将 N 叉树编码为二叉树的更多相关文章

  1. [LeetCode] Encode N-ary Tree to Binary Tree 将N叉树编码为二叉树

    Design an algorithm to encode an N-ary tree into a binary tree and decode the binary tree to get the ...

  2. 剑指offer-面试题27-二叉树的镜像-二叉树

    /* 题目:输入一个二叉树,输出该函数的镜像. */ /* 思路: 基础条件:树为空,或只有一个节点. 其它:递归交换二叉树的左右子树. */ void Mirror(TreeNode *pRoot) ...

  3. leetcode难题

    4 寻找两个有序数组的中位数       35.9% 困难     10 正则表达式匹配       24.6% 困难     23 合并K个排序链表       47.4% 困难     25 K ...

  4. [数据结构与算法]哈夫曼(Huffman)树与哈夫曼编码

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  5. POJ 1240 Pre-Post-erous! && East Central North America 2002 (由前序后序遍历序列推出M叉树的种类)

    题目链接 问题描述 : We are all familiar with pre-order, in-order and post-order traversals of binary trees. ...

  6. POJ 1240 Pre-Post-erous! && East Central North America 2002 (由前序后序遍历序列推出M叉树的种类)

    题目链接:http://poj.org/problem?id=1240 本文链接:http://www.cnblogs.com/Ash-ly/p/5482520.html 题意: 通过一棵二叉树的中序 ...

  7. C#数据结构-线索化二叉树

    为什么线索化二叉树? 对于二叉树的遍历,我们知道每个节点的前驱与后继,但是这是建立在遍历的基础上,否则我们只知道后续的左右子树.现在我们充分利用二叉树左右子树的空节点,分别指向当前节点的前驱.后继,便 ...

  8. leetcode_二叉树篇_python

    主要是深度遍历和层序遍历的递归和迭代写法. 另外注意:因为求深度可以从上到下去查 所以需要前序遍历(中左右),而高度只能从下到上去查,所以只能后序遍历(左右中). 所有题目首先考虑root否是空.有的 ...

  9. [Algorithm & NLP] 文本深度表示模型——word2vec&doc2vec词向量模型

    深度学习掀开了机器学习的新篇章,目前深度学习应用于图像和语音已经产生了突破性的研究进展.深度学习一直被人们推崇为一种类似于人脑结构的人工智能算法,那为什么深度学习在语义分析领域仍然没有实质性的进展呢? ...

随机推荐

  1. B+树索引页大小是如何确定的?

    B+树简介 在正式介绍本文的主题前,需要对 B+ 树有一定的了解,B+树是一种磁盘上数据的索引结构,大概长这个样子. B+树的叶子节点是所有的数据,非叶子节点称为索引页,索引页里有若干个索引项,本例中 ...

  2. 基于Python3(Autosub)以及Ffmpeg配合GoogleTranslation(谷歌)为你的影片实现双语版字幕(逐字稿)

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_169 为影片加字幕其实是一件非常耗费时间的事情,尤其是对于打字慢的朋友来说.当然不光为影片加字幕,在其他领域,类似的逐字稿也是工作 ...

  3. 字符编码和python中的文件处理

    字符编码与python文件处理 ---------------- 字符编码 1.常见的编码 ASCII: 美国人发明的,只编码英文字母和符号,1个字节. GB2312: 中国人发明的,增加了中文汉字和 ...

  4. MySQL启动报:[ERROR] The server quit without updating PID file

    修改配置后MySQL启动不了,报错: [root@localhost mysql]# service mysql restart Starting MySQL...[ERROR] The server ...

  5. NC202475 树上子链

    题目链接 题目 题目描述 给定一棵树 T ,树 T 上每个点都有一个权值. 定义一颗树的子链的大小为:这个子链上所有结点的权值和 . 请在树 T 中找出一条最大的子链并输出. 输入描述 第一行输入一个 ...

  6. ABC 203 F - Weed (DP)

    ABC203F - Weed 题意转述 S t e v e \rm Steve Steve 和 A l e x \rm Alex Alex 正在下界( N e t h e r l e n d \rm ...

  7. python使用pickle序列化对象读取输出二进制文件

    import pickle class tick: name = '牛牛牛' age = 10 samp = [1,2,3,'aaa',[12,3],tick()] with open('te.xxx ...

  8. 状态 :睡眠中,进程ID:13431,yum提示Another app is currently holding the yum lock; waiting for it to exit...

    问题描述: 今天想在虚拟机上重新安装docker然后使用到yum命令报错: 解决办法: [root@localhost ~]# rm -f /var/run/yum.pid 然后重新运行刚才的yum命 ...

  9. SpringMvc请求流程源码解析

    目录 SpringMvc请求流程图 请求流程粗讲解 方法细讲 doDispatcher --> 核心 找到Handler#getHandler getHandler(request) mappi ...

  10. 实践分享!GitLab CI/CD 快速入门

    用过 GitLab 的同学肯定也对 GitLab CI/CD 不陌生,GitLab CI/CD 是一个内置在 GitLab 中的工具,它可以帮助我们在每次代码推送时运行一系列脚本来构建.测试和验证代码 ...