二叉树的基本知识你还记得多少?

前言

今天我们来聊聊数据结构中的二叉树结构。树是一种非线性的数据结构,而二叉树是树结构中的一种,由节点(node)和连接这些节点的边(edge)组成。

基本概念

什么是树,在现实生活中我们的树就是由一根主干加许多枝条,枝条上有许多叶子组成。那么在数据结构中我们也是这么表示的,只不过这棵树是倒过来的树。

树的定义

  • :树是一种由节点组成的层次结构,其中每个节点包含一个值或条件,节点之间通过边连接。
  • 根节点(Root):树的顶层节点,没有父节点。
  • 子节点(Child):从一个节点直接连接下来的节点称为其子节点。
  • 父节点(Parent):直接连接到一个子节点的节点称为其父节点。
  • 叶节点(Leaf):没有子节点的节点。
  • 内部节点(Internal Node):有至少一个子节点的节点。
  • 兄弟节点(Sibling):同一个父节点的子节点。

树的属性

  • 高度(Height):从根节点到叶节点的最长路径上的边数。
  • 深度(Depth):从根节点到某一节点的边数。
  • 层次(Level):树中所有深度相同的节点的集合。
  • 度(Degree):一个节点拥有的子节点的数量。树的度是所有节点中最大的度。

树的类型

  • 二叉树(Binary Tree):每个节点最多有两个子节点,称为左子节点和右子节点。

    • 完全二叉树(Complete Binary Tree):除了最后一层外,所有层都是满的,最后一层的节点从左到右依次排列。
    • 满二叉树(Full Binary Tree):每个节点要么有两个子节点,要么没有子节点。
  • 红黑树(Red-Black Tree):一种自平衡二叉搜索树,每个节点带有额外的颜色属性(红或黑),用于保持树的平衡。

二叉树的定义

在代码中,我们经常使用这两种方式来表示一颗树。

使用对象的方式

ini 复制代码
function TreeNode(val){
    this.val = val;
    this.left = null;
    this.right = null;
}

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

使用数组的方式

css 复制代码
const root = {
    val: 1,
    left: {
        val: 2,
        left: {
            val: 4
        },
        right: {
            val: 5
        }
    },
    right: {
        val: 3,
        left: {
            val: 6
        },
        right: {
            val: 7
        }
    }
}

二叉树的遍历

二叉树的遍历分为深度优先(dfs)和广度优先(bfs)

深度优先是指先尽可能的深入树的分支,当无法深入时再回溯,遍历上一个分叉口的另一个分支。

广度优先是指逐层访问节点,先访问离起始节点最近的节点,一层一层遍历,就像漫出去的水一样。

接下来我们用算法来实现这两种遍历方式。使用递归的方式很简单,你能实现使用迭代的方式完成吗?

深度优先

  1. 先序遍历

先遍历根节点,再遍历左节点、右节点

scss 复制代码
function preOrder(root){
    if(!root){
        return;
    }
    console.log(root.val);
    preOrder(root.left)
    preOrder(root.right)
}
  1. 中序遍历

先遍历左节点,再遍历根节点、右节点

scss 复制代码
function midOrder(root) {
    if (!root) {
        return;
    }
    midOrder(root.left)
    console.log(root.val);
    midOrder(root.right)
}
  1. 后序遍历

先遍历左节点,再遍历右节点、根节点

scss 复制代码
function afterOrder(root) {
    if (!root) {
        return;
    }
    afterOrder(root.left)
    afterOrder(root.right)
    console.log(root.val);
}

接下来我们使用迭代的方式来实现一个先序遍历

scss 复制代码
var preorderTraversal = function(root) {
    if(!root) return []//如果是空树则返回一个空数组
    let stack = []//定义一个栈来辅助遍历
    let res = []//将结果存储并且返回
    stack.push(root)//首先将根节点入栈
    while(stack.length){
        let top = stack.pop()
        res.push(top.val);//拿到当前栈顶元素,并将值存储
        if(top.right){//如果当前出栈的节点有右节点,则入栈
            stack.push(top.right)
        }
        if(top.left){//如果当前出栈的节点有左节点,则入栈
            stack.push(top.left)
        }
    }
    return res
};

广度优先

层序遍历

一层一层遍历,逐层访问节点

scss 复制代码
function levesOrder(root){
    let queue = []
    queue.push(root)
    while(queue.length){
        let top = queue.shift()
        console.log(top.val);
        if(top.left){
            queue.push(top.left)
        }
        if(top.right){
            queue.push(top.right)
        }
    }
}
相关推荐
dy17171 小时前
element-plus表格默认展开有子的数据
前端·javascript·vue.js
2501_915918415 小时前
Web 前端可视化开发工具对比 低代码平台、可视化搭建工具、前端可视化编辑器与在线可视化开发环境的实战分析
前端·低代码·ios·小程序·uni-app·编辑器·iphone
程序员的世界你不懂5 小时前
【Flask】测试平台开发,新增说明书编写和展示功能 第二十三篇
java·前端·数据库
索迪迈科技5 小时前
网络请求库——Axios库深度解析
前端·网络·vue.js·北京百思可瑞教育·百思可瑞教育
gnip5 小时前
JavaScript二叉树相关概念
前端
attitude.x6 小时前
PyTorch 动态图的灵活性与实用技巧
前端·人工智能·深度学习
β添砖java6 小时前
CSS3核心技术
前端·css·css3
空山新雨(大队长)7 小时前
HTML第八课:HTML4和HTML5的区别
前端·html·html5
小欣加油7 小时前
leetcode 面试题01.02判定是否互为字符重排
数据结构·c++·算法·leetcode·职场和发展