1. 二叉树与N叉树的结构本质差异
在数据结构的世界里,树形结构就像是一个庞大的家族谱系。二叉树相当于每个家庭最多只能有两个孩子(左孩子和右孩子),而N叉树则像是一个多子多孙的大家庭,每个节点可以拥有任意数量的孩子。这种根本性的差异导致了它们在实现和应用上的诸多不同。
1.1 节点结构定义解析
二叉树节点的结构设计体现了极简主义思想。每个节点只需要维护三个基本属性:
- 存储数据的
val字段 - 指向左子节点的
left指针 - 指向右子节点的
right指针
这种设计在C++中通常用结构体表示,构造函数提供了三种初始化方式:
- 空节点构造(val=0,左右指针为空)
- 仅带值的构造
- 完整节点构造(包含值和左右子节点)
cpp复制struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode* left, TreeNode* right)
: val(x), left(left), right(right) {}
};
N叉树节点的设计则展现了更大的灵活性。关键区别在于:
- 使用
vector<Node*>容器存储子节点指针 - 子节点数量不受限制
- 通过索引而非固定名称访问子节点
cpp复制class Node {
public:
int val;
vector<Node*> children;
Node() : val(0) {}
Node(int _val) : val(_val) {}
Node(int _val, vector<Node*> _children)
: val(_val), children(_children) {}
};
注意:N叉树的实现中,使用vector而非原生数组是为了方便动态管理子节点。在性能敏感场景下,可以考虑预分配内存或使用其他容器。
1.2 内存布局与访问特性对比
从内存角度看,二叉树节点具有固定大小(通常16-24字节,取决于系统和对齐方式),而N叉树节点的大小会随着子节点数量变化。这种差异带来了不同的性能特征:
| 特性 | 二叉树 | N叉树 |
|---|---|---|
| 内存分配 | 每次固定大小 | 动态变化,含vector开销 |
| 子节点访问 | 直接通过left/right成员访问 | 需要通过children数组索引访问 |
| 缓存友好性 | 更好(连续分配时) | 较差(子节点可能分散) |
| 插入/删除复杂度 | O(1) | O(1)平均,可能触发vector扩容 |
实际工程中选择哪种结构,需要根据具体场景权衡。二叉树适合子节点数量固定且少的场景,而N叉树更适合需要灵活子节
