javaScript构建对称二叉树

       在讲二叉树之前,应该先了解数据结构中关于树的定义:(维基百科)。其中比较重要的常用术语:节点父节点叶子。而二叉树并不是树的特殊情况,因为二叉树和树的定义并不重合,二叉树并不是树的子集。只是二叉树类似树的结构而已。二叉树的定义:二叉树。二叉树比较重要的常用术语:左子树、右子树、根节点、满二叉树完全二叉树。这些概念比较多比较杂,需要花时间好好理解一下。

      今天我要写的是用JavaScript构建满二叉树(再进一步通过二叉树,判断二叉树是否是相同的树(leetcode),或者是否是对称二叉树(leetcode)。二叉树是数据结构与算法中非常重要的一部分,同时也是比较难理解的部分。(我也是通过慢慢理解,自己琢磨,多做笔记,多动手,渐渐消化它的。代码部分尽量讲的详细通俗一点。)

我们假设使用数组来表示二叉树的存储结构(链表也可以,这里使用数组更加方便)

使用es6构建树的节点,添加属性(val, left,right)

这一步的主要作用就是创建二叉树的节点属性。以后二叉树的节点都靠这个函数生成,生成的new Node就全都直接拿来只用。

第二步就开始创建二叉树,这一步有点抽象,需要仔细研读下代码。


通过class,创建二叉树

代码里面的含义,容我一步步解析:(es6中class的语法和constructor我就不细讲怎么使用了)

首先创建一个空数组,用来保存二叉树中所有的节点。那么肯定得先生成二叉树的节点,所以就用到for循环来创建所有节点,并存进数组当中。这里的i是数组的索引,我们的思路是通过数组的索引,找到当前索引对应的节点、当前索引所在的深度(层)、当前索引的父节点......

所以这个代码的核心就是利用二叉树中的节点只有两个分支,从而延申出的各种特性。

比如计算n(当前代码所在的层数)就是利用二叉树的特性: 当前索引和所在层级n之间的关系。这里用一张示意图来描述会更加形象一点:


索引和层级N之间的关系图

从图中不难发现,度数(层数)n和索引之间存在的关系:二叉树左侧的索引值  

                                   i = 2 ^(n - 1) - 1

这个也是构建树的关键点。既然   i = 2^(n - 1) - 1,那我们就可以反推出 


该式就是通过当前元素索引计算当前元素所在层数,但是要向下取整

                            即:n = Math.floor(Math.log2(i +1) + 1)

有了这个表达式,我们就可以继续计算出,当前元素所在层数的第一个索引 p:

                            即:  p = Math.pow(2, n -1) -1

继而可以计算出当前索引对应的父节点对应的索引 q:

                            即: q = Math.floor((i - p) / 2) + Math.pow(2, n - 2) - 1

计算父节点的索引的时候,可能有点会迷糊,为什么要把当前位置的索引 i (p为当前层数的第一个索引)减去 p 除以 2 向下取整呢?这就和二叉树的特点又有关系了。因为二叉树中,一个节点对应两个子节点,当前位置索引减去当前层数第一个索引除以2,取整,就是为了计算出父节点相对于父节点那层的第一个索引移动的数值。Math.pow(2, n - 2) - 1这个式子则是上一层的第一索引值,也就是父节点的层数对应的第一个索引值。如果还是不明白,可以自己动手算一算,纸上得来终觉浅

好了,有了这一步,那父节点的索引我们也就知道了。其实到这里二叉树基本已经确定完毕了,下面就是让这棵树散开枝叶了。

这里就可以开始解释,为什么要在计算n层级是,先加入一个判断 i  > 0,因为当索引 i = 0时,它没有父节点,如果你没加判断条件,运行时会报错。parent.left默认初始值都是null,当遍历到node节点时,把它赋值给他的父节点的左子节点。

我们只需要一个根节点root就行了。利用根节点,就可以一层一层的遍历二叉树。最后把保存节点的临时数组的内存释放,返回跟节点,二叉树的构建到此就结束了。当然,你传入一个数组进去,会输出一个对象node,就是数组的头元素,val等于当前元素的值,left,right都是一个对象,left是左节点,里面有左节点的属性,right是有节点,里面有右节点的属性,同时这些属性都是嵌套的,因为我们就是用这种方式构建二叉树的。


我传入的数组是[3,9,20,null,null,15,7]

对应的树的结构:(先序遍历)


[3,9,20,null,null,15,7]

如果你想验证对称二叉树,就需要在里面定义一个方法,判断二叉树是否对称。如果有人看这篇文章的话, 我再写吧。。。。。。估计也就我看看而已,哈哈哈

后面有时间了,再写下二叉树的遍历: 先序遍历(波兰式),中序遍历,后序遍历(逆波兰)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,830评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,992评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,875评论 0 331
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,837评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,734评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,091评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,550评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,217评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,368评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,298评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,350评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,027评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,623评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,706评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,940评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,349评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,936评论 2 341