feat: Revised the book (#978)

* Sync recent changes to the revised Word.

* Revised the preface chapter

* Revised the introduction chapter

* Revised the computation complexity chapter

* Revised the chapter data structure

* Revised the chapter array and linked list

* Revised the chapter stack and queue

* Revised the chapter hashing

* Revised the chapter tree

* Revised the chapter heap

* Revised the chapter graph

* Revised the chapter searching

* Reivised the sorting chapter

* Revised the divide and conquer chapter

* Revised the chapter backtacking

* Revised the DP chapter

* Revised the greedy chapter

* Revised the appendix chapter

* Revised the preface chapter doubly

* Revised the figures
This commit is contained in:
Yudong Jin
2023-12-02 06:21:34 +08:00
committed by GitHub
parent b824d149cb
commit e720aa2d24
404 changed files with 1537 additions and 1558 deletions

View File

@@ -1,6 +1,6 @@
# 二叉树
「二叉树 binary tree」是一种非线性数据结构代表祖先后代之间的派生关系,体现“一分为二”的分治逻辑。与链表类似,二叉树的基本单元是节点,每个节点包含值、左子节点引用右子节点引用。
「二叉树 binary tree」是一种非线性数据结构代表祖先”与“后代之间的派生关系,体现“一分为二”的分治逻辑。与链表类似,二叉树的基本单元是节点,每个节点包含值、左子节点引用右子节点引用。
=== "Python"
@@ -205,7 +205,7 @@
!!! tip
请注意,我们通常将“高度”和“深度”定义为“走过边的数量”,但有些题目或教材可能会将其定义为“走过节点的数量”。在这种情况下,高度和深度都需要加 1 。
请注意,我们通常将“高度”和“深度”定义为“经过的边的数量”,但有些题目或教材可能会将其定义为“经过的节点的数量”。在这种情况下,高度和深度都需要加 1 。
## 二叉树基本操作
@@ -223,7 +223,7 @@
n3 = TreeNode(val=3)
n4 = TreeNode(val=4)
n5 = TreeNode(val=5)
# 构建引用指向(即指针)
# 构建节点之间的引用(指针)
n1.left = n2
n1.right = n3
n2.left = n4
@@ -240,7 +240,7 @@
TreeNode* n3 = new TreeNode(3);
TreeNode* n4 = new TreeNode(4);
TreeNode* n5 = new TreeNode(5);
// 构建引用指向(即指针)
// 构建节点之间的引用(指针)
n1->left = n2;
n1->right = n3;
n2->left = n4;
@@ -256,7 +256,7 @@
TreeNode n3 = new TreeNode(3);
TreeNode n4 = new TreeNode(4);
TreeNode n5 = new TreeNode(5);
// 构建引用指向(即指针)
// 构建节点之间的引用(指针)
n1.left = n2;
n1.right = n3;
n2.left = n4;
@@ -273,7 +273,7 @@
TreeNode n3 = new(3);
TreeNode n4 = new(4);
TreeNode n5 = new(5);
// 构建引用指向(即指针)
// 构建节点之间的引用(指针)
n1.left = n2;
n1.right = n3;
n2.left = n4;
@@ -290,7 +290,7 @@
n3 := NewTreeNode(3)
n4 := NewTreeNode(4)
n5 := NewTreeNode(5)
// 构建引用指向(即指针)
// 构建节点之间的引用(指针)
n1.Left = n2
n1.Right = n3
n2.Left = n4
@@ -306,7 +306,7 @@
let n3 = TreeNode(x: 3)
let n4 = TreeNode(x: 4)
let n5 = TreeNode(x: 5)
// 构建引用指向(即指针)
// 构建节点之间的引用(指针)
n1.left = n2
n1.right = n3
n2.left = n4
@@ -323,7 +323,7 @@
n3 = new TreeNode(3),
n4 = new TreeNode(4),
n5 = new TreeNode(5);
// 构建引用指向(即指针)
// 构建节点之间的引用(指针)
n1.left = n2;
n1.right = n3;
n2.left = n4;
@@ -340,7 +340,7 @@
n3 = new TreeNode(3),
n4 = new TreeNode(4),
n5 = new TreeNode(5);
// 构建引用指向(即指针)
// 构建节点之间的引用(指针)
n1.left = n2;
n1.right = n3;
n2.left = n4;
@@ -357,7 +357,7 @@
TreeNode n3 = new TreeNode(3);
TreeNode n4 = new TreeNode(4);
TreeNode n5 = new TreeNode(5);
// 构建引用指向(即指针)
// 构建节点之间的引用(指针)
n1.left = n2;
n1.right = n3;
n2.left = n4;
@@ -373,7 +373,7 @@
let n3 = TreeNode::new(3);
let n4 = TreeNode::new(4);
let n5 = TreeNode::new(5);
// 构建引用指向(即指针)
// 构建节点之间的引用(指针)
n1.borrow_mut().left = Some(n2.clone());
n1.borrow_mut().right = Some(n3);
n2.borrow_mut().left = Some(n4);
@@ -390,7 +390,7 @@
TreeNode *n3 = newTreeNode(3);
TreeNode *n4 = newTreeNode(4);
TreeNode *n5 = newTreeNode(5);
// 构建引用指向(即指针)
// 构建节点之间的引用(指针)
n1->left = n2;
n1->right = n3;
n2->left = n4;
@@ -546,13 +546,13 @@
!!! note
需要注意的是,插入节点可能会改变二叉树的原有逻辑结构,而删除节点通常意味着删除该节点及其所有子树。因此,在二叉树中,插入与删除操作通常是由一套操作配合完成的,以实现有实际意义的操作。
需要注意的是,插入节点可能会改变二叉树的原有逻辑结构,而删除节点通常意味着删除该节点及其所有子树。因此,在二叉树中,插入与删除通常是由一套操作配合完成的,以实现有实际意义的操作。
## 常见二叉树类型
### 完美二叉树
「完美二叉树 perfect binary tree」所有层的节点都被完全填满。在完美二叉树中叶节点的度为 $0$ ,其余所有节点的度都为 $2$ ;若树高度为 $h$ ,则节点总数为 $2^{h+1} - 1$ ,呈现标准的指数级关系,反映了自然界中常见的细胞分裂现象。
如下图所示,「完美二叉树 perfect binary tree」所有层的节点都被完全填满。在完美二叉树中叶节点的度为 $0$ ,其余所有节点的度都为 $2$ ;若树高度为 $h$ ,则节点总数为 $2^{h+1} - 1$ ,呈现标准的指数级关系,反映了自然界中常见的细胞分裂现象。
!!! tip
@@ -580,20 +580,20 @@
## 二叉树的退化
下图展示了二叉树的理想与退化状态。当二叉树的每层节点都被填满时,达到“完美二叉树”;而当所有节点都偏向一侧时,二叉树退化为“链表”。
下图展示了二叉树的理想结构与退化结构。当二叉树的每层节点都被填满时,达到“完美二叉树”;而当所有节点都偏向一侧时,二叉树退化为“链表”。
- 完美二叉树是理想情况,可以充分发挥二叉树“分治”的优势。
- 链表则是另一个极端,各项操作都变为线性操作,时间复杂度退化至 $O(n)$ 。
![二叉树的最佳与最差结构](binary_tree.assets/binary_tree_best_worst_cases.png)
![二叉树的最佳结构与最差结构](binary_tree.assets/binary_tree_best_worst_cases.png)
如下表所示,在最佳和最差结构下,二叉树的叶节点数量、节点总数、高度等达到极大或极小值。
如下表所示,在最佳结构和最差结构下,二叉树的叶节点数量、节点总数、高度等达到极大或极小值。
<p align="center"> 表 <id> &nbsp; 二叉树的最佳与最差情况 </p>
<p align="center"> 表 <id> &nbsp; 二叉树的最佳结构与最差结构 </p>
| | 完美二叉树 | 链表 |
| ----------------------- | ------------------ | ------- |
| 第 $i$ 层的节点数量 | $2^{i-1}$ | $1$ |
| 高度 $h$ 树的叶节点数量 | $2^h$ | $1$ |
| 高度 $h$ 树的节点总数 | $2^{h+1} - 1$ | $h + 1$ |
| 节点总数 $n$ 树的高度 | $\log_2 (n+1) - 1$ | $n - 1$ |
| | 完美二叉树 | 链表 |
| --------------------------- | ------------------ | ------- |
| 第 $i$ 层的节点数量 | $2^{i-1}$ | $1$ |
| 高度 $h$ 树的叶节点数量 | $2^h$ | $1$ |
| 高度 $h$ 树的节点总数 | $2^{h+1} - 1$ | $h + 1$ |
| 节点总数 $n$ 树的高度 | $\log_2 (n+1) - 1$ | $n - 1$ |