| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 数据结构与算法 -> 树的那些破事~模板小结 -> 正文阅读 |
|
[数据结构与算法]树的那些破事~模板小结 |
文章目录前言这里主要记录一些和树相关的内容,一些常见的关于树的算法。 演示语言为了方便理解,本次还是采用Python来进行演示,原因的话很简单,主要是,首先在PTA这个平台,Python的评测速度要比java快,然后是输入问题,java的输入有很多坑,没有Python快。最后一点是,Python代码很明朗。会java 的看Python没有门槛,但是反过来,就不好说了。 树的定义在此之前我先说一下关于树的定义,这里还是采用最直接的表示方法,使用链表法也就是这样的。 注意点我们所有的数组的下标都是从0开始的,切记!(在本篇博文中)然后由于我的习惯问题,先序,前序都是一个玩意。
树的遍历这个咱们主要介绍5个遍历模板。 先序遍历根左右
中序遍历左根右
后序遍历左右根
这块的话,记住这个顺序,待会有妙用。 层次遍历这个的话就是稍微复杂一点点,需要使用到队列。
判断深度这个也是简单的
这个代码呢,不太好理解,你可以这样理解,就是这个函数 shendu()就是用来获取一棵树的深度的,一个树有左右子树,那么只需要获取两个子树的深度加上当前的这个深度就这颗树的深度。当某一个节点为空的时候,到头了,自然深度就是0,上一个过来的节点是叶子节点。 树的构建(通过已知的序(先,中,后))树的构建有很多种,要么是森林转为树,要么树转森林,等等,这里先来简单一点的,通过已知的序来创建一颗树,原来什么数据结构书上还有直接通过一个数组来创建的,那个就没必要说了,很简单。 先序+中序首先明确一点哈,如果不是特殊的树,例如二叉搜索树,在没有中序的情况下,是无法建立一颗树的。 这个前面,我是说过的,但是那个模板是没有优化的,今天也是结合一个哥们(BoyC啊)的思路,做一个小结。 为什么需要中序,才能建树原因的话,可以参考这张图
先解释一下参数的含义,从左到右
这个注意的是这个右子树的根节点在前序排序里面的下标的推导:root+i+1-start 后序+中序
这里和前面几乎一样但是区别就是,在后序里面推导左子树的根节点,因为后序是从后面开始作为根节点的。 二叉搜索树+先序前面说,我们之所以要中序是为了划分左右子树。 这道题目就是比较特殊的点。 来我们先看看刚才的从先序+中序的代码
现在我们改一下,如何通过这种特殊条件去建立一棵树。 所以此时是
start ,end 是左右子树的位置,
看到没有,其实是类似的,重点是确定根节点,然后这里比较特殊的是,左右子树的划分都在前序数组里面,然后边界就是根节点的位置(在前序里面) 镜像翻转这里的还不够,注意到题目里面,说要那个有镜像的,拿这个啥意思呢,其实就是左子树变成右子树。换个位置就可以了。
不建树已知中序和某个序获取另一个序这个意思还是上面那个题目的意思,要拿到后序遍历的数组。 存储结构优化前面我们是通过这个玩意
来存储我们的树的节点的,但是怎么说有点麻烦。主要是创建对象的时候需要消耗内存,而且,我们完全按照这个树的结构去存储的话,如果我想要获取某一个叶子节点的话,我就只能通过根节点去遍历,哪怕我知道那个叶子节点的父节点,也没有用,因为我拿不到那个父节点的内存地址,除非我把它都存起来了。如果是这样的话,那么我觉得也没有必要使用这个Node结构了。我们直接使用数组去维护算了。 不过这里考虑到要维护三个数组,比较繁琐,所以这里来个容易理解的使用字典,hashmap存储(但是多了就不好维护了,我先前做一个题目维护了四个字典,还是Python写的很痛苦,只是为了优化一点点查询的时间,而且我一般是在写图的时候用这个,写那个无向图,矩阵的话太那啥了,不过Python可以直接那样写,应该不会超,java的话拿样干必超) 这块主要说思路,因为写的话还是很好办的。 数组存树这里需要三个数组,然后通过下标把数组联系起来,需要三个数组的原因是因为我们有三个信息要维护,value,left ,next 这个一目了然,但是三个数组多少维护有点费劲。 所以还有一个就是Hash法 Hash 法这个的话,依然是需要Node来存储的,区别是直接先初始化,这样会快很多。我们同样表示上面那颗树。 这样一来也会稍微快一点,毕竟可以一次性初始化,一次性开辟和多次开辟是不一样的消耗。尤其是对Java来说,new 已经够慢了,虽然反射更慢,最快克隆。 而且说句实话,能用Python就Python,java 一个Scanner就把你坑住了了,C++,我不会,不熟悉,而且那玩意比Python难写多了。对于输入少,比较考验数据结构,没有精度问题的时候,在直接使用java,不过不知道为啥,可能是PTA这个平台的问题,同样的情况下,java 实现的往100+ms跑了,但是 Python 的就几十ms 。是不是把编译时间算上去了,咱们不知道,不过由于这个特性,所以,java 不敢写暴力,我Python阔以。 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/26 7:51:40- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |