mirror of
https://github.com/krahets/hello-algo.git
synced 2026-07-10 14:36:06 +00:00
First version.
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
# Представление двоичного дерева с помощью массивом
|
||||
|
||||
При представлении в виде списка единицей хранения двоичного дерева является узел `TreeNode`, а узлы соединяются между собой указателями. В предыдущем разделе были рассмотрены основные операции с двоичным деревом, представленным в виде списка.
|
||||
|
||||
Можно ли представить двоичное дерево с помощью массива? Ответ положительный.
|
||||
|
||||
## Представление идеального двоичного дерева
|
||||
|
||||
Сначала рассмотрим простой пример. Если дано идеальное двоичное дерево и все его узлы хранятся в массиве в порядке обхода по уровням, то каждому узлу соответствует уникальный индекс массива.
|
||||
|
||||
На основе свойств обхода по уровням можно вывести формулу отображения между индексом родительского узла и индексами дочерних узлов: **если индекс узла равен $i$, то индекс его левого дочернего узла равен $2i + 1$, а индекс правого дочернего узла равен $2i + 2$**. На рисунке ниже показаны отношения отображения между индексами различных узлов.
|
||||
|
||||
<!-- 🔴 俄文版缺失图片 -->
|
||||
<!-- 中文原文: -->
|
||||
|
||||
**Роль формулы отображения эквивалентна ссылкам на узлы (указателям) в списке**. Для любого узла в массиве мы можем получить доступ к его левому (правому) дочернему узлу с помощью формулы отображения.
|
||||
|
||||
## Представление произвольного двоичного дерева
|
||||
|
||||
<!-- 🔴 俄文版缺失此段落 -->
|
||||
<!-- 中文原文:完美二叉树是一个特例,在二叉树的中间层通常存在许多 `None` 。由于层序遍历序列并不包含这些 `None` ,因此我们无法仅凭该序列来推测 `None` 的数量和分布位置。**这意味着存在多种二叉树结构都符合该层序遍历序列**。 -->
|
||||
|
||||
<!-- 🔴 俄文版缺失此段落 -->
|
||||
<!-- 中文原文:如下图所示,给定一棵非完美二叉树,上述数组表示方法已经失效。 -->
|
||||
|
||||
<!-- 🔴 俄文版缺失图片 -->
|
||||
<!-- 中文原文: -->
|
||||
|
||||
<!-- 🔴 俄文版缺失此段落 -->
|
||||
<!-- 中文原文:为了解决此问题,**我们可以考虑在层序遍历序列中显式地写出所有 `None`** 。如下图所示,这样处理后,层序遍历序列就可以唯一表示二叉树了。示例代码如下: -->
|
||||
|
||||
<!-- 🔴 俄文版缺失代码示例 -->
|
||||
<!-- 中文原文:=== "Python" ... [多语言代码示例] -->
|
||||
|
||||
<!-- 🔴 俄文版缺失图片 -->
|
||||
<!-- 中文原文: -->
|
||||
|
||||
<!-- 🔴 俄文版缺失此段落 -->
|
||||
<!-- 中文原文:值得说明的是,**完全二叉树非常适合使用数组来表示**。回顾完全二叉树的定义,`None` 只出现在最底层且靠右的位置,**因此所有 `None` 一定出现在层序遍历序列的末尾**。 -->
|
||||
|
||||
<!-- 🔴 俄文版缺失此段落 -->
|
||||
<!-- 中文原文:这意味着使用数组表示完全二叉树时,可以省略存储所有 `None` ,非常方便。下图给出了一个例子。 -->
|
||||
|
||||
<!-- 🔴 俄文版缺失图片 -->
|
||||
<!-- 中文原文: -->
|
||||
|
||||
<!-- 🔴 俄文版缺失此段落 -->
|
||||
<!-- 中文原文:以下代码实现了一棵基于数组表示的二叉树,包括以下几种操作。 -->
|
||||
|
||||
<!-- 🔴 俄文版缺失列表 -->
|
||||
<!-- 中文原文:- 给定某节点,获取它的值、左(右)子节点、父节点。- 获取前序遍历、中序遍历、后序遍历、层序遍历序列。 -->
|
||||
|
||||
<!-- 🔴 俄文版缺失代码引用 -->
|
||||
<!-- 中文原文:```src [file]{array_binary_tree}-[class]{array_binary_tree}-[func]{} ``` -->
|
||||
|
||||
## Преимущества и ограничения
|
||||
|
||||
<!-- 🔴 俄文版缺失此段落 -->
|
||||
<!-- 中文原文:二叉树的数组表示主要有以下优点。 -->
|
||||
|
||||
<!-- 🔴 俄文版缺失列表 -->
|
||||
<!-- 中文原文:- 数组存储在连续的内存空间中,对缓存友好,访问与遍历速度较快。- 不需要存储指针,比较节省空间。- 允许随机访问节点。 -->
|
||||
|
||||
<!-- 🔴 俄文版缺失此段落 -->
|
||||
<!-- 中文原文:然而,数组表示也存在一些局限性。 -->
|
||||
|
||||
<!-- 🔴 俄文版缺失列表 -->
|
||||
<!-- 中文原文:- 数组存储需要连续内存空间,因此不适合存储数据量过大的树。- 增删节点需要通过数组插入与删除操作实现,效率较低。- 当二叉树中存在大量 `None` 时,数组中包含的节点数据比重较低,空间利用率较低。 -->
|
||||
Reference in New Issue
Block a user