mirror of
https://github.com/krahets/hello-algo.git
synced 2024-12-25 12:16:29 +08:00
1. Add array representation of binary tree.
2. Update the LEGO example. 3. Update headers of the Python files.
This commit is contained in:
parent
9015222a0b
commit
919236f479
36 changed files with 151 additions and 61 deletions
|
@ -1,8 +1,8 @@
|
|||
'''
|
||||
"""
|
||||
File: array.py
|
||||
Created Time: 2022-11-25
|
||||
Author: Krahets (krahets@163.com)
|
||||
'''
|
||||
"""
|
||||
|
||||
import sys, os.path as osp
|
||||
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
'''
|
||||
"""
|
||||
File: linked_list.py
|
||||
Created Time: 2022-11-25
|
||||
Author: Krahets (krahets@163.com)
|
||||
'''
|
||||
"""
|
||||
|
||||
import sys, os.path as osp
|
||||
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
'''
|
||||
"""
|
||||
File: list.py
|
||||
Created Time: 2022-11-25
|
||||
Author: Krahets (krahets@163.com)
|
||||
'''
|
||||
"""
|
||||
|
||||
import sys, os.path as osp
|
||||
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
'''
|
||||
"""
|
||||
File: my_list.py
|
||||
Created Time: 2022-11-25
|
||||
Author: Krahets (krahets@163.com)
|
||||
'''
|
||||
"""
|
||||
|
||||
import sys, os.path as osp
|
||||
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
'''
|
||||
"""
|
||||
File: leetcode_two_sum.py
|
||||
Created Time: 2022-11-25
|
||||
Author: Krahets (krahets@163.com)
|
||||
'''
|
||||
"""
|
||||
|
||||
import sys, os.path as osp
|
||||
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
'''
|
||||
"""
|
||||
File: space_complexity.py
|
||||
Created Time: 2022-11-25
|
||||
Author: Krahets (krahets@163.com)
|
||||
'''
|
||||
"""
|
||||
|
||||
import sys, os.path as osp
|
||||
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
'''
|
||||
"""
|
||||
File: time_complexity.py
|
||||
Created Time: 2022-11-25
|
||||
Author: Krahets (krahets@163.com)
|
||||
'''
|
||||
"""
|
||||
|
||||
import sys, os.path as osp
|
||||
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
'''
|
||||
"""
|
||||
File: worst_best_time_complexity.py
|
||||
Created Time: 2022-11-25
|
||||
Author: Krahets (krahets@163.com)
|
||||
'''
|
||||
"""
|
||||
|
||||
import sys, os.path as osp
|
||||
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
'''
|
||||
"""
|
||||
File: binary_search.py
|
||||
Created Time: 2022-11-26
|
||||
Author: timi (xisunyy@163.com)
|
||||
'''
|
||||
"""
|
||||
|
||||
import sys, os.path as osp
|
||||
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
'''
|
||||
"""
|
||||
File: hashing_search.py
|
||||
Created Time: 2022-11-26
|
||||
Author: timi (xisunyy@163.com)
|
||||
'''
|
||||
"""
|
||||
|
||||
import sys, os.path as osp
|
||||
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
'''
|
||||
"""
|
||||
File: linear_search.py
|
||||
Created Time: 2022-11-26
|
||||
Author: timi (xisunyy@163.com)
|
||||
'''
|
||||
"""
|
||||
|
||||
import sys, os.path as osp
|
||||
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
'''
|
||||
"""
|
||||
File: bubble_sort.py
|
||||
Created Time: 2022-11-25
|
||||
Author: timi (xisunyy@163.com)
|
||||
'''
|
||||
"""
|
||||
|
||||
import sys, os.path as osp
|
||||
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
'''
|
||||
"""
|
||||
File: insertion_sort.py
|
||||
Created Time: 2022-11-25
|
||||
Author: timi (xisunyy@163.com)
|
||||
'''
|
||||
"""
|
||||
|
||||
import sys, os.path as osp
|
||||
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
'''
|
||||
"""
|
||||
File: merge_sort.py
|
||||
Created Time: 2022-11-25
|
||||
Author: timi (xisunyy@163.com)
|
||||
'''
|
||||
"""
|
||||
|
||||
import sys, os.path as osp
|
||||
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
'''
|
||||
"""
|
||||
File: quick_sort.py
|
||||
Created Time: 2022-11-25
|
||||
Author: timi (xisunyy@163.com)
|
||||
'''
|
||||
"""
|
||||
|
||||
import sys, os.path as osp
|
||||
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
'''
|
||||
"""
|
||||
File: array_queue.py
|
||||
Created Time: 2022-12-01
|
||||
Author: Peng Chen (pengchzn@gmail.com)
|
||||
'''
|
||||
"""
|
||||
|
||||
import os.path as osp
|
||||
import sys
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
'''
|
||||
"""
|
||||
File: array_stack.py
|
||||
Created Time: 2022-11-29
|
||||
Author: Peng Chen (pengchzn@gmail.com)
|
||||
'''
|
||||
"""
|
||||
|
||||
import sys, os.path as osp
|
||||
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
'''
|
||||
"""
|
||||
File: deque.py
|
||||
Created Time: 2022-11-29
|
||||
Author: Peng Chen (pengchzn@gmail.com)
|
||||
'''
|
||||
"""
|
||||
|
||||
import os.path as osp
|
||||
import sys
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
'''
|
||||
"""
|
||||
File: linkedlist_queue.py
|
||||
Created Time: 2022-12-01
|
||||
Author: Peng Chen (pengchzn@gmail.com)
|
||||
'''
|
||||
"""
|
||||
|
||||
import os.path as osp
|
||||
import sys
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
'''
|
||||
"""
|
||||
File: linkedlist_stack.py
|
||||
Created Time: 2022-11-29
|
||||
Author: Peng Chen (pengchzn@gmail.com)
|
||||
'''
|
||||
"""
|
||||
|
||||
import sys, os.path as osp
|
||||
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
'''
|
||||
"""
|
||||
File: queue.py
|
||||
Created Time: 2022-11-29
|
||||
Author: Peng Chen (pengchzn@gmail.com)
|
||||
'''
|
||||
"""
|
||||
|
||||
import os.path as osp
|
||||
import sys
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
'''
|
||||
"""
|
||||
File: stack.py
|
||||
Created Time: 2022-11-29
|
||||
Author: Peng Chen (pengchzn@gmail.com)
|
||||
'''
|
||||
"""
|
||||
|
||||
import sys, os.path as osp
|
||||
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
'''
|
||||
"""
|
||||
File: binary_search_tree.py
|
||||
Created Time: 2022-11-25
|
||||
Author: Krahets (krahets@163.com)
|
||||
'''
|
||||
"""
|
||||
|
||||
import sys, os.path as osp
|
||||
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
'''
|
||||
"""
|
||||
File: binary_tree.py
|
||||
Created Time: 2022-11-25
|
||||
Author: Krahets (krahets@163.com)
|
||||
'''
|
||||
"""
|
||||
|
||||
import sys, os.path as osp
|
||||
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
'''
|
||||
"""
|
||||
File: binary_tree_bfs.py
|
||||
Created Time: 2022-11-25
|
||||
Author: Krahets (krahets@163.com)
|
||||
'''
|
||||
"""
|
||||
|
||||
import sys, os.path as osp
|
||||
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
'''
|
||||
"""
|
||||
File: binary_tree_dfs.py
|
||||
Created Time: 2022-11-25
|
||||
Author: Krahets (krahets@163.com)
|
||||
'''
|
||||
"""
|
||||
|
||||
import sys, os.path as osp
|
||||
sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
'''
|
||||
"""
|
||||
File: binary_tree.py
|
||||
Created Time: 2021-12-11
|
||||
Author: Krahets (krahets@163.com)
|
||||
'''
|
||||
"""
|
||||
|
||||
import collections
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
'''
|
||||
"""
|
||||
File: linked_list.py
|
||||
Created Time: 2021-12-11
|
||||
Author: Krahets (krahets@163.com)
|
||||
'''
|
||||
"""
|
||||
|
||||
class ListNode:
|
||||
"""Definition for a singly-linked list node
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
'''
|
||||
"""
|
||||
File: print_util.py
|
||||
Created Time: 2021-12-11
|
||||
Author: Krahets (krahets@163.com), msk397 (machangxinq@gmail.com)
|
||||
'''
|
||||
"""
|
||||
|
||||
import copy
|
||||
import queue
|
||||
|
|
|
@ -31,12 +31,23 @@ comments: true
|
|||
- 算法是发挥数据结构优势的舞台。数据结构仅存储数据信息,结合算法才可解决特定问题。
|
||||
- 算法有对应最优的数据结构。给定算法,一般可基于不同的数据结构实现,而最终执行效率往往相差很大。
|
||||
|
||||
如果将数据结构与算法比作「LEGO 乐高」,数据结构就是乐高「积木」,而算法就是把积木拼成目标形态的一系列「操作步骤」。
|
||||
|
||||
![relationship_between_data_structure_and_algorithm](what_is_dsa.assets/relationship_between_data_structure_and_algorithm.png)
|
||||
|
||||
<p align="center"> Fig. 数据结构与算法的关系 </p>
|
||||
|
||||
如果将「LEGO 乐高」类比到「数据结构与算法」,那么可以得到下表所示的对应关系。
|
||||
|
||||
<div class="center-table" markdown>
|
||||
|
||||
| 数据结构与算法 | LEGO 乐高 |
|
||||
| -------------- | ---------------------------------------- |
|
||||
| 输入数据 | 未拼装的积木 |
|
||||
| 数据结构 | 积木组织形式,包括形状、大小、连接方式等 |
|
||||
| 算法 | 把积木拼成目标形态的一系列操作步骤 |
|
||||
| 输出数据 | 积木模型 |
|
||||
|
||||
</div>
|
||||
|
||||
!!! tip "约定俗成的简称"
|
||||
|
||||
在实际讨论中,我们通常会将「数据结构与算法」直接简称为「算法」。例如,我们熟称的 LeetCode 算法题目,实际上同时考察了数据结构和算法两部分知识。
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 72 KiB |
Binary file not shown.
After Width: | Height: | Size: 94 KiB |
Binary file not shown.
After Width: | Height: | Size: 77 KiB |
Binary file not shown.
After Width: | Height: | Size: 68 KiB |
|
@ -377,3 +377,82 @@ comments: true
|
|||
| 树的结点总数为 $n$ 时的高度 | $\log_2 (n+1) - 1$ | $n - 1$ |
|
||||
|
||||
</div>
|
||||
|
||||
## 二叉树表示方式 *
|
||||
|
||||
我们一般使用二叉树的「链表表示」,即存储单位为结点 `TreeNode` ,结点之间通过指针(引用)相连接。本文前述示例代码展示了二叉树在链表表示下的各项基本操作。
|
||||
|
||||
那能否可以用「数组表示」二叉树呢?答案是肯定的。先来分析一个简单案例,给定一个「完美二叉树」,将结点按照层序遍历的顺序编号(从 0 开始),那么可以推导得出父结点索引与子结点索引之间的「映射公式」:**设结点的索引为 $i$ ,则该结点的左子结点索引为 $2i + 1$ 、右子结点索引为 $2i + 2$** 。
|
||||
|
||||
**本质上,映射公式的作用就是链表中的指针**。对于层序遍历序列中的任意结点,我们都可以使用映射公式来访问子结点。因此,可以直接使用层序遍历序列(即数组)来表示完美二叉树。
|
||||
|
||||
![array_representation_mapping](binary_tree.assets/array_representation_mapping.png)
|
||||
|
||||
然而,完美二叉树只是个例,二叉树中间层往往存在许多空结点(即 `null` ),而层序遍历序列并不包含这些空结点,并且我们无法单凭序列来猜测空结点的数量和分布位置,**即理论上存在许多种二叉树都符合该层序遍历序列**。显然,这种情况无法使用数组来存储二叉树。
|
||||
|
||||
![array_representation_without_empty](binary_tree.assets/array_representation_without_empty.png)
|
||||
|
||||
为了解决此问题,考虑按照完美二叉树的形式来表示所有二叉树,**即在序列中使用特殊符号来显式地表示“空位”**。如下图所示,这样处理后,序列(数组)就可以唯一表示二叉树了。
|
||||
|
||||
=== "Java"
|
||||
|
||||
```java title=""
|
||||
/* 二叉树的数组表示 */
|
||||
// 使用 int 的包装类 Integer ,就可以使用 null 来标记空位
|
||||
Integer[] tree = { 1, 2, 3, 4, null, 6, 7, 8, 9, null, null, 12, null, null, 15 };
|
||||
```
|
||||
|
||||
=== "C++"
|
||||
|
||||
```cpp title=""
|
||||
/* 二叉树的数组表示 */
|
||||
// 为了符合数据类型为 int ,使用 int 最大值标记空位
|
||||
// 该方法的使用前提是没有结点的值 = INT_MAX
|
||||
vector<int> tree = { 1, 2, 3, 4, INT_MAX, 6, 7, 8, 9, INT_MAX, INT_MAX, 12, INT_MAX, INT_MAX, 15 };
|
||||
```
|
||||
|
||||
=== "Python"
|
||||
|
||||
```python title=""
|
||||
“”“ 二叉树的数组表示 ”“”
|
||||
# 直接使用 None 来表示空位
|
||||
tree = [1, 2, 3, 4, None, 6, 7, 8, 9, None, None, 12, None, None, 15]
|
||||
```
|
||||
|
||||
=== "Go"
|
||||
|
||||
```go title=""
|
||||
|
||||
```
|
||||
|
||||
=== "JavaScript"
|
||||
|
||||
```js title=""
|
||||
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title=""
|
||||
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
||||
```c title=""
|
||||
|
||||
```
|
||||
|
||||
=== "C#"
|
||||
|
||||
```csharp title=""
|
||||
|
||||
```
|
||||
|
||||
![array_representation_with_empty](binary_tree.assets/array_representation_with_empty.png)
|
||||
|
||||
回顾「完全二叉树」的满足条件,其只有最底层有空结点,并且最底层的结点尽量靠左,因而所有空结点都一定出现在层序遍历序列的末尾。**因为我们先验地确定了空位的位置,所以在使用数组表示完全二叉树时,可以省略存储“空位”**。“便于使用数组表示”也是完全二叉树受欢迎的原因之一。
|
||||
|
||||
![array_representation_complete_binary_tree](binary_tree.assets/array_representation_complete_binary_tree.png)
|
||||
|
||||
数组表示有两个优点: 一是不需要存储指针,节省空间;二是可以随机访问结点。然而,当二叉树中的“空位”很多时,数组中只包含很少结点的数据,空间利用率很低。
|
||||
|
|
Loading…
Reference in a new issue