存储方式
二叉树的存储方式有多种,常见的有以下两种主要方式:
1. 顺序存储(数组存储)
适合于存储完全二叉树和满二叉树,因为这些树的节点位置有规律,可以用数组按层次存储节点数据。
特点:
树的节点按层次编号,根节点位于数组的第 1 个位置(数组下标为 0 或 1),然后是左子树和右子树的节点依次填充。
下标关系:
父节点的下标为 (i),则:
左子节点的下标为 (2i + 1) (0-based),或 (2i)(1-based)。
右子节点的下标为 (2i + 2) (0-based),或 (2i + 1)(1-based)。
子节点的下标为 (i),则父节点的下标为 (\frac{i-1}{2}) (0-based)或 (\frac{i}{2})(1-based)。
优点:
简单,适合完全二叉树或满二叉树,便于计算节点的关系。
缺点:
如果是一般二叉树,可能会有大量的空位置浪费空间,特别是对于稀疏的二叉树。
示例: 对于如下二叉树:
1
/ \
2 3
/ \
4 5
它的数组表示为 [1, 2, 3, 4, 5]
。
2. 链式存储(链表存储)
这是最常见的一种二叉树存储方式,特别是对于普通二叉树或不规则树,使用链表来存储更为高效。
特点:
每个节点包含三部分:
数据域(存储节点的值)。
左指针域(指向左子节点)。
右指针域(指向右子节点)。
如果没有左或右子节点,则对应的指针为
null
(空指针)。
节点结构(C语言或类似语言表示):
struct TreeNode {
int value; // 节点值
TreeNode* left; // 左子节点指针
TreeNode* right; // 右子节点指针
};
优点:
适合一般二叉树,能够灵活处理各种树形结构。
不浪费内存,因为只为实际存在的节点分配空间。
缺点:
对于完全二叉树或满二叉树,链式存储可能占用更多的空间(每个节点额外存储两个指针)。
示例: 对于如下二叉树:
1
/ \
2 3
/ \
4 5
使用链式存储的结构如下:
TreeNode {
value = 1,
left = TreeNode { value = 2, left = TreeNode { value = 4 }, right = TreeNode { value = 5 } },
right = TreeNode { value = 3 }
}
比较:
存储方式
适用场景
优点
缺点
顺序存储
完全二叉树、满二叉树
节点关系可以通过下标直接计算,简单
空间浪费,适合规则树
链式存储
普通二叉树(不规则结构的树)
灵活,节省空间,不存在空节点浪费
需要指针,空间开销更大,复杂度增加
3. 特殊存储方式
在一些特殊应用场景中,也有针对特定需求的存储方法。例如:
父子表示法:每个节点除了存储子节点的指针,还存储父节点的指针,用于快速找到父节点。
三叉链表:用于三叉树或有特殊指向需求的树。
具体的存储方式取决于实际应用场景和二叉树的类型。
Last updated