聊一聊学习树的经历吧

之前也没有系统的学过数据结构,但是平时用到的数组,链表等还是比较简单的,理解的时候即便没有接触过但是撸一撸源码,看一看画的图,基本上也就会了,树,二叉树,二叉搜索树,平衡二叉树,2-3树(完美平衡二叉树),红黑树。这次主要是在整理Java基本的数据类型Collection和Map子类的时候,发现要想吃透的话,还是绕不过这一块,更别提现在的hashMap和CurrentHashMap在容量大于8时,也抛弃了用链表转向红黑树的实现,这些种种都说明了树对于一个由码农进阶程序员的人来说有多重要。

树对于所有人来说,都是相当熟悉的,本码农以前是学建筑设计的,所以树对于我来说都不知道画了多少颗,树分为树根,树干,树枝,树叶,而对于程序员来说,就是用数字来连接的的一颗树,有根节点(树根),子节点(数干树枝交叉的地方),叶子节点(树叶)。其实这么看起来也很简单(刚开始学的时候也是这么想的),渐渐的接触到二叉树,其实就是一个根最多只有俩树干,每个树干最多只有俩树枝,每个树枝上只有俩树叶,其实学到这里我还是不太理解,树的作用在哪,完全没有规律可寻。我根本就不知道我要插一个数据往哪插,删除一个数据去哪找。我有个坏习惯,看一个东西总想知道为啥要这么写,而且不知道为啥有时候有点没法往下看(虽然我平时都跟女朋友说学习遇到不会的地方先放着,不要一根筋O(∩_∩)O),找遍了网上确实没看到怎么实现,没办法只能先往后看了。

