[路飞]前端算法——数据结构篇(三、树): 初识二叉树

310 阅读4分钟

前言

前端算法系列是我对算法学习的一个记录, 主要从常见算法数据结构算法思维常用技巧几个方面剖析学习算法知识, 通过LeetCode平台实现刻意练习, 通过掘金和B站的输出来实践费曼学习法, 我会在后续不断更新优质内容并同步更新到掘金、B站和Github, 以记录学习算法的完整过程, 欢迎大家多多交流点赞收藏, 让我们共同进步, daydayup👊

目录地址:目录篇

相关代码地址: Github

相关视频地址: 哔哩哔哩

一、概念

a54ad9458c9adf3b19be70f50fa68585.jpeg

(一)、树

树在我们的日常生活中非常常见, 而在在算法的世界里, 它也是我们经常需要用到的一种数据结构. 也正是从它开始, 我们从原本的 线性表结构 向更复杂的数据结构前进.

计算机中所说的树与现实中的树不同的是, 它更像是埋藏在地底的树根, 它从一个根节点开始, 向下不断扩散, 在数据结构上它就像是一个分叉的链表.

12cd91da2618c8f7700c26226feedd91.jpeg

(二)、度

度: 每个节点的边的数量

入度: 以该节点为末尾的边的数量

出度: 以该节点为开头的边的数量

997c524fee72c4bf852e6db068139974.jpeg

(三)、遍历

遍历方式
前序遍历
中序遍历
后序遍历

image.png

前序遍历为例, 在遍历二叉树时

会首先将根节点输出, 然后输出左节点, 再输出右节点

⚠️需要注意的是, 如果左节点有子节点, 需要优先对子节点也按根左右的顺序遍历

也就是遍历过程遵循: 深度优先原则

以上图为例, 按照前序遍历的方式输出应为:

// A, B, C, D, E, F
// 按顺序先输出根节点A, 然后因为A的左节点有子节点, 深度优先,
// 所以先按根左右的顺序输出 B, C, D, 再去输出A的右节点 E, F

除了上面三种遍历方式外, 树还有一种 广度优先 的遍历方式: 层序遍历

同样以上图为例, 按层序遍历的顺序则输出应为:

// A B E C D F
// 按照每层从左到右的顺序输出

二叉树的几种遍历方式其实代表了不同的处理问题的思路:

层序遍历方式代表: 广度优先, 其他三种则是 深度优先

前序遍历方式代表: 自顶向下

后序遍历方式代表: 自底向上

(肆)、二叉树

1、定义

1、每个节点的度最多2

2、度为0的节点比度为2的节点多1个

2、图例

下图为几种比较常见的二叉树

d09fe7f63a1fae3308bf6a9977e1be2f.jpeg

满二叉树

除最后一层每个节点的度为 0 外, 其他每层的节点度都为 2, 也就是都有左右子树

完全二叉树

只有最后一层的右边部分缺少节点, 需要注意的是, 二叉树的最后一层需要左边是连续的节点. 另外, 假设二叉树的高度是 h, 那么完全二叉树的第 h - 1 层应该是是一个满二叉树

3、特性

1、在二叉树的第 n 层, 最多有 2的n-1次方 个节点

2、如果二叉树的高度为 k, 那么该二叉树最多有 2的k次方-1 个节点

3、在完全二叉树中, 如果存在 n 个节点, 那么二叉树的高度为 log2n + 1 (向下取整)

二、实现

上面我们已经大概了解关于二叉树的基本知识, 接下来我们来具体的实现一下, 其实二叉树的实现非常简单, 我们只需要实现其中的一个节点就可以了

function TreeNode(val, left, right) {
    this.val = (val===undefined ? 0 : val)
    this.left = (left===undefined ? null : left)
    this.right = (right===undefined ? null : right)
}

哈哈 略显敷衍, 下一篇中我们来具体的实现一下二叉树的几种遍历方式!下期再见!

TODO 深搜DFS与广搜BFS 二叉树的经典问题 大顶堆与小顶堆 手撕AVL树