树:重建二叉树

题目描述

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

        ///              1///           /     \///          2       3  ///         /       / \///        4       5   6///         \         ////          7       8  

解题思路

基础知识

前序遍历:根结点 ---> 左子树 ---> 右子树
中序遍历:左子树---> 根结点 ---> 右子树
后序遍历:左子树 ---> 右子树 ---> 根结点
层次遍历:只需按层次遍历即可

例如:

前序遍历:1 2 4 7 3 5 6 8
中序遍历:4 7 2 1 5 3 8 6
后序遍历:7 4 2 5 8 6 3 1
层次遍历:1 2 3 4 5 6 7 8

前序遍历首先访问根结点然后遍历左子树,最后遍历右子树。在遍历左、右子树时,仍然先访问根结点,然后遍历左子树,最后遍历右子树。
中序遍历(LDR)是二叉树遍历的一种,也叫做中根遍历、中序周游。在二叉树中,中序遍历首先遍历左子树,然后访问根结点,最后遍历右子树。
二叉树的什么什么遍历,其实也是很好记的,就是根在呢就是什么遍历,在前就是前遍历,中就是中序遍历,后就是后序遍历,其他的是层次遍历。

解题:

根据前序遍历,可以知道根节点(1),根据中序遍历可以知道左子树(4,7,2)和右子树(5,3,8,6)。找到左右子树之后,我们可以以相同的方式找到左右子树,也就是说这是一个递归的过程。根>左>右。

代码实现

二叉树

    /// <summary>/// 二叉树/// </summary>public class TreeNode{public int val;public TreeNode left;public TreeNode right;public TreeNode(int x){val = x;}}

前序遍历:根结点 ---> 左子树 ---> 右子树

        public static void PreNode(TreeNode node, List<int> treeList){if (node != null){treeList.Add(node.val);PreNode(node.left, treeList);PreNode(node.right, treeList);}}

中序遍历:左子树---> 根结点 ---> 右子树

        public static void MidNode(TreeNode node, List<int> treeList){if (node != null) {MidNode(node.left, treeList);treeList.Add(node.val);MidNode(node.right, treeList);}}

后序遍历:左子树 ---> 右子树 ---> 根结点

        public static void EndNode(TreeNode node, List<int> treeList){if (node != null) {EndNode(node.left, treeList);EndNode(node.right, treeList);treeList.Add(node.val);}}

层次遍历:只需按层次遍历即可。思路:根据层次遍历的顺序,每一层都是从左到右的遍历输出,借助于一个队列。先从根节点入队,将其出队访问,如果当前节点的左节点不为空左节点入队,如果当前右节点部位空右节点入队。所以出队顺序是从左到右。

        public static void LevelNode(TreeNode node, List<int> treeList){if (node != null) {Queue<TreeNode> queue = new Queue<TreeNode>();queue.Enqueue(node);TreeNode currentNode = null;while (queue.Count > 0) {currentNode = queue.Dequeue();treeList.Add(currentNode.val);if (currentNode.left != null) {queue.Enqueue(currentNode.left);}if (currentNode.right != null) {queue.Enqueue(currentNode.right);}}}}