接下来就到了二叉搜索树,这玩意其实很简单,就是在插入的时候如果树里面没有节点,那就是根节点,树里面有节点的话,就跟当前节点比,大的继续查找右子树,小的继续查找左子树,依次类推,直到没有子树,就找到这个节点应该放的位置了,然后放进去就可以了(具体的实现呢,网上有很多,大同小异,找个自己好理解的就可以了:https://blog.csdn.net/WeiJiFeng_/article/details/80227811)。

痛苦的日子开始了,平衡二叉树的学习,有点伤头发的。平衡二叉树,又称AVL树,据说是发明这个伤头发东西的三个科学家的首字母(第一次看到心里还小污了一把,结果发现是我心思不够纯洁,阿弥陀佛),书上给它的定义其实很简单:

1.它是一颗二叉排序树(左边儿子比爸爸小,右边儿子比爸爸大)

2.它的左右两个子树的高度差(平衡因子)的绝对值不超过1并且左右两个字树都是一颗平衡二叉树(其实就是从任意一个节点往下数,节点个数数量不能相差超过1个,ps:相差一个是允许的)

不知道大家有没有发现一个问题,平衡二叉树定义里面居然也写了平衡二叉树,这不是递归吗!!!(划重点了),定义写的真有内涵,这不用递归来实现都对不起AV大神们啊。来来来,再给大家推荐一个个人认为整理的还不错的文章:https://www.cnblogs.com/qm-article/p/9349681.html 这篇文章已经写的很棒了,回头复习可以再来看看,哈哈,我不是因为懒才用别人的。个人建议大家学的时候一定要先把出现需要旋转的场景摸透,其实是有规律可循的,比如说当插入数据在失衡节点的左字树的左边,那就直接用右旋就可以搞定了,而当插入节点在失衡节点的左子树的右边,那就先将左子树左旋(其实大家可以将这块理解为先把失衡节点左子树的右边给旋转到左边去),然后再将失衡节点右旋。还有两种其实也是一样的,具体可以看我推荐的那篇文章。

还有一个点就是刚开始学的时候,完全不知道失衡节点怎么找,其实就是这个节点他的左右字数相差大于1了,然后把他和他的子树可以当作一颗树来旋转,比如下面两颗树:左边插入28变成右边,这时候20这个节点变成了失衡节点(左边只有一个节点,右边最高有30-25-28  3个节点,3-1=2>1,所以失衡啦),那如果我加一个27,会加到28的左子节点,这时候30就变成了失衡节点,将30及下面的子树当成一棵树进行旋转就可以了(很明显27再30左子树25的右边,先将25进行右旋,再将30进行左旋,可以自己画图试试)

                              

看起来确实是很复杂,我要是用链表,加一个数据怎么也不用你翻来覆去这么折腾啊,那为啥我们要这么玩呢? 俗话说天生我才必有用,我平头大树哥

这么辛苦,怎么可能没用呢,吃得苦中苦,方为人上人嘛。 平衡二叉树的查找效率很高,比如上面左边的树,这些数据放到链表,我很有可能要找6次才能找到,而在我平头大树哥的英明领导下,你查三次必然能查得到,这还只是6个数据,如果60个,600个甚至更多呢,那么效率自然是差距越来越大,怎么样我平头大树哥还是很厉害的吧。

聊完了平衡二叉树,是不是觉得这树确实有点极端,你要求那么严格,那么我每次插入数据也太麻烦了吧,所以,牛逼的大佬们就想到要不要换个要求没那么高,我每次插入至少不用转来转去那么多次的啊。红黑树这时候就出来了,红黑树有的人说是2-3树的简化版,听到2-3树的名字呢大家应该可以想到这个树他其实就是2节点和3节点都可以的树,2节点就是我们普通的一个爸爸,两个儿子,3节点就比较厉害了,两个爸爸,三个儿子,左爸爸比右爸爸小,三个儿子刚好在两个爸爸左边中间和右边,如果这个时候又来一个儿子争宠,俩爸爸没位置了,那就分家吧,一个爸爸带俩儿子,一层层往上分,说起来挺容易,但是一想,这玩意让我用代码写,一个头2-3个大,所以就演变成红黑树,说了那么多,其实主角还是红黑树,因为这玩意用的确实多,为啥大家都喜欢用红黑树呢?

其实要了解红黑树为啥这么受欢迎,还要从他的定义说起,红黑树有5个定义:

1、每个节点不是红色就是黑色。

  2、根节点为黑色。

  3、每个叶子节点都是黑色的。

  4、每个红色节点的子节点都是黑色。

  5、任意节点,到其任意叶节点的所有路径都包含相同的黑色节点。

我们逐个分析一下这5点,首先第一点是废话,我们可以不用理他,第二点其实也很好理解,第三点其实第一次看有点疑惑,如果我插入一个红色节点,那我怎么保证他就不是叶子节点呢,后来百度了一下才知道,叶子节点都是黑色空节点。。。好吧厉害,第四点其实就是说,俩红色节点不能相连,第五点其实保证了每两个节点相差不能超过两倍(包含也不行),因为每个分支红色节点是不能超过黑色节点的。其实直到看到第五点,我才稍稍有些释然,这不就是平衡二叉树的平民版嘛,要求没那么高,所以,旋转也没那么多,但是查找的效率可能比平衡二叉树要差一点,但是也还是阔以的。在献上红黑树的文章https://www.cnblogs.com/rainple/p/9983786.html,写的确实还可以。

写这篇文章其实是觉得,我之前在学习的时候,很多都是为了学而学,根本就想不到这些东西在被设计出来的初衷是为了什么,其实现在很多人都是这样,为了拿高工资,面试顺利,去硬啃一些平时用不到的知识,大部分时候我也是为了以后进大厂,拿高工资去学习,但是在平时工作中,这些应该是可以用到的,所以慢慢的会觉得,学了这么多,完全不能融会贯通,真的太鸡肋了,自己想去了解一些背景,了解优略,了解用途,而不只是知道啃。希望有梦想的人都能梦想成真,希望我可以进阿里!!!

原文地址:https://www.cnblogs.com/gmt-hao/p/11831648.html

时间: 2024-11-05 18:39:38

聊一聊学习树的经历吧的相关文章

算法学习 - 树的一些解释

树的解释 树是ADT里面很经典的数据结构了,应用太多了,相对于链表的线性访问时间,O(n).树的大部分操作的平均运行时间都是为O(logN). - 树的概念 树有几种方式定义,一种是递归,若树不为空,则一棵树是由根(root)的节点r和0个或者多个非空树组成.N个节点的树,有N-1个边.没有儿子的节点称为叶子(leaf). 对于任意节点N(i),它的深度为从根节点到N(i)的唯一路径长度.如果存在N(1)到N(2)的路径,那么N(1)是N(2)的祖先.如果N(1)不等于N(2),那么就称为真祖先

谈谈我学习图像处理的经历与收获

谈谈我学习图像处理的经历与收获 大概是在2011年年底的时候,我在家里整理以前的IT书籍.发现我买的几本图像处理的书,于是我又随手翻了翻,发现自己还是挺感兴趣的,就直接放到书架上了,说实话做Java这么多年了,一直都是做外包,想想自己也没什么拿得出手的竞争力.想想英语没英国人讲的好.工作没年纪轻的加班猛.沟通交流没有文科生那圆滑.还是走技术吧,毕竟自己还做了这么久,想想大学毕业设计是关于图像处理的,于是我又捡了起来.从2012年初.坚持自己研究图像处理.期间也有几次想放弃.想去学学安卓什么的,但

复旦微电子牛人学习模电经历

复旦微电子牛人学习模电经历 2011-03-09 18:41:40 分类: IT职场 注:文章内容来自网络,网址不详 复旦攻读微电子专业模拟芯片设计方向研究生开始到现在五年工作经验,已经整整八年了,其间聆听过很多国内外专家的指点.最近,应朋友之邀,写一点心得体会和大家共享. 我记得本科刚毕业时,由于本人打算研究传感器的,后来阴差阳错进了复旦逸夫楼专用集成电路与系统国家重点实验室做研究生.现在想来这个实验室名字大有深意,只是当时惘然.电路和系统,看上去是两个概念,两个层次. 我同学有读电子学与信息

C++学习的一些经历

闲扯C++道路的经历 前言 不知道会不会被骂,毕竟作为一个还不能称为精通C++的人说这些在大神面前总显得有些班门弄斧了. 周围有不少的同学朋友编程都相对比较差,感觉是缺少一些方法,我把我的历程经验贴出来,供大家参考,也欢迎牛人继续讨论. 大学 大学时候,必修的C,选修的C++,当时就只知道什么类呀,继承啊,多态啊之类的称呼,根本不能说会用. 写个Retangle类还行,一碰到实际的需求,还是用C的过程性的描述,外面一大推的全局变量,然后一堆C函数堆砌在一起,就算完成任务了,根本没有面向对象的思想

数据结构学习——树的基本分类

自学数据结构已经很久了,使用的教材是<数据结构与算法分析--C语言描述>.现在回过头来再看一遍此书,重新梳理一下数据结构的相关知识. 以下是摘自维基百科的一些树的基本分类: 无序树:树中任意节点的子节点之间没有顺序关系,这种树称为无序树,也称为自由树: 有序树:树中任意节点的子节点之间有顺序关系,这种树称为有序树: 二叉树:每个节点最多含有两个子树的树称为二叉树: 完全二叉树:对于一颗二叉树,假设其深度为d(d>1).除了第d层外,其它各层的节点数目均已达最大值,且第d层所有节点从左向右

asp.net MVC 小白的笔记-说下这几天学习mvc的经历

到现在才来学习mvc,算是有点晚了,接触的比较晚! 首先是接触到了基础的EF,先说下EF,EF是一种ORM(实体映射对象)框架,是基于ado.net的一种开发更便捷的对数据库进行的技术,有2种开发,一种是ModelFirst,就是 先通过新建ado模型,把数据库中的表直接映射到项目中的模型视图 , 该模型视图下有数据库中的各种字段,并且这些字段会自动生成一个类,映射成一个实体类.还有另外一种就是CodeFirst,顾名思义 就是先写代码,建视图,根据所建的视图,视图之间的关系,关系这里有一个非常

算法学习 - 树的三种遍历(递归实现)先序遍历,中序遍历,后序遍历

树的遍历 这三种遍历方法其实都很简单的,举例来说: a / b c 这个是例子下面讲下这三个是如何遍历的. struct TreeNode; typedef TreeNode* Node; typedef int EleType; struct TreeNode{ Node lchild; Node rchild; EleType data; }; 先序遍历 先序遍历,就是从上到下,从左到右,遇到一个就遍历,上面这个例子遍历的序列就是:a b c 递归代码如下: void PreOrderTre

老男孩学习之亲身经历心得

2015年9月20日,我永远也忘不了的日子,我痛下决心辞去四年的工作来到了帝都北京,学习改变我命运的技能,想用这一技之长来改变自己以后的生活,算是给自己前半生的一个圆满句号. 在我的生命里,体育运动是伴随我时间最长的一项运动,我的项目是中长跑,从我初中的生活就开始,这使得我有一种坚持的精神,我相信只要是自己想达到的愿望,通过自己不懈的努力就可以实现,不管什么事情,最难能可贵的就是坚持.所以我依然辞职,挤进了这个快节奏高消费的大都市--北京. 我对linux没有一点认识,在我的脑海里,电脑就是用来

数据结构学习——树的基本概念

参考书籍<数据结构与算法分析--C语言描述> 连接俩个节点的称为边 一棵树是N个节点和N-1条边的集合 没有儿子的节点称为树叶(叶). 具有相同父亲的称为兄弟. 对任意节点ni,ni的深度为从根到ni的唯一路经长,其中根的深度为0.一棵树叶的深度等于它最深的树叶深度. ni的高是从ni到一片树叶的最长路径的长,一棵树的高等于它根的高,所有树叶的高都是0. 某路径的长为该路径上边的条数. 一棵树的所有节点的深度的和称为内部路径长. 下图所示的树中: 树的根节点为20,有7个节点,3个叶节点. 节