数据结构:树

核心定义

树是非线性数据结构,由n(n≥0)个节点组成的有限集合:

  • 当n=0时,称为"空树";
  • 当n>0时,有且仅有一个根节点(Root) ,其余节点分为若干个互不相交的子集,每个子集仍是树(称为"子树")。
  • 资料:https://pan.quark.cn/s/43d906ddfa1b

关键术语(必记)

术语 定义
根节点(Root) 树的最顶层节点,无父节点(如文件系统的"根目录")。
父节点/子节点 若节点A直接包含节点B,则A是B的父节点,B是A的子节点(父子是直接关系)。
兄弟节点 同一父节点的子节点互称兄弟(如同一文件夹下的同级文件)。
叶子节点 无子节点的节点(树的"末端")。
深度(Depth) 从根节点到当前节点的路径长度(根节点深度=0或1,需注意场景约定)。
高度(Height) 从当前节点到最远叶子节点的路径长度(叶子节点高度=0)。
层数(Level) 根节点为第1层(或第0层),子节点层数=父节点层数+1(与深度对应)。
子树(Subtree) 以某节点为根的所有后代节点组成的树(含该节点)。

树的核心特性

  1. 无环性:任意两个节点之间有且仅有一条路径(不存在循环);
  2. 层次性:节点按"父子关系"分层排列,根在上,叶子在下;
  3. 唯一性:有且仅有一个根节点,所有非根节点有且仅有一个父节点。

常见树的分类(高频考点)

1. 按节点子树数量划分

  • 二叉树 :每个节点最多有2个子节点(左子树、右子树),是最常用的树结构;
    • 特殊二叉树:满二叉树(所有叶子节点在同一层,且非叶子节点都有2个子节点)、完全二叉树(按层序编号,与满二叉树编号一致,缺右不缺左)。
  • 多叉树 :每个节点可以有多个子节点(如三叉树、N叉树);
    • 典型应用:文件系统(目录树)、Trie树(前缀树)。

2. 按特殊规则划分

  • 二叉搜索树(BST):左子树所有节点值 < 根节点值,右子树所有节点值 > 根节点值(支持快速查找、插入、删除,时间复杂度O(logn),最坏O(n));
  • 平衡二叉树(AVL):左右子树高度差绝对值≤1(解决BST失衡问题,保证查找效率稳定O(logn));
  • 红黑树:通过"红黑节点"规则维持平衡(插入删除效率比AVL高,用于Java TreeMap、HashMap(JDK8));
  • B树/B+树:多路平衡查找树(用于数据库索引,适配磁盘IO)。

二叉树的存储方式

  1. 顺序存储(数组)

    • 适用于完全二叉树,按层序编号存储(根节点存index=0,左子节点=2i+1,右子节点=2i+2);
    • 优点:访问节点快,无需存储指针;缺点:非完全二叉树浪费空间。
  2. 链式存储(链表)

    • 每个节点包含"数据域"+"左指针(指向左子树)"+"右指针(指向右子树)";
    • 优点:空间利用率高,适合任意二叉树;缺点:访问子节点需通过指针遍历。

二叉树的核心遍历算法(必会代码)

遍历目标:按一定顺序访问树中所有节点,分为深度优先(DFS)广度优先(BFS)

1. 深度优先遍历(DFS)

(1)前序遍历(根→左→右)
python 复制代码
# 递归实现
def preorder(root):
    if not root:
        return []
    return [root.val] + preorder(root.left) + preorder(root.right)

# 迭代实现(栈)
def preorder_iter(root):
    stack, res = [root] if root else [], []
    while stack:
        node = stack.pop()
        res.append(node.val)
        if node.right:  # 右子树先入栈(栈先进后出)
            stack.append(node.right)
        if node.left:
            stack.append(node.left)
    return res
(2)中序遍历(左→根→右)
  • 二叉搜索树的中序遍历是升序序列(核心特性)。
python 复制代码
# 递归实现
def inorder(root):
    if not root:
        return []
    return inorder(root.left) + [root.val] + inorder(root.right)

# 迭代实现(栈)
def inorder_iter(root):
    stack, res, curr = [], [], root
    while stack or curr:
        while curr:  # 左子树到底
            stack.append(curr)
            curr = curr.left
        curr = stack.pop()
        res.append(curr.val)
        curr = curr.right  # 访问右子树
    return res
(3)后序遍历(左→右→根)
python 复制代码
# 递归实现
def postorder(root):
    if not root:
        return []
    return postorder(root.left) + postorder(root.right) + [root.val]

# 迭代实现(栈+标记)
def postorder_iter(root):
    stack, res = [(root, False)] if root else [], []
    while stack:
        node, visited = stack.pop()
        if visited:
            res.append(node.val)
        else:
            stack.append((node, True))  # 标记根节点,后续处理
            if node.right:
                stack.append((node.right, False))
            if node.left:
                stack.append((node.left, False))
    return res

2. 广度优先遍历(BFS,层序遍历)

  • 按"层"访问节点(从上到下,从左到右),用队列实现。
python 复制代码
from collections import deque

def levelorder(root):
    if not root:
        return []
    res = []
    queue = deque([root])
    while queue:
        level_size = len(queue)  # 当前层节点数
        level = []
        for _ in range(level_size):
            node = queue.popleft()
            level.append(node.val)
            if node.left:
                queue.append(node.left)
            if node.right:
                queue.append(node.right)
        res.append(level)  # 按层存储结果
    return res

树的典型应用场景

  1. 数据查找:二叉搜索树、平衡二叉树、B+树(数据库索引);
  2. 排序:二叉搜索树的中序遍历(升序);
  3. 层级数据存储:文件系统、组织架构图;
  4. 字符串处理:Trie树(前缀匹配,如搜索引擎自动补全);
  5. 算法优化:哈夫曼树(数据压缩)、决策树(机器学习)。
相关推荐
kyle~1 小时前
算法与数据结构---并查集(Union-Find)
数据结构·c++·算法
CoderYanger1 小时前
A.每日一题——3512. 使数组和能被 K 整除的最少操作次数
java·数据结构·算法·leetcode·职场和发展·1024程序员节
学困昇1 小时前
Linux基础开发工具(上):从包管理到“进度条”项目实战,掌握 yum/vim/gcc 核心工具
linux·运维·开发语言·数据结构·c++·vim
星释2 小时前
Rust 练习册 105:从零开始实现链表数据结构
数据结构·链表·rust
良木生香2 小时前
【数据结构-初阶】详解算法复杂度:时间与空间复杂度
数据结构
会员果汁2 小时前
优先级队列-C语言
c语言·数据结构·算法
却话巴山夜雨时i2 小时前
347. 前 K 个高频元素【中等】
数据结构·算法·leetcode
蘑菇小白2 小时前
数据结构--栈
数据结构·算法·
Bear on Toilet2 小时前
12 . 二叉树的直径
数据结构·算法·二叉树