Add the figure of assembling blocks.

Update some texts.
This commit is contained in:
krahets 2023-05-31 01:04:40 +08:00
parent 8247a611d7
commit e35e2e31eb
5 changed files with 7 additions and 5 deletions

View file

@ -7,8 +7,7 @@ Author: Krahets (krahets@163.com)
def binary_search_left_edge(nums: list[int], target: int) -> int: def binary_search_left_edge(nums: list[int], target: int) -> int:
"""二分查找最左一个元素""" """二分查找最左一个元素"""
# 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素 i, j = 0, len(nums) - 1 # 初始化双闭区间 [0, n-1]
i, j = 0, len(nums) - 1
while i <= j: while i <= j:
m = (i + j) // 2 # 计算中点索引 m m = (i + j) // 2 # 计算中点索引 m
if nums[m] < target: if nums[m] < target:
@ -24,8 +23,7 @@ def binary_search_left_edge(nums: list[int], target: int) -> int:
def binary_search_right_edge(nums: list[int], target: int) -> int: def binary_search_right_edge(nums: list[int], target: int) -> int:
"""二分查找最右一个元素""" """二分查找最右一个元素"""
# 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素 i, j = 0, len(nums) - 1 # 初始化双闭区间 [0, n-1]
i, j = 0, len(nums) - 1
while i <= j: while i <= j:
m = (i + j) // 2 # 计算中点索引 m m = (i + j) // 2 # 计算中点索引 m
if nums[m] < target: if nums[m] < target:

View file

@ -58,6 +58,8 @@
不修改 `P.next` 也可以。从该链表的角度看,从头结点遍历到尾结点已经遇不到 `P` 了。这意味着结点 `P` 已经从链表中删除了,此时结点 `P` 指向哪里都不会对这条链表产生影响了。 不修改 `P.next` 也可以。从该链表的角度看,从头结点遍历到尾结点已经遇不到 `P` 了。这意味着结点 `P` 已经从链表中删除了,此时结点 `P` 指向哪里都不会对这条链表产生影响了。
从垃圾回收的角度看,对于 Java, Python, Go 等拥有自动垃圾回收的语言来说,节点 `P` 是否被回收取决于是否有仍存在指向它的引用,而不是 `P.next` 的值。在 C, C++ 等语言中,我们需要手动释放节点内存。
!!! question "在链表中插入和删除操作的时间复杂度是 $O(1)$ 。但是增删之前都需要 $O(n)$ 查找元素,那为什么时间复杂度不是 $O(n)$ 呢?" !!! question "在链表中插入和删除操作的时间复杂度是 $O(1)$ 。但是增删之前都需要 $O(n)$ 查找元素,那为什么时间复杂度不是 $O(n)$ 呢?"
如果是先查找元素、再删除元素,确实是 $O(n)$ 。然而,链表的 $O(1)$ 增删的优势可以在其他应用上得到体现。例如,双向队列适合使用链表实现,我们维护一个指针变量始终指向头结点、尾结点,每次插入与删除操作都是 $O(1)$ 。 如果是先查找元素、再删除元素,确实是 $O(n)$ 。然而,链表的 $O(1)$ 增删的优势可以在其他应用上得到体现。例如,双向队列适合使用链表实现,我们维护一个指针变量始终指向头结点、尾结点,每次插入与删除操作都是 $O(1)$ 。

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

View file

@ -8,6 +8,8 @@
从数据结构与算法的角度来看,积木的各种形状和连接方式代表数据结构,而组装说明书上的一系列步骤则是算法。 从数据结构与算法的角度来看,积木的各种形状和连接方式代表数据结构,而组装说明书上的一系列步骤则是算法。
![拼装积木](algorithms_are_everywhere.assets/assembling_blocks.jpg)
**例二:查阅字典**。在字典里,每个汉字都对应一个拼音,而字典是按照拼音的英文字母顺序排列的。假设我们需要查找一个拼音首字母为 $r$ 的字,通常会这样操作: **例二:查阅字典**。在字典里,每个汉字都对应一个拼音,而字典是按照拼音的英文字母顺序排列的。假设我们需要查找一个拼音首字母为 $r$ 的字,通常会这样操作:
1. 翻开字典约一半的页数,查看该页首字母是什么(假设为 $m$ 1. 翻开字典约一半的页数,查看该页首字母是什么(假设为 $m$

View file

@ -2,7 +2,7 @@
!!! tip !!! tip
阅读本节前,请确保已完成堆章节的学习 阅读本节前,请确保已学完「堆」章节
「堆排序 Heap Sort」是一种基于堆数据结构实现的高效排序算法。我们可以利用已经学过的“建堆操作”和“元素出堆操作”实现堆排序 「堆排序 Heap Sort」是一种基于堆数据结构实现的高效排序算法。我们可以利用已经学过的“建堆操作”和“元素出堆操作”实现堆排序