二叉树及其简单遍历方式

530 阅读2分钟

前言

什么是二叉树? 一种数据结构,其中每个节点最多有两个子节点(不一定每个节点都有两个子节点),通常被称之为左节点右节点。二叉树中的每个节点包含三个部分:数据元素、指向左子树的引用以及指向右子树的引用。空树也可称为二叉树;非空树,必须由 根节点 左子树和右子树构成,且左右子树都是二叉树。

image.png

创建一个二叉树

function TreeNode(val) {
    this.val = val;
    this.left = null;
    this.right = null;
}

const node = new TreeNode(1)

const node2 = new TreeNode(2)
const node3 = new TreeNode(3)
node.left = node2
node.right = node3

image.png

用对象表示二叉树

image.png 怎么用对象表示该二叉树?

const root = {
    val: 1,
    left: {
        val: 2,
        left: {
            val: 4
        },
        right: {
            val: 5
        }
    },
    right: {
        val: 3,
        right: {
            val:6
        }
    }
}

二叉树的遍历方式

  • 先序遍历 --- 根左右
  • 中序遍历 --- 左根右
  • 后序遍历 --- 左右根

示例

image.png

先序遍历 --- 根左右

const root = {
    val: 1,
    left: {
        val: 2,
        left: {
            val: 4
        },
        right: {
            val: 5
        }
    },
    right: {
        val: 3,
        right: {
            val:6
        }
    }
}

function preorder(root) {
    if(!root) {     // 递归一定要出口不然会报错
        return
    }
    console.log(root.val);
    // root.left
    preorder(root.left) 
    preorder(root.right)
}
preorder(root)

打印结果

image.png

分析

  • 当先遍历到节点1时,判断该节点是否为空,不为空则跳出if语句,打印该节点1判断该节点是否有左子节点。
  • 若有左子节点,递归调用该遍历函数把做左子节点作为参数传入,再重新判断,打印值2,判断节点2是否有左子节点。
  • 若有则打印其值4,判断节点4是否有左右子节点,无就执行if语句跳出该递归。
  • 返回到2节点,执行preorder(root.right),判断其是否有右节点,有则将其作为参数传入。
  • 先打印节点5的值为5,判断节点5是否有左右节点,无则执行if语句跳出递归。
  • 返回到1节点,执行preorder(root.right),判断其是否有右子节点,有将其作为参数传入。
  • 先打印节点3的值为3,再判断节点3是否有左子节点,无则跳出递归返回到节点3,再执行preorder(root.right),判断其是否有右子节点,有则将其作为参数传入。
  • 先打印该右子节点6的值为6,判断其是否有左右子节点,都没有,跳出递归。所以打印顺序为1 2 4 5 3 6。 剩下两种二叉树的简单遍历方法与该方法类似。

中序遍历

先找左节点再找根节点最后找右节点

function inorder(root) {
    if(!root) return
    inorder(root.left)  
    console.log(root.val);  // 4 2 5 1 3 6
    inorder(root.right)
}
inorder(root)

打印结果

image.png

后序遍历

先找左节点再找右节点最后找根节点

function postorder(root) {
    if(!root) return
    postorder(root.left)
    postorder(root.right)
    console.log(root.val);
}
postorder(root)

打印结果

image.png

结语

Thanks.jpg