简介
在之前的一些学习中有几个地方碰到将二叉树转化成链表的问题。它们虽然各不相同,但是如果仔细分析它们的具体过程,我们会发现其中有一些规律可以遵循的。
问题讨论
这个问题比较有意思的地方在于有这么一个特性。我们定义的二叉树一般有几种常用的遍历方式。比如前序,中序,后序以及层次遍历。它们的每种遍历方式所经历过的节点就构成了一个序列。如果我们需要将一棵二叉树转换成对应的链表,它们所要构成的链表的顺序基本上就和我们遍历的顺序一致。
通用思路
对于上述的问题,如果我们针对它们各种不同的情况来进行遍历的话,我们首先能想到的第一个想法就是递归遍历的办法。当然,光一个递归遍历还是不够的。因为我们需要将它们串起来,也就是说要修改它们的指针来使得它们构成一个对应的双向链表。如果没有其他限制的情况下,我们可以考虑用一个队列来将每次遍历访问的元素保存起来。然后再按照队列的顺序将它们一个个的拼接起来。
假设我们定义的树节点元素如下:
public class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; } }
前序
前序遍历的递归方法只需要稍微做一点修改就可以达到我们期望的结果:
public void flattenTree(TreeNode root) { if(root == null) return; Queue<TreeNode> queue = new LinkedList<>(); flatten(root, queue); Node node = queue.remove(); node.left = null; while(!queue.isEmpty()) { Node temp = queue.remove(); node.right = temp; temp.left = node; node = temp; } node.right = null; } public void flatten(TreeNode node, Queue<TreeNode> queue) { if(node == null) return; queue.add(node); flatten(node.left, queue); flatten(node.right, queue); }
这种具体的实现方法利用了原有树的递归调用。不过在调用的过程中将真正需要访问处理的元素加入到一个队列中,这样通过这个队列作为传递的参数,它将最终保存我们期望的结果。然后剩下的步骤就是将这些处理的元素一个个出队列并拼接形成一个链表。
上面的方法是用递归的方式实现了这么个转换的过程。如果我们想用非递归的方式来处理也好办。这里要利用到一个栈。我们也只是需要在栈处理元素的某个时候来将元素加入队列。一个对应的参考实现如下:
public void flattenTree(TreeNode root) { if(root == null) return; Queue<TreeNode> queue = new LinkedList<>(); Stack<TreeNode> stack = new Stack<>(); TreeNode node = root; while(node != null || !stack.isEmpty()) { if(node != null) { queue.add(node); if(node.right != null) stack.push(node.right); node = node.left; } else if(!stack.isEmpty()) { node = stack.pop(); } } // process the queue, same as before node = queue.remove(); node.left = null; while(!queue.isEmpty()) { Node temp = queue.remove(); node.right = temp; temp.left = node; node = temp; } node.right = null; }
没什么巧的,这里不过是在非递归的前序遍历实现里加了个壳。对应后面的中序、后序以及层次遍历实现其实都可以用类似的套路来对付。这里可以参考后面的文章来处理。
总结
将二叉树转换成对应的链表的方式有若干种。主要取决于我们要转换成的链表和我们遍历树的关系。对于我们有对应关系的构造,我们可以用常用的递归和非递归方法去首先遍历这课树。在遍历的过程中将访问到的节点放到队列中。后面再统一处理。
当然,针对一些具体问题的变化中,它还有一些具体的实现差别。比如说在有些要求直接变换不能使用额外存储的情况下。我们需要去发现它们每个节点的前一个位置和后一个位置的关系然后迭代的处理。在某些要求将元素节点转换成循环链表的情况下,我们可以考虑一些递归的解法。这些都是一些问题变体的应用。
参考材料
http://shmilyaw-hotmail-com.iteye.com/blog/1828011
http://shmilyaw-hotmail-com.iteye.com/blog/2289879
http://cslibrary.stanford.edu/109/TreeListRecursion.html
相关推荐
java java_leetcode-114-flatten-binary-tree-to-linked-list
python python_leetcode题解之114_Flatten_Binary_Tree_to_Linked_List
javascript js_leetcode题解之114-flatten-binary-tree-to-linked-list.js
在IT领域,特别是数据结构与算法的学习中,"Flatten Binary Tree to Linked List" 是一个经典的问题。这个任务要求我们将一棵二叉树转换为单链表。二叉树是一种非线性数据结构,而链表则是一种线性数据结构。在实际...
leetcode做过的LeetCode的题目记录一下。对一些比较经典的题型进行分类总结。数据结构 数组 字符串 队列 链表 双指针 栈 堆 树 二叉搜索树 字典树 线段树 并查集 哈希表 图基础... Flatten Binary Tree to Linked List
- **Flatten Binary Tree to Linked List**:将二叉树展平为单链表。 - **Validate Binary Search Tree**:验证一个二叉树是否为二叉搜索树。 - **Recover Binary Search Tree**:恢复二叉搜索树中的两个错误节点...
"flatten"这个包就是实现这一功能的工具。 1. **Laravel框架基础**:Laravel是一款基于PHP的开源Web应用框架,遵循MVC(模型-视图-控制器)架构模式,以其优雅的语法和丰富的功能库而闻名。开发者可以利用Laravel...
geojson-flatten 将文件中的MultiPoint,MultiPolygon,MultiLineString和GeometryCollection几何图形展平为简单的非复杂几何图形。 如果传入FeatureCollection,则返回FeatureCollection。 如果传入单个功能,则...
GLSL是一种用于GPU编程的语言,允许开发者直接在图形处理器上编写计算密集型代码,以实现更高效的图形渲染效果。 在本项目中,我们可以看到几个关键的文件: 1. ogl3.cpp:这是主程序文件,包含了与OpenGL交互的...
leetcode 答案leetcode 的工具 这个项目提供了一些工具来更容易地测试 leetcode 答案。 树:切片 <-> TreeNode 此工具有助于将切片转换为 ...--name="Flatten Binary Tree to Linked List" --type=tree
标题“Tool for Flatten A Folder”指的是一个用于整理和扁平化文件夹结构的命令行工具。这个工具的主要功能是帮助用户将多个不同目录下的特定文件复制到一个单一的目标目录中,从而实现文件夹的扁平化,使得文件...
flatten ( structure )[ 1 , 2 , 3 , 4 ]>> > tree . map_structure ( lambda v : v ** 2 , structure )[[ 1 ], [[[ 4 , 9 ]]], [ 16 ]] tree由适合于苛刻的应用程序(例如机器学习模型)使用的优化的C ++实现支持...
资源分类:Python库 所属语言:Python 资源全名:flatten_json-0.1.12.tar.gz 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059
西兰花压扁 扁平化文件树,因此所有...tree = flatten ( tree , options ) ; 选项 支持以下选项: destDir目录存放所有文件的位置 ###例子 var pickFiles = require ( 'broccoli-static-compiler' ) ; var flatten
flatten_gds.tcl
flatten()函数的基本用法有三种,分别是针对数组、列表和矩阵。需要注意的是,flatten()函数不适用于Python原生的list类型,只适用于numpy的ndarray类型。 1. 当用在数组对象时,可以将多维数组转换成一维数组。...
MojoHaus Flatten Maven插件 这是 。 1.0.x分支: 快速开始 这个插件会生成您pom.xml的扁平版本,并使maven可以安装和部署该版本,而不是原始pom.xml。 <groupId>org.codehaus.mojo <artifactId>flatten-...
以上就是JavaScript中实现数组扁平化的几种常见方法。在实际开发中,可以根据项目的具体需求和环境选择适合的实现方式。例如,如果需要兼容旧版浏览器,可能需要避免使用ES新特性,而倾向于使用递归或`reduce()`方法...
Flatten Maven插件 生产发布 开发发布 安装 相似的插件 插件功能 取代公开的身份 解决依赖版本范围 根据范围排除依赖项 可选地包括传递依赖 根据xml标签名称删除pom.xml成员 用生成的pom.xml.flatten切换项目pom....