数据结构-二叉树及其拓展

前言:

二叉树是数据结构中最重要的非线性结构之一,其分层特性和递归定义使其成为理解树、图等复杂结构的基础。本文将系统介绍二叉树的核心概念、分类及进阶拓展(如平衡树、B 树等),并通过 Python 代码演示关键操作的实现,帮助读者建立从理论到实践的完整认知。

一、二叉树的本质定义与核心特性
1.1 定义

二叉树是一种分层的树状数据结构,每个节点最多有两个子节点,分别称为左子节点右子节点。其递归定义为:

空树是二叉树;

若 T 是非空树,则 T 由根节点、左子树 TL 和右子树 TR 组成,且 TL 和 TR 均为二叉树。

1.2 核心特性

1、每个节点度≤2:节点的子节点数量只能是 0、1 或 2。

2、有序性:左子树和右子树是有序的(交换左右子树会形成不同的二叉树)。

3、分层结构:具有根节点(第 1 层),每一层节点最多有 2^(i-1) 个(i 为层数)。

二、二叉树的分类:从特殊到一般

2.1满二叉树

定义:除最后一层外,所有层的节点都有两个子节点,且最后一层节点全为叶子节点(无任何子节点)。

数学特征:若高度为 h,则总节点数为 2^h - 1(h≥1)。

特点:每层节点 “填满”,无空缺,适合用链式存储或完全二叉树的顺序存储。

2. 2完全二叉树

定义:除最后一层外,其余层节点数均达到最大值,且最后一层节点从左到右连续存在(不允许中间有空缺)。

关键性质

可使用顺序存储结构(数组)高效表示,根节点索引为 0,左子节点为 2i+1,右子节点为 2i+2。高度为 h 的完全二叉树节点数范围:2^(h-1) ≤ n < 2^h

2.3 平衡二叉树

定义:任意节点的左、右子树高度差不超过 1。

典型实现

AVL 树:严格平衡,通过旋转(LL、RR、LR、RL)保持平衡,插入 / 删除时最多旋转 2 次。

红黑树:弱平衡(最长路径 ≤ 最短路径的 2 倍),通过颜色标记(红 / 黑)和少量旋转实现高效平衡,应用更广泛(如 Java 的TreeMap)。

作用:避免退化为链表,保证搜索、插入、删除的时间复杂度为 O(log n)

三、二叉树核心操作的代码实现(Python)

3.1节点定义与树构建

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val    # 节点值
        self.left = left  # 左子节点
        self.right = right# 右子节点

# 示例:构建一棵简单二叉树
#      根节点 1
#     /      \
#    2        3
#   / \
#  4   5
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
root.left.left = TreeNode(4)
root.left.right = TreeNode(5)
3.2深度优先遍历(DFS) 
# 前序遍历(根→左→右)
def preorder(root):
    if root:
        print(root.val, end=' ')
        preorder(root.left)
        preorder(root.right)

# 中序遍历(左→根→右)
def inorder(root):
    if root:
        inorder(root.left)
        print(root.val, end=' ')
        inorder(root.right)

# 后序遍历(左→右→根)
def postorder(root):
    if root:
        postorder(root.left)
        postorder(root.right)
        print(root.val, end=' ')
3. 3广度优先遍历(BFS,层序遍历) 
        return []
    queue = deque([root])
    result = []
    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)
        result.append(level)
    return result

四、二叉树的进阶结构与应用

4.1 AVL 树:严格平衡的二叉搜索树

特性:左右子树高度差不超过 1,通过旋转保持平34衡。

旋转类型

LL 旋转(左左插入):右单旋,调整失衡节点的左子3树。

RR 旋转(右右插入):左单旋,调整失衡节点的右子3树。

LR 旋转(左右插入):先左后右双旋,调整失衡节点的左子树的右子3树。

RL 旋转(右左插入):先右后左双旋,调整失衡节点的右子树的左子3树。

应用:早期数据库索引,需频繁查询但较少插入 / 删除的场景。

4.2 红黑树:高效的弱平衡树

核心规则

节点非红即黑,根节点和叶子节点(虚拟 NULL)为黑色。

红色节点的子节点必须为黑色,任意路径上黑色节点数相同。

插入修复逻辑:若父节点为红色,根据叔叔节点颜色调整:

叔叔为黑色:通过旋转(左旋 / 右旋)调整颜色,恢复平衡。

叔叔为红色:父、叔变黑,祖父变红,递归处理祖父;

应用:Java 的TreeMap、C++ 的std::map、Linux 内核调度器。

4.3 B 树与 B + 树:适合磁盘存储的多叉树

B 树

结构:每个节点包含多个键值对,子节点数介于\(m/2\)和m之间(m 为阶数)。

操作:插入时若节点满则分裂,删除时若节点不足则合并,保证树高为 (O (\log_m n)7)。

B + 树

特性:所有数据存储在叶子节点,叶子节点通过链表连接,支持高效范围查78询。

应用:数据库索引(如 MySQL 的 InnoDB 引擎)、文件系统(如 NTFS8)。

4.4 哈夫曼树:最优前缀编码

构建步骤:将所有节点按权重排序,每次选取权重最小的两个节点作为左右子树,合并为父节点(权重为两者之和);重复直至形成单棵树,左路径编码为 0,右路径编码为 1。

import heapq

class HuffmanNode:
    def __init__(self, val, freq):
        self.val = val
        self.freq = freq
        self.left = self.right = None

def build_huffman_tree(frequencies):
    heap = [HuffmanNode(char, freq) for char, freq in frequencies.items()]
    heapq.heapify(heap)
    while len(heap) > 1:
        left = heapq.heappop(heap)
        right = heapq.heappop(heap)
        parent = HuffmanNode(None, left.freq + right.freq)
        parent.left, parent.right = left, right
        heapq.heappush(heap, parent)
    return heap[0]

五、总结

二叉树是理解树形结构的基石,其递归特性和分层设计为后续学习平衡树(AVL / 红黑树)、多叉树(B/B + 树)及应用算法(如哈夫曼编码)提供了理论基础。通过掌握二叉树的遍历、构建及扩展结构,可有效提升算法思维和问题解决能力,尤其在面试和实际开发(如数据库索引、数据压缩)中具有重要价值。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

佩可official

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值