c++二叉树详解

一、二叉树基础概念

1. 定义

  • 每个节点最多两个孩子:左孩子、右孩子
  • 分:空树、只有根、只有左子树、只有右子树、左右都有

2. 基本名词

  • 根节点:最上面那个
  • 叶子节点:没有孩子的节点
  • 父节点、子节点、兄弟节点
  • 子树:以某个孩子为根的树
  • 深度 / 高度
    • 深度:从根往下数第几层
    • 高度:从当前节点到最远叶子的层数

3. 重要公式

  • 第 i 层最多:2i−1 个节点
  • 高度 h 的满二叉树最多:2h−1 个节点
  • n 个节点的二叉树高度至少:⌊log2n⌋+1

二、二叉树两种存储结构

1. 链式存储(最通用)

复制代码
struct Node {
    int val;
    Node *l, *r;
    Node(int x) : val(x), l(0), r(0) {}
};

2. 数组存储(完全二叉树专用)

  • 根:1

  • i 的左孩子:2*i

  • i 的右孩子:2*i+1

  • i 的父亲:i/2

    int tree[100005];


三、二叉树四大遍历(必考核心)

1. 前序:根 → 左 → 右

复制代码
void pre(Node *u) {
    if (!u) return;
    cout << u->val;
    pre(u->l);
    pre(u->r);
}

2. 中序:左 → 根 → 右

复制代码
void in(Node *u) {
    if (!u) return;
    in(u->l);
    cout << u->val;
    in(u->r);
}

3. 后序:左 → 右 → 根

复制代码
void post(Node *u) {
    if (!u) return;
    post(u->l);
    post(u->r);
    cout << u->val;
}

4. 层序:按层遍历(BFS)

复制代码
void bfs(Node *root) {
    queue<Node*> q;
    q.push(root);
    while (!q.empty()) {
        Node *u = q.front(); q.pop();
        cout << u->val;
        if (u->l) q.push(u->l);
        if (u->r) q.push(u->r);
    }
}

四、必考结论

  • 前序 + 中序 可确定二叉树
  • 后序 + 中序 可确定二叉树
  • 前序 + 后序 不能唯一确定

五、特殊二叉树(完整体系)

1. 满二叉树

  • 所有非叶子都有 2 个孩子
  • 所有叶子在同一层

2. 完全二叉树

  • 除最后一层,前面全满
  • 最后一层靠左排列
  • 用途:堆、线段树

3. 二叉搜索树 BST

规则:左 < 根 < 右

  • 中序遍历 = 有序序列
  • 查找、插入、删除平均 O (log n)
  • 最坏退化成链 O (n)

4. 平衡二叉树 AVL

  • BST + 左右高度差 ≤ 1
  • 不平衡靠旋转修正
  • 保证稳定 O (log n)

5. 红黑树

  • 弱平衡 BST,节点带颜色
  • 最长路径 ≤ 最短路径 × 2
  • C++ map/set 底层

6. 堆(完全二叉树)

  • 大根堆:父 ≥ 子
  • 小根堆:父 ≤ 子
  • 用途:优先队列、Dijkstra、堆排序

7. 哈夫曼树(最优二叉树)

  • 带权路径长度 WPL 最小
  • 权大靠近根,权小在深处
  • 用途:哈夫曼编码、数据压缩

8. 线索二叉树

  • 把空指针利用:
    • 左空 → 前驱
    • 右空 → 后继
  • 非递归遍历更快

六、基础操作(递归万能)

1. 求树深度

复制代码
int dfs(Node *u) {
    if (!u) return 0;
    return max(dfs(u->l), dfs(u->r)) + 1;
}

2. 求节点总数

复制代码
int cnt(Node *u) {
    if (!u) return 0;
    return cnt(u->l) + cnt(u->r) + 1;
}

3. 求叶子数

复制代码
int leaf(Node *u) {
    if (!u) return 0;
    if (!u->l && !u->r) return 1;
    return leaf(u->l) + leaf(u->r);
}

七、洛谷经典真题(直接能交)

题 1:P1030 已知中序后序求前序

复制代码
#include <iostream>
#include <string>
using namespace std;

string in, post;

void dfs(int l1, int r1, int l2, int r2) {
    if (l1 > r1) return;
    char root = post[r2];
    cout << root;
    int k = l1;
    while (in[k] != root) k++;
    int len = k - l1;
    dfs(l1, k-1, l2, l2+len-1);
    dfs(k+1, r1, l2+len, r2-1);
}

int main() {
    cin >> in >> post;
    dfs(0, in.size()-1, 0, post.size()-1);
    return 0;
}

题 2:P3378 小根堆模板

复制代码
#include <iostream>
using namespace std;

int h[1000005], len;

void up(int i) {
    while (i>1 && h[i]<h[i/2]) {
        swap(h[i], h[i/2]);
        i /= 2;
    }
}

void down(int i) {
    int s;
    while (2*i <= len) {
        s = 2*i;
        if (s+1 <= len && h[s+1]<h[s]) s++;
        if (h[s] < h[i]) swap(h[i], h[s]), i=s;
        else break;
    }
}

void push(int x) { h[++len]=x; up(len); }
void pop() { h[1]=h[len--]; down(1); }

int main() {
    int n, op, x;
    cin >> n;
    while (n--) {
        cin >> op;
        if (op == 1) cin >> x, push(x);
        else if (op == 2) cout << h[1] << '\n';
        else pop();
    }
    return 0;
}

题 3:P1090 合并果子(哈夫曼)

复制代码
#include <iostream>
#include <queue>
using namespace std;

priority_queue<int, vector<int>, greater<int>> q;

int main() {
    int n, x, ans=0;
    cin >> n;
    while (n--) cin >> x, q.push(x);
    while (q.size()>1) {
        int a=q.top(); q.pop();
        int b=q.top(); q.pop();
        ans += a+b;
        q.push(a+b);
    }
    cout << ans;
    return 0;
}

八、完整二叉树知识体系总结

  1. 基础概念 + 存储
  2. 4 种遍历(前中后层)
  3. 递归万能操作(深度、数量、叶子)
  4. 8 种特殊二叉树
  5. 3 道洛谷经典题(可直接 AC)
相关推荐
郝学胜-神的一滴2 小时前
循环队列深度剖析:从算法原理到C++实现全解析
开发语言·数据结构·c++·算法·leetcode
Via_Neo2 小时前
接雨水问题 + 输入优化
java·开发语言·算法
plus4s2 小时前
3月13日(进阶5)
算法
FirstFrost --sy2 小时前
仿mudou库one thread one loop式并发服务器实现
运维·服务器·开发语言·c++
x_xbx2 小时前
LeetCode:27. 移除元素
数据结构·算法·leetcode
云泽8082 小时前
C++ map 底层探秘:从结构设计到 operator [] 实现的全解析
数据结构·c++·算法
闻哥2 小时前
深入剖析Redis数据类型与底层数据结构
java·jvm·数据结构·spring boot·redis·面试·wpf
小O的算法实验室2 小时前
2026年EAAI SCI1区TOP,基于LLM驱动的多群粒子群算法动态通信策略生成方法,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进
午彦琳2 小时前
leetcode hot 100_49,128
算法·leetcode·职场和发展