day2:二叉树遍历

122 阅读2分钟

只吹理解不记忆,不如回家去种地:)

不要沉溺在“我看懂了”、“我理解了”、“我知道你说的是啥意思了”这种虚无的成就感中——假的,都是假的,只有自己写出来的代码才是真的!

二叉树的遍历

按照顺序规则:

  • 先序遍历
  • 中序遍历
  • 后序遍历
  • 层次遍历

按照实现方式:

  • 递归遍历(先、中、后序遍历)
  • 迭代遍历(层次遍历)

递归遍历

简单来说,一个函数反复调用自己的时候,递归就发生了;需要了解两个概念:

  • 递归式 :每一次重复的内容是什么
  • 递归边界 :指的是你什么时候停下来

最基本的二叉树结构:根结点,左子树,右子树

image.png

根据“根结点”的位置,那么遍历顺序可以有:

  • 根结点 -> 左子树 -> 右子树 (先序遍历)
  • 左子树 -> 根结点 -> 右子树 (中序遍历)
  • 左子树 -> 右子树 -> 根结点 (后序遍历)

先序遍历

GIF 2022-8-17 14-57-33.gif 代码实现:

const root = {
    val: "A",
    left: {
        val: "B",
        left: {
            val: "D"
        },
        right: {
            val: "E"
        }
    },
    right: {
        val: "C",
        right: {
            val: "F"
        }
    }
};

// 所有遍历函数的入参都是树的根结点对象
function preorder(root) {
    // 递归边界,root 为空
    if (!root) {
        return
    }

    // 输出当前遍历的结点值
    console.log('当前遍历的结点值是:', root.val)
    // 递归遍历左子树 
    preorder(root.left)
    // 递归遍历右子树  
    preorder(root.right)
}

当前遍历的结点值是: A
当前遍历的结点值是: B
当前遍历的结点值是: D
当前遍历的结点值是: E
当前遍历的结点值是: C
当前遍历的结点值是: F

中序遍历

左序遍历.gif

// 中序遍历
// 所有遍历函数的入参都是树的根结点对象
function inorder(root) {
    // 递归边界,root 为空
    if (!root) {
        return
    }

    // 递归遍历左子树 
    inorder(root.left)
    // 输出当前遍历的结点值
    console.log('当前遍历的结点值是:', root.val)
    // 递归遍历右子树  
    inorder(root.right)
}

当前遍历的结点值是: D
当前遍历的结点值是: B
当前遍历的结点值是: E
当前遍历的结点值是: A
当前遍历的结点值是: C
当前遍历的结点值是: F

后序遍历

后续遍历.gif

function postorder(root) {
    // 递归边界,root 为空
    if (!root) {
        return
    }

    // 递归遍历左子树 
    postorder(root.left)
    // 递归遍历右子树  
    postorder(root.right)
    // 输出当前遍历的结点值
    console.log('当前遍历的结点值是:', root.val)
}

当前遍历的结点值是: D
当前遍历的结点值是: E
当前遍历的结点值是: B
当前遍历的结点值是: F
当前遍历的结点值是: C
当前遍历的结点值是: A

——————————————————————

(关于迭代遍历(层次遍历)真题中学习)