Update the book based on the revised second edition (#1014)

* Revised the book

* Update the book with the second revised edition

* Revise base on the manuscript of the first edition
This commit is contained in:
Yudong Jin
2023-12-28 18:06:09 +08:00
committed by GitHub
parent 19dde675df
commit f68bbb0d59
261 changed files with 643 additions and 647 deletions

View File

@ -25,7 +25,7 @@ class MyList:
def get(self, index: int) -> int:
"""访问元素"""
# 索引如果越界则抛出异常,下同
# 索引如果越界则抛出异常,下同
if index < 0 or index >= self._size:
raise IndexError("索引越界")
return self._arr[index]
@ -68,12 +68,12 @@ class MyList:
self._arr[j] = self._arr[j + 1]
# 更新元素数量
self._size -= 1
# 返回被删除元素
# 返回被删除元素
return num
def extend_capacity(self):
"""列表扩容"""
# 新建一个长度为原数组 __extend_ratio 倍的新数组,并将原数组拷贝到新数组
# 新建一个长度为原数组 _extend_ratio 倍的新数组,并将原数组复制到新数组
self._arr = self._arr + [0] * self.capacity() * (self._extend_ratio - 1)
# 更新列表容量
self._capacity = len(self._arr)

View File

@ -21,10 +21,10 @@ def backtrack(
return
# 遍历所有列
for col in range(n):
# 计算该格子对应的主对角线和对角线
# 计算该格子对应的主对角线和对角线
diag1 = row - col + n - 1
diag2 = row + col
# 剪枝:不允许该格子所在列、主对角线、对角线上存在皇后
# 剪枝:不允许该格子所在列、主对角线、对角线上存在皇后
if not cols[col] and not diags1[diag1] and not diags2[diag2]:
# 尝试:将皇后放置在该格子
state[row][col] = "Q"
@ -42,7 +42,7 @@ def n_queens(n: int) -> list[list[list[str]]]:
state = [["#" for _ in range(n)] for _ in range(n)]
cols = [False] * n # 记录列是否有皇后
diags1 = [False] * (2 * n - 1) # 记录主对角线上是否有皇后
diags2 = [False] * (2 * n - 1) # 记录对角线上是否有皇后
diags2 = [False] * (2 * n - 1) # 记录对角线上是否有皇后
res = []
backtrack(0, n, state, res, cols, diags1, diags2)

View File

@ -14,7 +14,7 @@ from graph_adjacency_list import GraphAdjList
def graph_bfs(graph: GraphAdjList, start_vet: Vertex) -> list[Vertex]:
"""广度优先遍历 BFS"""
"""广度优先遍历"""
# 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点
# 顶点遍历序列
res = []
@ -58,7 +58,7 @@ if __name__ == "__main__":
print("\n初始化后,图为")
graph.print()
# 广度优先遍历 BFS
# 广度优先遍历
res = graph_bfs(graph, v[0])
print("\n广度优先遍历BFS顶点序列为")
print(vets_to_vals(res))

View File

@ -13,7 +13,7 @@ from graph_adjacency_list import GraphAdjList
def dfs(graph: GraphAdjList, visited: set[Vertex], res: list[Vertex], vet: Vertex):
"""深度优先遍历 DFS 辅助函数"""
"""深度优先遍历辅助函数"""
res.append(vet) # 记录访问顶点
visited.add(vet) # 标记该顶点已被访问
# 遍历该顶点的所有邻接顶点
@ -25,7 +25,7 @@ def dfs(graph: GraphAdjList, visited: set[Vertex], res: list[Vertex], vet: Verte
def graph_dfs(graph: GraphAdjList, start_vet: Vertex) -> list[Vertex]:
"""深度优先遍历 DFS"""
"""深度优先遍历"""
# 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点
# 顶点遍历序列
res = []
@ -51,7 +51,7 @@ if __name__ == "__main__":
print("\n初始化后,图为")
graph.print()
# 深度优先遍历 DFS
# 深度优先遍历
res = graph_dfs(graph, v[0])
print("\n深度优先遍历DFS顶点序列为")
print(vets_to_vals(res))

View File

@ -7,7 +7,7 @@ Author: Krahets (krahets@163.com)
def max_capacity(ht: list[int]) -> int:
"""最大容量:贪心"""
# 初始化 i, j 分列数组两端
# 初始化 i, j,使其分列数组两端
i, j = 0, len(ht) - 1
# 初始最大容量为 0
res = 0

View File

@ -93,7 +93,7 @@ if __name__ == "__main__":
hmap.print()
# 查询操作
# 向哈希表输入键 key ,得到值 value
# 向哈希表输入键 key ,得到值 value
name = hmap.get(15937)
print("\n输入学号 15937 ,查询到姓名 " + name)

View File

@ -26,7 +26,7 @@ if __name__ == "__main__":
print_dict(hmap)
# 查询操作
# 向哈希表输入键 key ,得到值 value
# 向哈希表输入键 key ,得到值 value
name: str = hmap[15937]
print("\n输入学号 15937 ,查询到姓名 " + name)

View File

@ -34,11 +34,11 @@ class HashMapChaining:
"""查询操作"""
index = self.hash_func(key)
bucket = self.buckets[index]
# 遍历桶,若找到 key 则返回对应 val
# 遍历桶,若找到 key 则返回对应 val
for pair in bucket:
if pair.key == key:
return pair.val
# 若未找到 key 则返回 None
# 若未找到 key 则返回 None
return None
def put(self, key: int, val: str):
@ -107,7 +107,7 @@ if __name__ == "__main__":
hashmap.print()
# 查询操作
# 向哈希表输入键 key ,得到值 value
# 向哈希表输入键 key ,得到值 value
name = hashmap.get(13276)
print("\n输入学号 13276 ,查询到姓名 " + name)

View File

@ -37,9 +37,9 @@ class HashMapOpenAddressing:
first_tombstone = -1
# 线性探测,当遇到空桶时跳出
while self.buckets[index] is not None:
# 若遇到 key ,返回对应桶索引
# 若遇到 key ,返回对应桶索引
if self.buckets[index].key == key:
# 若之前遇到了删除标记,则将键值对移动至该索引
# 若之前遇到了删除标记,则将键值对移动至该索引
if first_tombstone != -1:
self.buckets[first_tombstone] = self.buckets[index]
self.buckets[index] = self.TOMBSTONE
@ -48,7 +48,7 @@ class HashMapOpenAddressing:
# 记录遇到的首个删除标记
if first_tombstone == -1 and self.buckets[index] is self.TOMBSTONE:
first_tombstone = index
# 计算桶索引,越过尾部返回头部
# 计算桶索引,越过尾部返回头部
index = (index + 1) % self.capacity
# 若 key 不存在,则返回添加点的索引
return index if first_tombstone == -1 else first_tombstone
@ -127,7 +127,7 @@ if __name__ == "__main__":
hashmap.print()
# 查询操作
# 向哈希表输入键 key ,得到值 val
# 向哈希表输入键 key ,得到值 val
name = hashmap.get(13276)
print("\n输入学号 13276 ,查询到姓名 " + name)

View File

@ -23,15 +23,15 @@ class MaxHeap:
self.sift_down(i)
def left(self, i: int) -> int:
"""获取左子节点索引"""
"""获取左子节点索引"""
return 2 * i + 1
def right(self, i: int) -> int:
"""获取右子节点索引"""
"""获取右子节点索引"""
return 2 * i + 2
def parent(self, i: int) -> int:
"""获取父节点索引"""
"""获取父节点索引"""
return (i - 1) // 2 # 向下整除
def swap(self, i: int, j: int):

View File

@ -30,7 +30,7 @@ def bubble_sort_with_flag(nums: list[int]):
nums[j], nums[j + 1] = nums[j + 1], nums[j]
flag = True # 记录交换元素
if not flag:
break # 此轮冒泡未交换任何元素,直接跳出
break # 此轮冒泡未交换任何元素,直接跳出
"""Driver Code"""

View File

@ -7,12 +7,12 @@ Author: timi (xisunyy@163.com), Krahets (krahets@163.com)
def merge(nums: list[int], left: int, mid: int, right: int):
"""合并左子数组和右子数组"""
# 左子数组区间 [left, mid], 右子数组区间 [mid+1, right]
# 左子数组区间 [left, mid], 右子数组区间 [mid+1, right]
# 创建一个临时数组 tmp ,用于存放合并后的结果
tmp = [0] * (right - left + 1)
# 初始化左子数组和右子数组的起始索引
i, j, k = left, mid + 1, 0
# 当左右子数组都还有元素时,比较并将较小的元素复制到临时数组中
# 当左右子数组都还有元素时,进行比较并将较小的元素复制到临时数组中
while i <= mid and j <= right:
if nums[i] <= nums[j]:
tmp[k] = nums[i]

View File

@ -39,7 +39,7 @@ class QuickSortMedian:
"""快速排序类(中位基准数优化)"""
def median_three(self, nums: list[int], left: int, mid: int, right: int) -> int:
"""选取三个元素的中位数"""
"""选取三个候选元素的中位数"""
# 此处使用异或运算来简化代码
# 异或规则为 0 ^ 0 = 1 ^ 1 = 0, 0 ^ 1 = 1 ^ 0 = 1
if (nums[left] < nums[mid]) ^ (nums[left] < nums[right]):

View File

@ -39,7 +39,7 @@ class ArrayDeque:
print("双向队列已满")
return
# 队首指针向左移动一位
# 通过取余操作实现 front 越过数组头部后回到尾部
# 通过取余操作实现 front 越过数组头部后回到尾部
self._front = self.index(self._front - 1)
# 将 num 添加至队首
self._nums[self._front] = num
@ -50,7 +50,7 @@ class ArrayDeque:
if self._size == self.capacity():
print("双向队列已满")
return
# 计算尾指针,指向队尾索引 + 1
# 计算尾指针,指向队尾索引 + 1
rear = self.index(self._front + self._size)
# 将 num 添加至队尾
self._nums[rear] = num

View File

@ -30,8 +30,8 @@ class ArrayQueue:
"""入队"""
if self._size == self.capacity():
raise IndexError("队列已满")
# 计算尾指针,指向队尾索引 + 1
# 通过取余操作实现 rear 越过数组尾部后回到头部
# 计算尾指针,指向队尾索引 + 1
# 通过取余操作实现 rear 越过数组尾部后回到头部
rear: int = (self._front + self._size) % self.capacity()
# 将 num 添加至队尾
self._nums[rear] = num
@ -40,7 +40,7 @@ class ArrayQueue:
def pop(self) -> int:
"""出队"""
num: int = self.peek()
# 队首指针向后移动一位,若越过尾部则返回到数组头部
# 队首指针向后移动一位,若越过尾部则返回到数组头部
self._front = (self._front + 1) % self.capacity()
self._size -= 1
return num

View File

@ -30,7 +30,7 @@ class LinkedListQueue:
def push(self, num: int):
"""入队"""
# 尾节点后添加 num
# 尾节点后添加 num
node = ListNode(num)
# 如果队列为空,则令头、尾节点都指向该节点
if self._front is None:

View File

@ -101,7 +101,7 @@ class AVLTree:
"""递归插入节点(辅助方法)"""
if node is None:
return TreeNode(val)
# 1. 查找插入位置并插入节点
# 1. 查找插入位置并插入节点
if val < node.val:
node.left = self.insert_helper(node.left, val)
elif val > node.val:
@ -122,7 +122,7 @@ class AVLTree:
"""递归删除节点(辅助方法)"""
if node is None:
return None
# 1. 查找节点并删除
# 1. 查找节点并删除
if val < node.val:
node.left = self.remove_helper(node.left, val)
elif val > node.val: