代码随想录算法训练营第十三天|二叉树

199 阅读2分钟

二叉树

二叉树种类

  • 满二叉树

    如果一棵二叉树只有度为0的结点和度为2的结点,并且度为0的结点在同一层上,则这棵二叉树为满二叉树

  • 完全二叉树

    在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2^(h-1) 个节点

  • 二叉搜索

    是有数值的

    • 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
    • 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
    • 它的左、右子树也分别为二叉排序树
  • 平衡二叉搜索

    它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树

二叉树存储方式

  • 链式存储

    链表实现

  • 顺序存储

    数组实现,根节点为i,左子树为2i+1,右子树为2i+2

    这种情况下,非完全二叉树需要转化为完全二叉树才能存储,这样会浪费空间

二叉树的遍历

深度遍历

  • 前序遍历

    中左右

  • 中序遍历

  • 左中右

  • 后序遍历

    左右中

广度遍历

层次遍历

递归遍历

递归的步骤:

  • 确定递归函数的参数和返回值
  • 确定终止条件
  • 确定单层递归的逻辑

前序遍历

中左右

var preorderTraversal = function(root) {
    let arr = []
    function dfs(root){
        if(root === null) return;
        // 遍历的顺序
        arr.push(root.val)
        dfs(root.left)
        dfs(root.right)
    }
    dfs(root);
    return arr;
​
};
  • 参数这里只需要一个root,也就是当前节点
  • 终止条件比较简单,当前节点为空时,终止
  • 单层的递归逻辑,中间节点就入栈,然后左边,然后右边

后序遍历

左右中

这里主要是把单层的递归逻辑改变一下

dfs(root.left)
dfs(root.right)
arr.push(root.val)

按照左右中的顺序

中序遍历

左中右

dfs(root.left)
arr.push(root.val)
dfs(root.right)

总结

这里的递归逻辑比较难以理解,因为这里单层的递归逻辑中有两个递归函数

所以,很容易搞乱

这里要抓住递归的底层逻辑是栈这一点来写,比如,以中序遍历为例

image-20230329162946509

单层递归逻辑如下:

dfs(root.left)
arr.push(root.val)
dfs(root.right)

迭代遍历

用栈结构

这部分先放过,留到二刷再回来写