二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。思路:根据前序遍历找到根,根据中序遍历找到左右子树,依次递归。归结:根 > 左 > 右

        public static TreeNode Tree(List<int> preTree, List<int> midTree){if (preTree == null || preTree.Count() == 0 || midTree == null || midTree.Count() == 0){return null;}//根节点int rootTree = preTree[0];//移除根节点preTree.RemoveAt(0);TreeNode treeNode = new TreeNode(rootTree);//左右子树List<int> leftTree = null;List<int> tempList = new List<int>();bool isTree = false;foreach (var item in midTree){tempList.Add(item);if (item == rootTree){isTree = true;tempList.Remove(item);leftTree = tempList;tempList = new List<int>();}}if (!isTree) {Console.WriteLine("不是正确的树");return null;}List<int> rightTree = tempList;//递归左右节点treeNode.left = Tree(preTree, leftTree);treeNode.right = Tree(preTree, rightTree);return treeNode;}

测试

普通二叉树

        /// <summary>/// 普通二叉树///              1///           /     \///          2       3  ///         /       / \///        4       5   6///         \         ////          7       8        /// </summary>
        [Fact]public void Common() {int[] preTree = { 1, 2, 4, 7, 3, 5, 6, 8 };int[] midTree = { 4, 7, 2, 1, 5, 3, 8, 6 };TreeNode tree = Coding004.Tree(preTree.ToList(), midTree.ToList());List<int> result = new List<int>();Coding004.PreNode(tree, result);Assert.Equal(JsonConvert.SerializeObject(preTree), JsonConvert.SerializeObject(result));result.Clear();Coding004.MidNode(tree, result);Assert.Equal(JsonConvert.SerializeObject(midTree), JsonConvert.SerializeObject(result));}

所有结点都没有右子结点

        /// <summary>/// 所有结点都没有右子结点///            1///           / ///          2   ///         / ///        3 /// </summary>
        [Fact]public void Right(){int[] preTree = { 1, 2, 3 };int[] midTree = { 3, 2, 1 };TreeNode tree = Coding004.Tree(preTree.ToList(), midTree.ToList());List<int> result = new List<int>();Coding004.PreNode(tree, result);Assert.Equal(JsonConvert.SerializeObject(preTree), JsonConvert.SerializeObject(result));result.Clear();Coding004.MidNode(tree, result);Assert.Equal(JsonConvert.SerializeObject(midTree), JsonConvert.SerializeObject(result));}

所有结点都没有左子结点

        /// <summary>/// 所有结点都没有左子结点///            1///             \ ///              2   ///               \ ///                3 ///                 \//////                   \///                    5/// </summary>
        [Fact]public void Left(){int[] preTree = { 1, 2, 3, 4, 5 };int[] midTree = { 1, 2, 3, 4, 5 };TreeNode tree = Coding004.Tree(preTree.ToList(), midTree.ToList());List<int> result = new List<int>();Coding004.PreNode(tree, result);Assert.Equal(JsonConvert.SerializeObject(preTree), JsonConvert.SerializeObject(result));result.Clear();Coding004.MidNode(tree, result);Assert.Equal(JsonConvert.SerializeObject(midTree), JsonConvert.SerializeObject(result));}

树中只有一个结点

        /// <summary>/// 树中只有一个结点/// </summary>
        [Fact]public void One(){int[] preTree = { 1 };int[] midTree = { 1 };TreeNode tree = Coding004.Tree(preTree.ToList(), midTree.ToList());List<int> result = new List<int>();Coding004.PreNode(tree, result);Assert.Equal(JsonConvert.SerializeObject(preTree), JsonConvert.SerializeObject(result));result.Clear();Coding004.MidNode(tree, result);Assert.Equal(JsonConvert.SerializeObject(midTree), JsonConvert.SerializeObject(result));}

完全二叉树

        /// <summary>/// 完全二叉树///              1///           /    \///          2      3  ///         / \     / \///        4   5   6   7/// </summary>
        [Fact]public void All(){int[] preTree = { 1, 2, 4, 5, 3, 6, 7 };int[] midTree = { 4, 2, 5, 1, 6, 3, 7 };TreeNode tree = Coding004.Tree(preTree.ToList(), midTree.ToList());List<int> result = new List<int>();Coding004.PreNode(tree, result);Assert.Equal(JsonConvert.SerializeObject(preTree), JsonConvert.SerializeObject(result));result.Clear();Coding004.MidNode(tree, result);Assert.Equal(JsonConvert.SerializeObject(midTree), JsonConvert.SerializeObject(result));}

想入非非:扩展思维,发挥想象

1. 熟悉二叉树
2. 熟悉二叉树的几种遍历
3. 熟悉队列先进先出
4. 熟悉递归

其他系列的文章

面试题【从尾到头打印链表】

面试题【字符串替换空格】

面试题【二维数组中的查找】

转载于:https://www.cnblogs.com/zhao123/p/11138608.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/363998.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

css随堂笔记(一)

Css初体验第一天 1 css初识&#xff1a;css主要用于设置HTML页面中文本内容&#xff0c;图片的外形&#xff0c;以及版面的布局等外观显示样式 Css样式规范&#xff1a;h1{属性&#xff1a;值} 2 css的三总书写方式&#xff1a;1 行内样式 将样式写在标签里面,只能作用于当前标…

关于全排列

嗯... 关于全排列&#xff0c;有很多种种做法... 嗯.... 那什么叫全排列呢&#xff1f;&#xff1f;&#xff01;&#xff01; 从n个不同元素中任取m&#xff08;m≤n&#xff09;个元素&#xff0c;按照一定的顺序排列起来&#xff0c;叫做从n个不同元素中取出m个元素的一个排…

[Java]如何安排任务间隔运行

应用程序中经常需要在后台运行某些特定任务以在一定间隔内完成某些工作。 该示例可以是&#xff0c;服务在后台运行以清理应用程序&#xff0c;就像我们有Java Garbage集合一样。 在本文中&#xff0c;我将向您展示3种不同的方法来实现这一目标 他们如下 使用简单的线程 使…

Sky Line 与 ArcEngine的粘合剂 Composite UI AB?

如今的goverment领导们觉得地图都太抽象&#xff0c;只有google Earth式的应用能引起他们的兴趣&#xff0c;作为为公仆服务的我们自然要学习掌握3D GIS技术来提高zf的执政能力了&#xff0c;于是Sky Line来了&#xff0c;拿到开发手册的时候觉得接口不多应该很容易开发&#x…

php if终止,php判断用户是否掉线及关闭网页的方法分享

要实现判断用户已掉线并关闭网页&#xff0c;主要用到方法connection_status 和 connection_aborted。通过一个例子&#xff0c;来了解下它们的用法:echo str_repeat(" ",300);//以下不可省略&#xff0c;否则用户断线&#xff0c;php(线程)立即终止&#xff0c;不会…

默认方法一种扩展旧代码的方法

如您所知&#xff0c;Java的新版本于2014年3月18日发布&#xff0c;我将介绍一系列文章来演示其新功能&#xff0c;也许在某些方面&#xff0c;我将谈论我的想法和批评。 我认为重要的第一个功能是“默认方法”&#xff0c;在所有Java语言的先前版本中&#xff0c;接口只能包含…

vue 如何点击按钮返回上一页

1&#xff0c;vue 如何点击按钮返回上一页呢&#xff1f; 这是vue挂载的范围html代码 <div click"goOff()">返回</div> 下面是点击返回的方法 第一种只返回上一页 goOff(){ this.$router.go(-1); }, 第二种 返回上一页&#x…

2007白领职场成功需要哪“十商”

1.德商(MQ)&#xff1a;指一个人的道德人格品质。德商的内容包括体贴、尊重、容忍、宽容、诚实、负责、平和、忠心、礼貌、幽默等各种美德。 2.智商(IQ)&#xff1a;是一种表示人智力高低的数量指标。也可以表现为一个人对知识的掌握程度&#xff0c;反映人的观察力、记忆力、思…

Remove Element - LeetCode

目录 题目链接注意点解法小结题目链接 Remove Element - LeetCode 注意点 输入的数组是无序的解法 解法一&#xff1a;使用了erase函数&#xff0c;将等于val的值移除。时间复杂度为O(n) class Solution { public:int removeElement(vector<int>& nums, int val) {fo…

DRF url控制 解析器 响应器 版本控制 分页(常规分页,偏移分页,cursor游标分页)...

url控制第二种写法&#xff08;只要继承了ViewSetMixin&#xff09; url(r^pub/$,views.Pub.as_view({get:list,post:create})), #获取所有记得路由后面加$结束符 #pub/?formatjsonurl(r^pub\.(?P<format>\w)$,views.Pub.as_view({get:list,post:create})), #pu…

要配置php环境_只需修改,要配置Apache的PHP环境,只需修改()。

案例分析一&#xff1a;假定CPU的主频是500MHz。硬盘采用DMA方式进行数据传送&#xff0c;其数据传输率为4MB/s, 每次DMA传输的数据量为8KB, 要求没有任何数据传输被错过。如果CPU在DMA初始化设置和启动硬盘操作等方面用了1000个时钟周期&#xff0c;并且在DMA传送完成后的中断…

使用Java 8和Lambda简化ReadWriteLock

考虑到旧版Java代码&#xff0c;无论您在哪里看&#xff0c;带有lambda表达式的Java 8绝对可以提高质量和可读性。 今天&#xff0c;让我们看一下ReadWriteLock以及如何使它使用起来更简单。 假设我们有一个称为Buffer的类&#xff0c;该类可以记住队列中的最后几条消息&#x…

[导入]C#好书盘点【月儿原创】

C#好书盘点【月儿原创】 文章来源:http://blog.csdn.net/21aspnet/archive/2007/07/07/1682200.aspx 转载于:https://www.cnblogs.com/zhaoxiaoyang2/archive/2007/07/08/816177.html

岁月如歌,人生如诗

虎跃千山龙腾海&#xff0c;春满家园喜满怀。新的一年&#xff0c;孕育着新的生命&#xff1b;新的一年&#xff0c;掸去了飞雪的扬花&#xff0c;满心的惬意告诉我们&#xff0c;所有的期盼与期望&#xff0c;一切的向往与憧憬正向着我们走近&#xff0c;向着春天融合。 ​ 新…

DOM编程以及domReady加载的几种方式

1&#xff0c;关于DOM编程 DOM编程主要是对dom树节点进行操作&#xff0c;所以你必须掌握基本的节点类型&#xff0c;如何去获取节点名字以及值&#xff08;这些相关知识你可以去网上查&#xff0c;这里推荐一个慕课学习网站->https://www.imooc.com/video/9491&#…

倒叙输出 php,php foreach正序倒序输出示例代码

实现代码&#xff1a;// 正序foreach($files as $file_num > $file) {if(is_file($directory.$file)){//$file iconv("gb2312","UTF-8",$file); //或者 iconv("gb2312","UTF-8",$value);$date substr($file,0,9);echo ;echo ;ech…

黑色系产业结构

转载于:https://www.cnblogs.com/luoluo-123/p/11143867.html

在Java 8 Lambda中创建自己的循环结构

Java没有简单的构造可以重复N次。 当然&#xff0c;我们可以创建一个for循环&#xff0c;但是很多时候我们甚至都不关心在循环中创建的变量。 我们只想重复一些代码N次&#xff0c;仅此而已。 使用Java 8中的lambda时&#xff0c;您可以尝试执行以下操作&#xff1a; public c…

Smart Form Tutorial(适用新手学习)

发现Smart Form在ECC6中和4.6C相比改变了不少&#xff0c;最近重新研究了一下。help.sap.com上的文档基本上是针对新特性的&#xff0c;不过例子却还是旧的。做个笔记省的以后找不到最新的example。最大的改变在Table上&#xff0c;现在table的header和footer比以前好做了。还是…

执行命令npm install XXX后仍然提示 Cannot find Module XXX

最近遇到一个问题&#xff0c;在服务器上配置完node环境后 执行npm start 命令后提示 Cannot find Module "Jquery" 然后就知道可能没有安装jquery 就继续在当前文件夹下执行 npm install jquery 但是再次执行后却仍然提示 Cannot find Module "Jquery"…