看到一篇很好的二叉树文章,翻译过来与大家共享

二叉树

最近读了一篇很好的关于二叉树的英文文章,想把这篇文章翻译成中文共享

介绍

我们期望数据结构不仅仅是一对一的关系,二叉树由节点组成,节点包含左节点的地址,右节点的地址,还有值,最顶部的节点叫做根节点。
每个节点(除了根节点)都挂载到其它节点上,被挂载的节点是父节点,每个节点下面可以连接任意多个节点,被称为这个节点的子节点,没有子节点的节点叫做叶子,或则外部节点,其它节点叫做内部节点,挂载在同一个节点下面的两个节点称为兄弟节点

更多术语

  • 节点深度: 表示从根节点到节点的边数
  • 节点高度:表示从节点到最深叶子的边数
  • 树的高度也就是根节点的高度
  • 一个完满二叉树是每个节点有两个或则不存在子节点
  • 一个完全二叉树,他除了底层是被完全填满的,底层的填充规则是从左到右
    [图片上传失败...(image-b2cf92-1585324873747)]

一个完全二叉树是一个特殊的树,它提供极好的平衡在节点数量和高度之间,它的高度h和节点N的关系可以表示为h=O(log N)。我们能够很容易的通过层级推算出这个层级的节点总计
[图片上传失败...(image-8d6411-1585324873747)]

=》
h = O(log n)

二叉树的优点

二叉树是如此的有价值和被如此的平凡的使用,是因为它们有非常显著的优点

  • 树反映和记录了数据之间的关系
  • 树被使用去展示层次结构
  • 树有很好的插入和查询效率
  • 树是非常灵活的数据,只需要非常小的成本即可移动节点

遍历

遍历就是浏览这棵树里面所有的子节点,因为树的结构是非线性的,所以遍历的方法也不是唯一的,可以分为以下两种遍历大类

  • 深度遍历
  • 广度遍历

针对深度遍历又存在三种不同的遍历方法

  • 先序遍历: 首先浏览父节点,然后浏览左节点和右节点(中左右)
  • 中序遍历: 首先浏览左节点,然后浏览父节点,最后浏览中节点 (左中右)
  • 后序遍历: 首先浏览左节点,然后浏览右节点,最后浏览父节点(左右中)

针对广度遍历只有一种方法,那就是从根节点一层一层的往下遍历

下面是四种不同的遍历方法的输出

  • 前序遍历 - 8, 5, 9, 7, 1, 12, 2, 4, 11, 3

  • 中序遍历 - 9, 5, 1, 7, 2, 12, 8, 4, 3, 11

  • 后序遍历 - 9, 1, 2, 12, 7, 5, 3, 11, 4, 8

  • 广度遍历 - 8, 5, 4, 9, 7, 11, 1, 12, 3, 2*

    [图片上传失败...(image-7d4076-1585324873747)]

下面是1,2,3...7按照不同的遍历逻辑插入的例子
[图片上传失败...(image-6ce35d-1585324873747)]

如果我们遍历每个节点三次,那我们就可以使用同一个算法表示三种深度遍历,一个欧拉向导表示的是围绕二叉树随意走,但是每个边缘视为一堵墙,不能被穿过,在这个随意走的过程中,每个节点能够被浏览在左边,下边或则右边,这个欧拉向导我们浏览这个左边的过程叫做先序遍历,当我们浏览下边的过程,叫做中序遍历,当我们浏览右边的过程,叫做后序遍历
[图片上传失败...(image-898dfd-1585324873747)]

二叉树查找

我们考虑一种特殊的二叉树叫做二叉查找树(BST),设计这种树的基础需求是能够有一种存储库能够提供有效的数据排序,查询和检索
一个平衡二叉树它的节点排序遵循以下几个规则

  • 每个节点包含一个值
  • 左边的值是小于父节点的
  • 父节点的值是小于右节点的值的
  • 重复值是不被允许的

下面这张图中所有的左节点的值都是小于10的,所有右边节点的值都是大于10的,因为每个左节点和右节点都是一个子二叉查找树,所以这个规则递归适合每一个节点
[图片上传失败...(image-fdfd56-1585324873747)]

实现

因为原文使用的是java,我对nodejs比较熟悉,我使用nodejs来实现这个程序

插入

插入的逻辑和查找的逻辑十分相似,从根节点递归往下比较,直到符合查找二叉树的规则位为止,如果有重复的值,不做任务操作,行为停止

// insert
function insert(value) {
  function doInsert(tree) {
    if (!tree) {
      tree = node(value);
    } else {
      if (tree.value > value) {
        if (!tree.left) {
          tree.left = node(value);
        } else {
          doInsert(tree.left);
        }
      } else {
        if (!tree.right) {
          tree.right = node(value);
        } else {
          doInsert(tree.right);
        }
      }
    }
  }
  doInsert(tree);
}
练习

给与一系列数字

11,6,8,19,4,10,5,17,43,49,31

画出一个二叉查找树通过上面这些数字
[图片上传失败...(image-2841e0-1585324873747)]

查找

查找是从二叉查找树的根节点开始的,使用需要比较的数据和根节点比较(称呼整个过程为toSearch),如果和根节点的值不匹配,我们根据比较结果决定是和左节点还是右节点进行比较,如果数据的值大于根节点,就和右节点进行比较,反之则和左节点进行比较,同理向下递归处理直到找到匹配的值

在查找二叉树中最坏的运行复杂度是O(h),h是树的高度,一颗有n个节点的二叉查找树的最小高度是O(log n) ,需要花费至少O(log n)次比较去查找需要的节点,最糟糕的情况是二叉查找树可能转换为链表,此时的查找时间为O(n)

删除

删除比查找更复杂,有以下几种情况需要考虑(我们叫整个过程为toDelete)

  • 不在树上
  • 是叶子节点
  • 只有一个子节点
  • 有两个子节点

如果toDelete的数据没有在节点上或则是叶子节点,那不需要做任何操作。如果删除的节点只有一个节点,类似于链表,我们仅仅需要跳过被删除的节点把整棵树链接起来
[图片上传失败...(image-de3842-1585324873747)]
删除有两个子节点的情况还是比较复杂的,首先整棵树会被分成两棵字树,一些内部的节点将会没办法遍历到,就像如下的情况
[图片上传失败...(image-7e20d7-1585324873747)]
删除策略如下,用左节点最大的节点代替被删除的节点,也可以使用右节点最小的节点代替被删除的节点,根据节点的对称性决定

完整的demo可以参考BST
原文链接

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

推荐阅读更多精彩内容