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

前言

今天我们来聊聊数据结构中的二叉树结构。树是一种非线性的数据结构,而二叉树是树结构中的一种,由节点(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)
        }
    }
}
相关推荐
JokerSZ.1 分钟前
【Leetcode 每日一题】268. 丢失的数字
数据结构·算法·leetcode
㣲信团队7 分钟前
小和问题和逆序对问题
数据结构·算法
阿垚啊17 分钟前
列表渲染 v-for
前端·javascript·vue.js·html
铁匠匠匠19 分钟前
django学习入门系列之第三点《BootSrap初了解》
前端·经验分享·笔记·python·学习·django·前端框架
前端宝哥32 分钟前
Composition API VS Options API:谁才是你的最佳选择?
前端·javascript·vue.js
muyierfly34 分钟前
DAY19-力扣刷题
数据结构·算法·leetcode
hummhumm40 分钟前
数据结构第08小节:双端队列
java·数据结构·spring boot·spring·java-ee·maven·intellij-idea
不露声色丶1 小时前
elementPlus表格二次封装
前端·javascript·vue.js
王天乐0071 小时前
ElementUI的搭建
前端·javascript·elementui
OpenTiny社区1 小时前
7月6日 VueConf 技术大会即将在深圳举办
前端·vue.js·github