From cf9d102ed56c42b184268d8a40c064e72810313f Mon Sep 17 00:00:00 2001 From: krahets Date: Fri, 3 Mar 2023 02:46:12 +0800 Subject: [PATCH] build --- chapter_array_and_linkedlist/array.md | 14 +- chapter_array_and_linkedlist/linked_list.md | 8 +- chapter_array_and_linkedlist/list.md | 37 ++-- .../space_complexity.md | 16 +- .../space_time_tradeoff.md | 4 +- .../time_complexity.md | 26 +-- chapter_graph/graph_operations.md | 51 +++--- chapter_graph/graph_traversal.md | 23 ++- chapter_hashing/hash_map.md | 21 +-- chapter_heap/build_heap.md | 2 +- chapter_heap/heap.md | 21 +-- chapter_searching/binary_search.md | 12 +- chapter_searching/hashing_search.md | 8 +- chapter_searching/linear_search.md | 4 +- chapter_sorting/bubble_sort.md | 4 +- chapter_sorting/insertion_sort.md | 4 +- chapter_sorting/merge_sort.md | 8 +- chapter_sorting/quick_sort.md | 10 +- chapter_stack_and_queue/deque.md | 161 +++++++++--------- chapter_stack_and_queue/queue.md | 40 ++--- chapter_stack_and_queue/stack.md | 56 +++--- chapter_tree/avl_tree.md | 82 ++++----- chapter_tree/binary_search_tree.md | 10 +- chapter_tree/binary_tree_traversal.md | 12 +- 24 files changed, 320 insertions(+), 314 deletions(-) diff --git a/chapter_array_and_linkedlist/array.md b/chapter_array_and_linkedlist/array.md index a5cd5a3fb..0b71aa6be 100755 --- a/chapter_array_and_linkedlist/array.md +++ b/chapter_array_and_linkedlist/array.md @@ -149,8 +149,8 @@ elementAddr = firtstElementAddr + elementLength * elementIndex === "Python" ```python title="array.py" - """ 随机访问元素 """ def random_access(nums): + """ 随机访问元素 """ # 在区间 [0, len(nums)-1] 中随机抽取一个数字 random_index = random.randint(0, len(nums) - 1) # 获取并返回随机元素 @@ -285,10 +285,8 @@ elementAddr = firtstElementAddr + elementLength * elementIndex === "Python" ```python title="array.py" - """ 扩展数组长度 """ - # 请注意,Python 的 list 是动态数组,可以直接扩展 - # 为了方便学习,本函数将 list 看作是长度不可变的数组 def extend(nums, enlarge): + """ 扩展数组长度 """ # 初始化一个扩展长度后的数组 res = [0] * (len(nums) + enlarge) # 将原数组中的所有元素复制到新数组 @@ -442,8 +440,8 @@ elementAddr = firtstElementAddr + elementLength * elementIndex === "Python" ```python title="array.py" - """ 在数组的索引 index 处插入元素 num """ def insert(nums, num, index): + """ 在数组的索引 index 处插入元素 num """ # 把索引 index 以及之后的所有元素向后移动一位 for i in range(len(nums) - 1, index, -1): nums[i] = nums[i - 1] @@ -562,8 +560,8 @@ elementAddr = firtstElementAddr + elementLength * elementIndex === "Python" ```python title="array.py" - """ 删除索引 index 处元素 """ def remove(nums, index): + """ 删除索引 index 处元素 """ # 把索引 index 之后的所有元素向前移动一位 for i in range(index, len(nums) - 1): nums[i] = nums[i + 1] @@ -694,8 +692,8 @@ elementAddr = firtstElementAddr + elementLength * elementIndex === "Python" ```python title="array.py" - """ 遍历数组 """ def traverse(nums): + """ 遍历数组 """ count = 0 # 通过索引遍历数组 for i in range(len(nums)): @@ -850,8 +848,8 @@ elementAddr = firtstElementAddr + elementLength * elementIndex === "Python" ```python title="array.py" - """ 在数组中查找指定元素 """ def find(nums, target): + """ 在数组中查找指定元素 """ for i in range(len(nums)): if nums[i] == target: return i diff --git a/chapter_array_and_linkedlist/linked_list.md b/chapter_array_and_linkedlist/linked_list.md index 1ec86a04b..7d33bac3e 100755 --- a/chapter_array_and_linkedlist/linked_list.md +++ b/chapter_array_and_linkedlist/linked_list.md @@ -351,8 +351,8 @@ comments: true === "Python" ```python title="linked_list.py" - """ 在链表的结点 n0 之后插入结点 P """ def insert(n0, P): + """ 在链表的结点 n0 之后插入结点 P """ n1 = n0.next P.next = n1 n0.next = P @@ -470,8 +470,8 @@ comments: true === "Python" ```python title="linked_list.py" - """ 删除链表的结点 n0 之后的首个结点 """ def remove(n0): + """ 删除链表的结点 n0 之后的首个结点 """ if not n0.next: return # n0 -> P -> n1 @@ -609,8 +609,8 @@ comments: true === "Python" ```python title="linked_list.py" - """ 访问链表中索引为 index 的结点 """ def access(head, index): + """ 访问链表中索引为 index 的结点 """ for _ in range(index): if not head: return None @@ -757,8 +757,8 @@ comments: true === "Python" ```python title="linked_list.py" - """ 在链表中查找值为 target 的首个结点 """ def find(head, target): + """ 在链表中查找值为 target 的首个结点 """ index = 0 while head: if head.val == target: diff --git a/chapter_array_and_linkedlist/list.md b/chapter_array_and_linkedlist/list.md index 2bd56684b..d3b18e4cd 100755 --- a/chapter_array_and_linkedlist/list.md +++ b/chapter_array_and_linkedlist/list.md @@ -933,40 +933,45 @@ comments: true === "Python" ```python title="my_list.py" - """ 列表类简易实现 """ class MyList: - """ 构造方法 """ + """ 列表类简易实现 """ def __init__(self): + """ 构造方法 """ self.__capacity = 10 # 列表容量 self.__nums = [0] * self.__capacity # 数组(存储列表元素) self.__size = 0 # 列表长度(即当前元素数量) self.__extend_ratio = 2 # 每次列表扩容的倍数 - """ 获取列表长度(即当前元素数量) """ def size(self): + """ 获取列表长度(即当前元素数量) """ return self.__size - """ 获取列表容量 """ def capacity(self): + """ 获取列表容量 """ return self.__capacity - """ 访问元素 """ def get(self, index): + """ 访问元素 """ # 索引如果越界则抛出异常,下同 assert index >= 0 and index < self.__size, "索引越界" return self.__nums[index] - """ 更新元素 """ def set(self, num, index): + """ 更新元素 """ assert index >= 0 and index < self.__size, "索引越界" self.__nums[index] = num + + def add(self, num): + """ 尾部添加元素 """ + # 元素数量超出容量时,触发扩容机制 + if self.size() == self.capacity(): + self.extend_capacity(); + self.__nums[self.__size] = num + self.__size += 1 - """ 中间插入(尾部添加)元素 """ - def add(self, num, index=-1): + def insert(self, num, index): + """ 中间插入元素 """ assert index >= 0 and index < self.__size, "索引越界" - # 若不指定索引 index ,则向数组尾部添加元素 - if index == -1: - index = self.__size # 元素数量超出容量时,触发扩容机制 if self.__size == self.capacity(): self.extend_capacity() @@ -977,10 +982,10 @@ comments: true # 更新元素数量 self.__size += 1 - """ 删除元素 """ def remove(self, index): + """ 删除元素 """ assert index >= 0 and index < self.__size, "索引越界" - num = self.nums[index] + num = self.__nums[index] # 索引 i 之后的元素都向前移动一位 for j in range(index, self.__size - 1): self.__nums[j] = self.__nums[j + 1] @@ -989,15 +994,15 @@ comments: true # 返回被删除元素 return num - """ 列表扩容 """ def extend_capacity(self): + """ 列表扩容 """ # 新建一个长度为 self.__size 的数组,并将原数组拷贝到新数组 self.__nums = self.__nums + [0] * self.capacity() * (self.__extend_ratio - 1) # 更新列表容量 self.__capacity = len(self.__nums) - """ 返回有效长度的列表 """ def to_array(self): + """ 返回有效长度的列表 """ return self.__nums[:self.__size] ``` @@ -1311,7 +1316,7 @@ comments: true public toArray(): number[] { let size = this.size(); // 仅转换有效长度范围内的列表元素 - let nums = new Array(size); + const nums = new Array(size); for (let i = 0; i < size; i++) { nums[i] = this.get(i); } diff --git a/chapter_computational_complexity/space_complexity.md b/chapter_computational_complexity/space_complexity.md index 375671e4a..005ed7cb3 100755 --- a/chapter_computational_complexity/space_complexity.md +++ b/chapter_computational_complexity/space_complexity.md @@ -624,8 +624,8 @@ $$ === "Python" ```python title="space_complexity.py" - """ 常数阶 """ def constant(n): + """ 常数阶 """ # 常量、变量、对象占用 O(1) 空间 a = 0 nums = [0] * 10000 @@ -829,8 +829,8 @@ $$ === "Python" ```python title="space_complexity.py" - """ 线性阶 """ def linear(n): + """ 线性阶 """ # 长度为 n 的列表占用 O(n) 空间 nums = [0] * n # 长度为 n 的哈希表占用 O(n) 空间 @@ -996,8 +996,8 @@ $$ === "Python" ```python title="space_complexity.py" - """ 线性阶(递归实现) """ def linear_recur(n): + """ 线性阶(递归实现) """ print("递归 n =", n) if n == 1: return linear_recur(n - 1) @@ -1127,8 +1127,8 @@ $$ === "Python" ```python title="space_complexity.py" - """ 平方阶 """ def quadratic(n): + """ 平方阶 """ # 二维列表占用 O(n^2) 空间 num_matrix = [[0] * n for _ in range(n)] ``` @@ -1171,7 +1171,9 @@ $$ /* 平方阶 */ function quadratic(n: number): void { // 矩阵占用 O(n^2) 空间 - const numMatrix = Array(n).fill(null).map(() => Array(n).fill(null)); + const numMatrix = Array(n) + .fill(null) + .map(() => Array(n).fill(null)); // 二维列表占用 O(n^2) 空间 const numList = []; for (let i = 0; i < n; i++) { @@ -1273,8 +1275,8 @@ $$ === "Python" ```python title="space_complexity.py" - """ 平方阶(递归实现) """ def quadratic_recur(n): + """ 平方阶(递归实现) """ if n <= 0: return 0 # 数组 nums 长度为 n, n-1, ..., 2, 1 nums = [0] * n @@ -1403,8 +1405,8 @@ $$ === "Python" ```python title="space_complexity.py" - """ 指数阶(建立满二叉树) """ def build_tree(n): + """ 指数阶(建立满二叉树) """ if n == 0: return None root = TreeNode(0) root.left = build_tree(n - 1) diff --git a/chapter_computational_complexity/space_time_tradeoff.md b/chapter_computational_complexity/space_time_tradeoff.md index baa24b9a2..5c319fcf4 100755 --- a/chapter_computational_complexity/space_time_tradeoff.md +++ b/chapter_computational_complexity/space_time_tradeoff.md @@ -65,8 +65,8 @@ comments: true === "Python" ```python title="leetcode_two_sum.py" - """ 方法一:暴力枚举 """ def two_sum_brute_force(nums: List[int], target: int) -> List[int]: + """ 方法一:暴力枚举 """ # 两层循环,时间复杂度 O(n^2) for i in range(len(nums) - 1): for j in range(i + 1, len(nums)): @@ -242,8 +242,8 @@ comments: true === "Python" ```python title="leetcode_two_sum.py" - """ 方法二:辅助哈希表 """ def two_sum_hash_table(nums: List[int], target: int) -> List[int]: + """ 方法二:辅助哈希表 """ # 辅助哈希表,空间复杂度 O(n) dic = {} # 单层循环,时间复杂度 O(n) diff --git a/chapter_computational_complexity/time_complexity.md b/chapter_computational_complexity/time_complexity.md index 4e182fdfd..585b5575e 100755 --- a/chapter_computational_complexity/time_complexity.md +++ b/chapter_computational_complexity/time_complexity.md @@ -821,8 +821,8 @@ $$ === "Python" ```python title="time_complexity.py" - """ 常数阶 """ def constant(n): + """ 常数阶 """ count = 0 size = 100000 for _ in range(size): @@ -949,8 +949,8 @@ $$ === "Python" ```python title="time_complexity.py" - """ 线性阶 """ def linear(n): + """ 线性阶 """ count = 0 for _ in range(n): count += 1 @@ -1075,8 +1075,8 @@ $$ === "Python" ```python title="time_complexity.py" - """ 线性阶(遍历数组)""" def array_traversal(nums): + """ 线性阶(遍历数组)""" count = 0 # 循环次数与数组长度成正比 for num in nums: @@ -1215,8 +1215,8 @@ $$ === "Python" ```python title="time_complexity.py" - """ 平方阶 """ def quadratic(n): + """ 平方阶 """ count = 0 # 循环次数与数组长度成平方关系 for i in range(n): @@ -1391,8 +1391,8 @@ $$ === "Python" ```python title="time_complexity.py" - """ 平方阶(冒泡排序)""" def bubble_sort(nums): + """ 平方阶(冒泡排序)""" count = 0 # 计数器 # 外循环:待排序元素数量为 n-1, n-2, ..., 1 for i in range(len(nums) - 1, 0, -1): @@ -1604,8 +1604,8 @@ $$ === "Python" ```python title="time_complexity.py" - """ 指数阶(循环实现)""" def exponential(n): + """ 指数阶(循环实现)""" count, base = 0, 1 # cell 每轮一分为二,形成数列 1, 2, 4, 8, ..., 2^(n-1) for _ in range(n): @@ -1768,8 +1768,8 @@ $$ === "Python" ```python title="time_complexity.py" - """ 指数阶(递归实现)""" def exp_recur(n): + """ 指数阶(递归实现)""" if n == 1: return 1 return exp_recur(n - 1) + exp_recur(n - 1) + 1 ``` @@ -1884,8 +1884,8 @@ $$ === "Python" ```python title="time_complexity.py" - """ 对数阶(循环实现)""" def logarithmic(n): + """ 对数阶(循环实现)""" count = 0 while n > 1: n = n / 2 @@ -2017,8 +2017,8 @@ $$ === "Python" ```python title="time_complexity.py" - """ 对数阶(递归实现)""" def log_recur(n): + """ 对数阶(递归实现)""" if n <= 1: return 0 return log_recur(n / 2) + 1 ``` @@ -2133,8 +2133,8 @@ $$ === "Python" ```python title="time_complexity.py" - """ 线性对数阶 """ def linear_log_recur(n): + """ 线性对数阶 """ if n <= 1: return 1 count = linear_log_recur(n // 2) + \ linear_log_recur(n // 2) @@ -2290,8 +2290,8 @@ $$ === "Python" ```python title="time_complexity.py" - """ 阶乘阶(递归实现)""" def factorial_recur(n): + """ 阶乘阶(递归实现)""" if n == 0: return 1 count = 0 # 从 1 个分裂出 n 个 @@ -2480,16 +2480,16 @@ $$ === "Python" ```python title="worst_best_time_complexity.py" - """ 生成一个数组,元素为: 1, 2, ..., n ,顺序被打乱 """ def random_numbers(n): + """ 生成一个数组,元素为: 1, 2, ..., n ,顺序被打乱 """ # 生成数组 nums =: 1, 2, 3, ..., n nums = [i for i in range(1, n + 1)] # 随机打乱数组元素 random.shuffle(nums) return nums - """ 查找数组 nums 中数字 1 所在索引 """ def find_one(nums): + """ 查找数组 nums 中数字 1 所在索引 """ for i in range(len(nums)): # 当元素 1 在数组头部时,达到最佳时间复杂度 O(1) # 当元素 1 在数组尾部时,达到最差时间复杂度 O(n) diff --git a/chapter_graph/graph_operations.md b/chapter_graph/graph_operations.md index f4ba309ba..f94def5a6 100644 --- a/chapter_graph/graph_operations.md +++ b/chapter_graph/graph_operations.md @@ -127,8 +127,8 @@ comments: true ```cpp title="graph_adjacency_matrix.cpp" /* 基于邻接矩阵实现的无向图类 */ class GraphAdjMat { - vector vertices; // 顶点列表,元素代表“顶点值”,索引代表“顶点索引” - vector> adjMat; // 邻接矩阵,行列索引对应“顶点索引” + vector vertices; // 顶点列表,元素代表“顶点值”,索引代表“顶点索引” + vector> adjMat; // 邻接矩阵,行列索引对应“顶点索引” public: /* 构造方法 */ @@ -213,15 +213,15 @@ comments: true === "Python" ```python title="graph_adjacency_matrix.py" - """ 基于邻接矩阵实现的无向图类 """ class GraphAdjMat: + """ 基于邻接矩阵实现的无向图类 """ # 顶点列表,元素代表“顶点值”,索引代表“顶点索引” vertices = [] # 邻接矩阵,行列索引对应“顶点索引” adj_mat = [] - """ 构造方法 """ def __init__(self, vertices, edges): + """ 构造方法 """ self.vertices = [] self.adj_mat = [] # 添加顶点 @@ -232,12 +232,12 @@ comments: true for e in edges: self.add_edge(e[0], e[1]) - """ 获取顶点数量 """ def size(self): + """ 获取顶点数量 """ return len(self.vertices) - """ 添加顶点 """ def add_vertex(self, val): + """ 添加顶点 """ n = self.size() # 向顶点列表中添加新顶点的值 self.vertices.append(val) @@ -248,9 +248,8 @@ comments: true for row in self.adj_mat: row.append(0) - - """ 删除顶点 """ def remove_vertex(self, index): + """ 删除顶点 """ if index >= self.size(): raise IndexError() # 在顶点列表中移除索引 index 的顶点 @@ -261,9 +260,9 @@ comments: true for row in self.adj_mat: row.pop(index) - """ 添加边 """ - # 参数 i, j 对应 vertices 元素索引 def add_edge(self, i, j): + """ 添加边 """ + # 参数 i, j 对应 vertices 元素索引 # 索引越界与相等处理 if i < 0 or j < 0 or i >= self.size() or j >= self.size() or i == j: raise IndexError() @@ -271,17 +270,17 @@ comments: true self.adj_mat[i][j] = 1 self.adj_mat[j][i] = 1 - """ 删除边 """ - # 参数 i, j 对应 vertices 元素索引 def remove_edge(self, i, j): + """ 删除边 """ + # 参数 i, j 对应 vertices 元素索引 # 索引越界与相等处理 if i < 0 or j < 0 or i >= self.size() or j >= self.size() or i == j: raise IndexError() self.adj_mat[i][j] = 0 self.adj_mat[j][i] = 0 - """ 打印邻接矩阵 """ def print(self): + """ 打印邻接矩阵 """ print("顶点列表 =", self.vertices) print("邻接矩阵 =") print_matrix(self.adj_mat) @@ -964,13 +963,13 @@ comments: true === "Python" ```python title="graph_adjacency_list.py" - """ 基于邻接表实现的无向图类 """ class GraphAdjList: + """ 基于邻接表实现的无向图类 """ # 邻接表,key: 顶点,value:该顶点的所有邻接顶点 adj_list = {} - """ 构造方法 """ def __init__(self, edges: List[List[Vertex]]) -> None: + """ 构造方法 """ self.adj_list = {} # 添加所有顶点和边 for edge in edges: @@ -978,35 +977,35 @@ comments: true self.add_vertex(edge[1]) self.add_edge(edge[0], edge[1]) - """ 获取顶点数量 """ def size(self) -> int: + """ 获取顶点数量 """ return len(self.adj_list) - """ 添加边 """ def add_edge(self, vet1: Vertex, vet2: Vertex) -> None: + """ 添加边 """ if vet1 not in self.adj_list or vet2 not in self.adj_list or vet1 == vet2: raise ValueError # 添加边 vet1 - vet2 self.adj_list[vet1].append(vet2) self.adj_list[vet2].append(vet1) - """ 删除边 """ def remove_edge(self, vet1: Vertex, vet2: Vertex) -> None: + """ 删除边 """ if vet1 not in self.adj_list or vet2 not in self.adj_list or vet1 == vet2: raise ValueError # 删除边 vet1 - vet2 self.adj_list[vet1].remove(vet2) self.adj_list[vet2].remove(vet1) - """ 添加顶点 """ def add_vertex(self, vet: Vertex) -> None: + """ 添加顶点 """ if vet in self.adj_list: return # 在邻接表中添加一个新链表 self.adj_list[vet] = [] - """ 删除顶点 """ def remove_vertex(self, vet: Vertex) -> None: + """ 删除顶点 """ if vet not in self.adj_list: raise ValueError # 在邻接表中删除顶点 vet 对应的链表 @@ -1016,8 +1015,8 @@ comments: true if vet in self.adj_list[vertex]: self.adj_list[vertex].remove(vet) - """ 打印邻接表 """ def print(self) -> None: + """ 打印邻接表 """ print("邻接表 =") for vertex in self.adj_list: tmp = [v.val for v in self.adj_list[vertex]] @@ -1223,7 +1222,7 @@ comments: true /* 添加边 */ addEdge(vet1: Vertex, vet2: Vertex): void { if (!this.adjList.has(vet1) || !this.adjList.has(vet2) || vet1 === vet2) { - throw new Error("Illegal Argument Exception"); + throw new Error('Illegal Argument Exception'); } // 添加边 vet1 - vet2 this.adjList.get(vet1).push(vet2); @@ -1233,7 +1232,7 @@ comments: true /* 删除边 */ removeEdge(vet1: Vertex, vet2: Vertex): void { if (!this.adjList.has(vet1) || !this.adjList.has(vet2) || vet1 === vet2) { - throw new Error("Illegal Argument Exception"); + throw new Error('Illegal Argument Exception'); } // 删除边 vet1 - vet2 this.adjList.get(vet1).splice(this.adjList.get(vet1).indexOf(vet2), 1); @@ -1250,7 +1249,7 @@ comments: true /* 删除顶点 */ removeVertex(vet: Vertex): void { if (!this.adjList.has(vet)) { - throw new Error("Illegal Argument Exception"); + throw new Error('Illegal Argument Exception'); } // 在邻接表中删除顶点 vet 对应的链表 this.adjList.delete(vet); @@ -1265,13 +1264,13 @@ comments: true /* 打印邻接表 */ print(): void { - console.log("邻接表 ="); + console.log('邻接表 ='); for (const [key, value] of this.adjList.entries()) { const tmp = []; for (const vertex of value) { tmp.push(vertex.val); } - console.log(key.val + ": " + tmp.join()); + console.log(key.val + ': ' + tmp.join()); } } } diff --git a/chapter_graph/graph_traversal.md b/chapter_graph/graph_traversal.md index 0c30f89c9..11842c3f0 100644 --- a/chapter_graph/graph_traversal.md +++ b/chapter_graph/graph_traversal.md @@ -93,9 +93,9 @@ BFS 常借助「队列」来实现。队列具有“先入先出”的性质, === "Python" ```python title="graph_bfs.py" - """ 广度优先遍历 BFS """ - # 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点 def graph_bfs(graph: GraphAdjList, start_vet: Vertex) -> List[Vertex]: + """ 广度优先遍历 BFS """ + # 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点 # 顶点遍历序列 res = [] # 哈希表,用于记录已被访问过的顶点 @@ -198,15 +198,15 @@ BFS 常借助「队列」来实现。队列具有“先入先出”的性质, const que = [startVet]; // 以顶点 vet 为起点,循环直至访问完所有顶点 while (que.length) { - const vet = que.shift(); // 队首顶点出队 - res.push(vet); // 记录访问顶点 + const vet = que.shift(); // 队首顶点出队 + res.push(vet); // 记录访问顶点 // 遍历该顶点的所有邻接顶点 for (const adjVet of graph.adjList.get(vet) ?? []) { if (visited.has(adjVet)) { - continue; // 跳过已被访问过的顶点 + continue; // 跳过已被访问过的顶点 } - que.push(adjVet); // 只入队未访问 - visited.add(adjVet); // 标记该顶点已被访问 + que.push(adjVet); // 只入队未访问 + visited.add(adjVet); // 标记该顶点已被访问 } } // 返回顶点遍历序列 @@ -378,8 +378,8 @@ BFS 常借助「队列」来实现。队列具有“先入先出”的性质, === "Python" ```python title="graph_dfs.py" - """ 深度优先遍历 DFS 辅助函数 """ def dfs(graph: GraphAdjList, visited: Set[Vertex], res: List[Vertex], vet: Vertex): + """ 深度优先遍历 DFS 辅助函数 """ res.append(vet) # 记录访问顶点 visited.add(vet) # 标记该顶点已被访问 # 遍历该顶点的所有邻接顶点 @@ -389,9 +389,8 @@ BFS 常借助「队列」来实现。队列具有“先入先出”的性质, # 递归访问邻接顶点 dfs(graph, visited, res, adjVet) - """ 深度优先遍历 DFS """ - # 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点 def graph_dfs(graph: GraphAdjList, start_vet: Vertex) -> List[Vertex]: + """ 深度优先遍历 DFS """ # 顶点遍历序列 res = [] # 哈希表,用于记录已被访问过的顶点 @@ -466,8 +465,8 @@ BFS 常借助「队列」来实现。队列具有“先入先出”的性质, ```typescript title="graph_dfs.ts" /* 深度优先遍历 DFS 辅助函数 */ function dfs(graph: GraphAdjList, visited: Set, res: Vertex[], vet: Vertex): void { - res.push(vet); // 记录访问顶点 - visited.add(vet); // 标记该顶点已被访问 + res.push(vet); // 记录访问顶点 + visited.add(vet); // 标记该顶点已被访问 // 遍历该顶点的所有邻接顶点 for (const adjVet of graph.adjList.get(vet)) { if (visited.has(adjVet)) { diff --git a/chapter_hashing/hash_map.md b/chapter_hashing/hash_map.md index 98170340b..c091904be 100755 --- a/chapter_hashing/hash_map.md +++ b/chapter_hashing/hash_map.md @@ -604,69 +604,70 @@ $$ === "Python" ```python title="array_hash_map.py" - """ 键值对 int->String """ class Entry: + """ 键值对 int->String """ def __init__(self, key, val): self.key = key self.val = val - """ 基于数组简易实现的哈希表 """ class ArrayHashMap: + """ 基于数组简易实现的哈希表 """ def __init__(self): + """ 构造方法 """ # 初始化一个长度为 100 的桶(数组) self.bucket = [None] * 100 - """ 哈希函数 """ def hash_func(self, key): + """ 哈希函数 """ index = key % 100 return index - """ 查询操作 """ def get(self, key): + """ 查询操作 """ index = self.hash_func(key) pair = self.bucket[index] if pair is None: return None return pair.val - """ 添加操作 """ def put(self, key, val): + """ 添加操作 """ pair = Entry(key, val) index = self.hash_func(key) self.bucket[index] = pair - """ 删除操作 """ def remove(self, key): + """ 删除操作 """ index = self.hash_func(key) # 置为 None ,代表删除 self.bucket[index] = None - """ 获取所有键值对 """ def entry_set(self): + """ 获取所有键值对 """ result = [] for pair in self.bucket: if pair is not None: result.append(pair) return result - """ 获取所有键 """ def key_set(self): + """ 获取所有键 """ result = [] for pair in self.bucket: if pair is not None: result.append(pair.key) return result - """ 获取所有值 """ def value_set(self): + """ 获取所有值 """ result = [] for pair in self.bucket: if pair is not None: result.append(pair.val) return result - """ 打印哈希表 """ def print(self): + """ 打印哈希表 """ for pair in self.bucket: if pair is not None: print(pair.key, "->", pair.val) diff --git a/chapter_heap/build_heap.md b/chapter_heap/build_heap.md index b1d8fb693..15e8e6845 100644 --- a/chapter_heap/build_heap.md +++ b/chapter_heap/build_heap.md @@ -47,8 +47,8 @@ comments: true === "Python" ```python title="my_heap.py" - """ 构造方法 """ def __init__(self, nums: List[int]): + """ 构造方法 """ # 将列表元素原封不动添加进堆 self.max_heap = nums # 堆化除叶结点以外的其他所有结点 diff --git a/chapter_heap/heap.md b/chapter_heap/heap.md index c8384eaa2..efd1bc275 100644 --- a/chapter_heap/heap.md +++ b/chapter_heap/heap.md @@ -365,16 +365,16 @@ comments: true === "Python" ```python title="my_heap.py" - """ 获取左子结点索引 """ 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 # 向下整除 ``` @@ -532,8 +532,8 @@ comments: true === "Python" ```python title="my_heap.py" - """ 访问堆顶元素 """ def peek(self) -> int: + """ 访问堆顶元素 """ return self.max_heap[0] ``` @@ -681,15 +681,15 @@ comments: true === "Python" ```python title="my_heap.py" - """ 元素入堆 """ def push(self, val: int): + """ 元素入堆 """ # 添加结点 self.max_heap.append(val) # 从底至顶堆化 self.sift_up(self.size() - 1) - """ 从结点 i 开始,从底至顶堆化 """ def sift_up(self, i: int): + """ 从结点 i 开始,从底至顶堆化 """ while True: # 获取结点 i 的父结点 p = self.parent(i) @@ -995,8 +995,8 @@ comments: true === "Python" ```python title="my_heap.py" - """ 元素出堆 """ def poll(self) -> int: + """ 元素出堆 """ # 判空处理 assert not self.is_empty() # 交换根结点与最右叶结点(即交换首元素与尾元素) @@ -1008,8 +1008,8 @@ comments: true # 返回堆顶元素 return val - """ 从结点 i 开始,从顶至底堆化 """ def sift_down(self, i: int): + """ 从结点 i 开始,从顶至底堆化 """ while True: # 判断结点 i, l, r 中值最大的结点,记为 ma l, r, ma = self.left(i), self.right(i), i @@ -1113,7 +1113,7 @@ comments: true /* 元素出堆 */ poll(): number { // 判空处理 - if (this.isEmpty()) throw new RangeError("Heap is empty."); + if (this.isEmpty()) throw new RangeError('Heap is empty.'); // 交换根结点与最右叶结点(即交换首元素与尾元素) this.swap(0, this.size() - 1); // 删除结点 @@ -1128,7 +1128,8 @@ comments: true siftDown(i: number): void { while (true) { // 判断结点 i, l, r 中值最大的结点,记为 ma - const l = this.left(i), r = this.right(i); + const l = this.left(i), + r = this.right(i); let ma = i; if (l < this.size() && this.maxHeap[l] > this.maxHeap[ma]) ma = l; if (r < this.size() && this.maxHeap[r] > this.maxHeap[ma]) ma = r; diff --git a/chapter_searching/binary_search.md b/chapter_searching/binary_search.md index d5babb288..e9dae2ecf 100755 --- a/chapter_searching/binary_search.md +++ b/chapter_searching/binary_search.md @@ -98,8 +98,8 @@ $$ === "Python" ```python title="binary_search.py" - """ 二分查找(双闭区间) """ def binary_search(nums, target): + """ 二分查找(双闭区间) """ # 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素 i, j = 0, len(nums) - 1 while i <= j: @@ -145,7 +145,7 @@ $$ let i = 0, j = nums.length - 1; // 循环,当搜索区间为空时跳出(当 i > j 时为空) while (i <= j) { - let m = parseInt((i + j) / 2); // 计算中点索引 m ,在 JS 中需使用 parseInt 函数取整 + const m = parseInt((i + j) / 2); // 计算中点索引 m ,在 JS 中需使用 parseInt 函数取整 if (nums[m] < target) // 此情况说明 target 在区间 [m+1, j] 中 i = m + 1; else if (nums[m] > target) // 此情况说明 target 在区间 [i, m-1] 中 @@ -167,7 +167,7 @@ $$ let i = 0, j = nums.length - 1; // 循环,当搜索区间为空时跳出(当 i > j 时为空) while (i <= j) { - const m = Math.floor(i + (j - i) / 2); // 计算中点索引 m + const m = Math.floor((i + j) / 2); // 计算中点索引 m if (nums[m] < target) { // 此情况说明 target 在区间 [m+1, j] 中 i = m + 1; } else if (nums[m] > target) { // 此情况说明 target 在区间 [i, m-1] 中 @@ -309,8 +309,8 @@ $$ === "Python" ```python title="binary_search.py" - """ 二分查找(左闭右开) """ def binary_search1(nums, target): + """ 二分查找(左闭右开) """ # 初始化左闭右开 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1 i, j = 0, len(nums) # 循环,当搜索区间为空时跳出(当 i = j 时为空) @@ -357,7 +357,7 @@ $$ let i = 0, j = nums.length; // 循环,当搜索区间为空时跳出(当 i = j 时为空) while (i < j) { - let m = parseInt((i + j) / 2); // 计算中点索引 m ,在 JS 中需使用 parseInt 函数取整 + const m = parseInt((i + j) / 2); // 计算中点索引 m ,在 JS 中需使用 parseInt 函数取整 if (nums[m] < target) // 此情况说明 target 在区间 [m+1, j) 中 i = m + 1; else if (nums[m] > target) // 此情况说明 target 在区间 [i, m) 中 @@ -379,7 +379,7 @@ $$ let i = 0, j = nums.length; // 循环,当搜索区间为空时跳出(当 i = j 时为空) while (i < j) { - const m = Math.floor(i + (j - i) / 2); // 计算中点索引 m + const m = Math.floor((i + j) / 2); // 计算中点索引 m if (nums[m] < target) { // 此情况说明 target 在区间 [m+1, j) 中 i = m + 1; } else if (nums[m] > target) { // 此情况说明 target 在区间 [i, m) 中 diff --git a/chapter_searching/hashing_search.md b/chapter_searching/hashing_search.md index 301a3e829..ba971cae7 100755 --- a/chapter_searching/hashing_search.md +++ b/chapter_searching/hashing_search.md @@ -45,8 +45,8 @@ comments: true === "Python" ```python title="hashing_search.py" - """ 哈希查找(数组) """ def hashing_search_array(mapp, target): + """ 哈希查找(数组) """ # 哈希表的 key: 目标元素,value: 索引 # 若哈希表中无此 key ,返回 -1 return mapp.get(target, -1) @@ -85,7 +85,7 @@ comments: true function hashingSearchArray(map: Map, target: number): number { // 哈希表的 key: 目标元素,value: 索引 // 若哈希表中无此 key ,返回 -1 - return map.has(target) ? map.get(target) as number : -1; + return map.has(target) ? (map.get(target) as number) : -1; } ``` @@ -163,8 +163,8 @@ comments: true === "Python" ```python title="hashing_search.py" - """ 哈希查找(链表) """ def hashing_search_linkedlist(mapp, target): + """ 哈希查找(链表) """ # 哈希表的 key: 目标元素,value: 结点对象 # 若哈希表中无此 key ,返回 -1 return mapp.get(target, -1) @@ -203,7 +203,7 @@ comments: true function hashingSearchLinkedList(map: Map, target: number): ListNode | null { // 哈希表的 key: 目标结点值,value: 结点对象 // 若哈希表中无此 key ,返回 null - return map.has(target) ? map.get(target) as ListNode : null; + return map.has(target) ? (map.get(target) as ListNode) : null; } ``` diff --git a/chapter_searching/linear_search.md b/chapter_searching/linear_search.md index 506fe4020..1aaf53dc8 100755 --- a/chapter_searching/linear_search.md +++ b/chapter_searching/linear_search.md @@ -49,8 +49,8 @@ comments: true === "Python" ```python title="linear_search.py" - """ 线性查找(数组) """ def linear_search_array(nums, target): + """ 线性查找(数组) """ # 遍历数组 for i in range(len(nums)): if nums[i] == target: # 找到目标元素,返回其索引 @@ -206,8 +206,8 @@ comments: true === "Python" ```python title="linear_search.py" - """ 线性查找(链表) """ def linear_search_linkedlist(head, target): + """ 线性查找(链表) """ # 遍历链表 while head: if head.val == target: # 找到目标结点,返回之 diff --git a/chapter_sorting/bubble_sort.md b/chapter_sorting/bubble_sort.md index 620518cf5..c7f7616f3 100755 --- a/chapter_sorting/bubble_sort.md +++ b/chapter_sorting/bubble_sort.md @@ -87,8 +87,8 @@ comments: true === "Python" ```python title="bubble_sort.py" - """ 冒泡排序 """ def bubble_sort(nums): + """ 冒泡排序 """ n = len(nums) # 外循环:待排序元素数量为 n-1, n-2, ..., 1 for i in range(n - 1, 0, -1): @@ -295,8 +295,8 @@ comments: true === "Python" ```python title="bubble_sort.py" - """ 冒泡排序(标志优化) """ def bubble_sort_with_flag(nums): + """ 冒泡排序(标志优化) """ n = len(nums) # 外循环:待排序元素数量为 n-1, n-2, ..., 1 for i in range(n - 1, 0, -1): diff --git a/chapter_sorting/insertion_sort.md b/chapter_sorting/insertion_sort.md index 4e54732ae..0dbb019ab 100755 --- a/chapter_sorting/insertion_sort.md +++ b/chapter_sorting/insertion_sort.md @@ -63,9 +63,9 @@ comments: true === "Python" ```python title="insertion_sort.py" - """ 插入排序 """ def insertion_sort(nums): - # 外循环:base = nums[1], nums[2], ..., nums[n-1] + """ 插入排序 """ + # 外循环:base = nums[1], nums[2], ..., nums[n-1] for i in range(1, len(nums)): base = nums[i] j = i - 1 diff --git a/chapter_sorting/merge_sort.md b/chapter_sorting/merge_sort.md index 8007cc934..13fda8892 100755 --- a/chapter_sorting/merge_sort.md +++ b/chapter_sorting/merge_sort.md @@ -146,10 +146,10 @@ comments: true === "Python" ```python title="merge_sort.py" - """ 合并左子数组和右子数组 """ - # 左子数组区间 [left, mid] - # 右子数组区间 [mid + 1, right] def merge(nums, left, mid, right): + """ 合并左子数组和右子数组 """ + # 左子数组区间 [left, mid] + # 右子数组区间 [mid + 1, right] # 初始化辅助数组 借助 copy模块 tmp = nums[left:right + 1] # 左子数组的起始索引和结束索引 @@ -173,8 +173,8 @@ comments: true nums[k] = tmp[j] j += 1 - """ 归并排序 """ def merge_sort(nums, left, right): + """ 归并排序 """ # 终止条件 if left >= right: return # 当子数组长度为 1 时终止递归 diff --git a/chapter_sorting/quick_sort.md b/chapter_sorting/quick_sort.md index 734adb0b7..1c132cfa1 100755 --- a/chapter_sorting/quick_sort.md +++ b/chapter_sorting/quick_sort.md @@ -100,8 +100,8 @@ comments: true === "Python" ```python title="quick_sort.py" - """ 哨兵划分 """ def partition(self, nums, left, right): + """ 哨兵划分 """ # 以 nums[left] 作为基准数 i, j = left, right while i < j: @@ -333,8 +333,8 @@ comments: true === "Python" ```python title="quick_sort.py" - """ 快速排序 """ def quick_sort(self, nums, left, right): + """ 快速排序 """ # 子数组长度为 1 时终止递归 if left >= right: return @@ -552,8 +552,8 @@ comments: true === "Python" ```python title="quick_sort.py" - """ 选取三个元素的中位数 """ def median_three(self, nums, left, mid, right): + """ 选取三个元素的中位数 """ # 此处使用异或运算来简化代码 # 异或规则为 0 ^ 0 = 1 ^ 1 = 0, 0 ^ 1 = 1 ^ 0 = 1 if (nums[left] < nums[mid]) ^ (nums[left] < nums[right]): @@ -562,8 +562,8 @@ comments: true return mid return right - """ 哨兵划分(三数取中值) """ def partition(self, nums, left, right): + """ 哨兵划分(三数取中值) """ # 以 nums[left] 作为基准数 med = self.median_three(nums, left, (left + right) // 2, right) # 将中位数交换至数组最左端 @@ -845,8 +845,8 @@ comments: true === "Python" ```python title="quick_sort.py" - """ 快速排序(尾递归优化) """ def quick_sort(self, nums, left, right): + """ 快速排序(尾递归优化) """ # 子数组长度为 1 时终止 while left < right: # 哨兵划分操作 diff --git a/chapter_stack_and_queue/deque.md b/chapter_stack_and_queue/deque.md index 4884c96ad..2ca1db7cf 100644 --- a/chapter_stack_and_queue/deque.md +++ b/chapter_stack_and_queue/deque.md @@ -590,30 +590,31 @@ comments: true === "Python" ```python title="linkedlist_deque.py" - """ 双向链表结点 """ class ListNode: + """ 双向链表结点 """ def __init__(self, val): + """ 构造方法 """ self.val = val self.next = None # 后继结点引用(指针) self.prev = None # 前驱结点引用(指针) - """ 基于双向链表实现的双向队列 """ class LinkedListDeque: - """ 构造方法 """ + """ 基于双向链表实现的双向队列 """ def __init__(self): + """ 构造方法 """ self.front, self.rear = None, None # 头结点 front ,尾结点 rear self.__size = 0 # 双向队列的长度 - """ 获取双向队列的长度 """ def size(self): + """ 获取双向队列的长度 """ return self.__size - """ 判断双向队列是否为空 """ def is_empty(self): + """ 判断双向队列是否为空 """ return self.size() == 0 - """ 入队操作 """ def push(self, num, is_front): + """ 入队操作 """ node = ListNode(num) # 若链表为空,则令 front, rear 都指向 node if self.is_empty(): @@ -632,16 +633,16 @@ comments: true self.rear = node # 更新尾结点 self.__size += 1 # 更新队列长度 - """ 队首入队 """ def push_first(self, num): + """ 队首入队 """ self.push(num, True) - """ 队尾入队 """ def push_last(self, num): + """ 队尾入队 """ self.push(num, False) - """ 出队操作 """ def poll(self, is_front): + """ 出队操作 """ # 若队列为空,直接返回 None if self.is_empty(): return None @@ -666,24 +667,24 @@ comments: true self.__size -= 1 # 更新队列长度 return val - """ 队首出队 """ def poll_first(self): + """ 队首出队 """ return self.poll(True) - """ 队尾出队 """ def poll_last(self): + """ 队尾出队 """ return self.poll(False) - """ 访问队首元素 """ def peek_first(self): + """ 访问队首元素 """ return None if self.is_empty() else self.front.val - """ 访问队尾元素 """ def peek_last(self): + """ 访问队尾元素 """ return None if self.is_empty() else self.rear.val - """ 返回数组用于打印 """ def to_array(self): + """ 返回数组用于打印 """ node = self.front res = [0] * self.size() for i in range(self.size()): @@ -790,106 +791,106 @@ comments: true /* 基于双向链表实现的双向队列 */ class LinkedListDeque { - front; // 头结点 front - rear; // 尾结点 rear - len; // 双向队列的长度 + #front; // 头结点 front + #rear; // 尾结点 rear + #queSize; // 双向队列的长度 constructor() { - this.front = null; - this.rear = null; - this.len = 0; + this.#front = null; + this.#rear = null; + this.#queSize = 0; } /* 队尾入队操作 */ pushLast(val) { const node = new ListNode(val); // 若链表为空,则令 front, rear 都指向 node - if (this.len === 0) { - this.front = node; - this.rear = node; + if (this.#queSize === 0) { + this.#front = node; + this.#rear = node; } else { // 将 node 添加至链表尾部 - this.rear.next = node; - node.prev = this.rear; - this.rear = node; // 更新尾结点 + this.#rear.next = node; + node.prev = this.#rear; + this.#rear = node; // 更新尾结点 } - this.len++; + this.#queSize++; } /* 队首入队操作 */ pushFirst(val) { const node = new ListNode(val); // 若链表为空,则令 front, rear 都指向 node - if (this.len === 0) { - this.front = node; - this.rear = node; + if (this.#queSize === 0) { + this.#front = node; + this.#rear = node; } else { // 将 node 添加至链表头部 - this.front.prev = node; - node.next = this.front; - this.front = node; // 更新头结点 + this.#front.prev = node; + node.next = this.#front; + this.#front = node; // 更新头结点 } - this.len++; + this.#queSize++; } /* 队尾出队操作 */ pollLast() { - if (this.len === 0) { + if (this.#queSize === 0) { return null; } - const value = this.rear.val; // 存储尾结点值 + const value = this.#rear.val; // 存储尾结点值 // 删除尾结点 - let temp = this.rear.prev; + let temp = this.#rear.prev; if (temp !== null) { temp.next = null; - this.rear.prev = null; + this.#rear.prev = null; } - this.rear = temp; // 更新尾结点 - this.len--; + this.#rear = temp; // 更新尾结点 + this.#queSize--; return value; } /* 队首出队操作 */ pollFirst() { - if (this.len === 0) { + if (this.#queSize === 0) { return null; } - const value = this.front.val; // 存储尾结点值 + const value = this.#front.val; // 存储尾结点值 // 删除头结点 - let temp = this.front.next; + let temp = this.#front.next; if (temp !== null) { temp.prev = null; - this.front.next = null; + this.#front.next = null; } - this.front = temp; // 更新头结点 - this.len--; + this.#front = temp; // 更新头结点 + this.#queSize--; return value; } /* 访问队尾元素 */ peekLast() { - return this.len === 0 ? null : this.rear.val; + return this.#queSize === 0 ? null : this.#rear.val; } /* 访问队首元素 */ peekFirst() { - return this.len === 0 ? null : this.front.val; + return this.#queSize === 0 ? null : this.#front.val; } /* 获取双向队列的长度 */ size() { - return this.len; + return this.#queSize; } /* 判断双向队列是否为空 */ isEmpty() { - return this.len === 0; + return this.#queSize === 0; } /* 打印双向队列 */ print() { const arr = []; - let temp = this.front; + let temp = this.#front; while (temp !== null) { arr.push(temp.val); temp = temp.next; @@ -917,21 +918,21 @@ comments: true /* 基于双向链表实现的双向队列 */ class LinkedListDeque { - front: ListNode; // 头结点 front - rear: ListNode; // 尾结点 rear - len: number; // 双向队列的长度 + private front: ListNode; // 头结点 front + private rear: ListNode; // 尾结点 rear + private queSize: number; // 双向队列的长度 constructor() { this.front = null; this.rear = null; - this.len = 0; + this.queSize = 0; } /* 队尾入队操作 */ pushLast(val: number): void { const node: ListNode = new ListNode(val); // 若链表为空,则令 front, rear 都指向 node - if (this.len === 0) { + if (this.queSize === 0) { this.front = node; this.rear = node; } else { @@ -940,14 +941,14 @@ comments: true node.prev = this.rear; this.rear = node; // 更新尾结点 } - this.len++; + this.queSize++; } /* 队首入队操作 */ pushFirst(val: number): void { const node: ListNode = new ListNode(val); // 若链表为空,则令 front, rear 都指向 node - if (this.len === 0) { + if (this.queSize === 0) { this.front = node; this.rear = node; } else { @@ -956,12 +957,12 @@ comments: true node.next = this.front; this.front = node; // 更新头结点 } - this.len++; + this.queSize++; } /* 队尾出队操作 */ pollLast(): number { - if (this.len === 0) { + if (this.queSize === 0) { return null; } const value: number = this.rear.val; // 存储尾结点值 @@ -972,13 +973,13 @@ comments: true this.rear.prev = null; } this.rear = temp; // 更新尾结点 - this.len--; + this.queSize--; return value; } /* 队首出队操作 */ pollFirst(): number { - if (this.len === 0) { + if (this.queSize === 0) { return null; } const value: number = this.front.val; // 存储尾结点值 @@ -989,28 +990,28 @@ comments: true this.front.next = null; } this.front = temp; // 更新头结点 - this.len--; + this.queSize--; return value; } /* 访问队尾元素 */ peekLast(): number { - return this.len === 0 ? null : this.rear.val; + return this.queSize === 0 ? null : this.rear.val; } /* 访问队首元素 */ peekFirst(): number { - return this.len === 0 ? null : this.front.val; + return this.queSize === 0 ? null : this.front.val; } /* 获取双向队列的长度 */ size(): number { - return this.len; + return this.queSize; } /* 判断双向队列是否为空 */ isEmpty(): boolean { - return this.len === 0; + return this.queSize === 0; } /* 打印双向队列 */ @@ -1593,35 +1594,35 @@ comments: true === "Python" ```python title="array_deque.py" - """ 基于环形数组实现的双向队列 """ class ArrayDeque: - """ 构造方法 """ + """ 基于环形数组实现的双向队列 """ def __init__(self, capacity): + """ 构造方法 """ self.nums = [0] * capacity self.front = 0 self.que_size = 0 - """ 获取双向队列的容量 """ def capacity(self): + """ 获取双向队列的容量 """ return len(self.nums) - """ 获取双向队列的长度 """ def size(self): + """ 获取双向队列的长度 """ return self.que_size - """ 判断双向队列是否为空 """ def is_empty(self): + """ 判断双向队列是否为空 """ return self.que_size == 0 - """ 计算环形数组索引 """ def index(self, i): + """ 计算环形数组索引 """ # 通过取余操作实现数组首尾相连 # 当 i 越过数组尾部后,回到头部 # 当 i 越过数组头部后,回到尾部 return (i + self.capacity()) % self.capacity() - """ 队首入队 """ def push_first(self, num): + """ 队首入队 """ if self.que_size == self.capacity(): print("双向队列已满") return @@ -1632,8 +1633,8 @@ comments: true self.nums[self.front] = num self.que_size += 1 - """ 队尾入队 """ def push_last(self, num): + """ 队尾入队 """ if self.que_size == self.capacity(): print("双向队列已满") return @@ -1643,34 +1644,34 @@ comments: true self.nums[rear] = num self.que_size += 1 - """ 队首出队 """ def poll_first(self): + """ 队首出队 """ num = self.peek_first() # 队首指针向后移动一位 self.front = self.index(self.front+1) self.que_size -= 1 return num - """ 队尾出队 """ def poll_last(self): + """ 队尾出队 """ num = self.peek_last() self.que_size -= 1 return num - """ 访问队首元素 """ def peek_first(self): + """ 访问队首元素 """ assert not self.is_empty(), "双向队列为空" return self.nums[self.front] - """ 访问队尾元素 """ def peek_last(self): + """ 访问队尾元素 """ assert not self.is_empty(), "双向队列为空" # 计算尾元素索引 last = self.index(self.front + self.que_size - 1) return self.nums[last] - """ 返回数组用于打印 """ def to_array(self): + """ 返回数组用于打印 """ # 仅转换有效长度范围内的列表元素 res = [] for i in range(self.que_size): diff --git a/chapter_stack_and_queue/queue.md b/chapter_stack_and_queue/queue.md index 3c5f5cc3a..3ea0e687a 100755 --- a/chapter_stack_and_queue/queue.md +++ b/chapter_stack_and_queue/queue.md @@ -429,23 +429,24 @@ comments: true === "Python" ```python title="linkedlist_queue.py" - """ 基于链表实现的队列 """ class LinkedListQueue: + """ 基于链表实现的队列 """ def __init__(self): + """ 构造方法 """ self.__front = None # 头结点 front self.__rear = None # 尾结点 rear self.__size = 0 - """ 获取队列的长度 """ def size(self): + """ 获取队列的长度 """ return self.__size - """ 判断队列是否为空 """ def is_empty(self): + """ 判断队列是否为空 """ return not self.__front - """ 入队 """ def push(self, num): + """ 入队 """ # 尾结点后添加 num node = ListNode(num) # 如果队列为空,则令头、尾结点都指向该结点 @@ -458,23 +459,23 @@ comments: true self.__rear = node self.__size += 1 - """ 出队 """ def poll(self): + """ 出队 """ num = self.peek() # 删除头结点 self.__front = self.__front.next self.__size -= 1 return num - """ 访问队首元素 """ def peek(self): + """ 访问队首元素 """ if self.size() == 0: print("队列为空") return False return self.__front.val - """ 转化为列表用于打印 """ def to_list(self): + """ 转化为列表用于打印 """ queue = [] temp = self.__front while temp: @@ -614,7 +615,7 @@ comments: true /* 基于链表实现的队列 */ class LinkedListQueue { private front: ListNode | null; // 头结点 front - private rear: ListNode | null; // 尾结点 rear + private rear: ListNode | null; // 尾结点 rear private queSize: number = 0; constructor() { @@ -651,8 +652,7 @@ comments: true /* 出队 */ poll(): number { const num = this.peek(); - if (!this.front) - throw new Error("队列为空") + if (!this.front) throw new Error('队列为空'); // 删除头结点 this.front = this.front.next; this.queSize--; @@ -661,8 +661,7 @@ comments: true /* 访问队首元素 */ peek(): number { - if (this.size === 0) - throw new Error("队列为空"); + if (this.size === 0) throw new Error('队列为空'); return this.front!.val; } @@ -1105,27 +1104,28 @@ comments: true === "Python" ```python title="array_queue.py" - """ 基于环形数组实现的队列 """ class ArrayQueue: + """ 基于环形数组实现的队列 """ def __init__(self, size): + """ 构造方法 """ self.__nums = [0] * size # 用于存储队列元素的数组 self.__front = 0 # 队首指针,指向队首元素 self.__size = 0 # 队列长度 - """ 获取队列的容量 """ def capacity(self): + """ 获取队列的容量 """ return len(self.__nums) - """ 获取队列的长度 """ def size(self): + """ 获取队列的长度 """ return self.__size - """ 判断队列是否为空 """ def is_empty(self): + """ 判断队列是否为空 """ return self.__size == 0 - """ 入队 """ def push(self, num): + """ 入队 """ assert self.__size < self.capacity(), "队列已满" # 计算尾指针,指向队尾索引 + 1 # 通过取余操作,实现 rear 越过数组尾部后回到头部 @@ -1134,21 +1134,21 @@ comments: true self.__nums[rear] = num self.__size += 1 - """ 出队 """ def poll(self): + """ 出队 """ num = self.peek() # 队首指针向后移动一位,若越过尾部则返回到数组头部 self.__front = (self.__front + 1) % self.capacity() self.__size -= 1 return num - """ 访问队首元素 """ def peek(self): + """ 访问队首元素 """ assert not self.is_empty(), "队列为空" return self.__nums[self.__front] - """ 返回列表用于打印 """ def to_list(self): + """ 返回列表用于打印 """ res = [0] * self.size() j = self.__front for i in range(self.size()): diff --git a/chapter_stack_and_queue/stack.md b/chapter_stack_and_queue/stack.md index 86cf65648..25664dee1 100755 --- a/chapter_stack_and_queue/stack.md +++ b/chapter_stack_and_queue/stack.md @@ -410,42 +410,43 @@ comments: true === "Python" ```python title="linkedlist_stack.py" - """ 基于链表实现的栈 """ class LinkedListStack: + """ 基于链表实现的栈 """ def __init__(self): + """ 构造方法 """ self.__peek = None self.__size = 0 - """ 获取栈的长度 """ def size(self): + """ 获取栈的长度 """ return self.__size - """ 判断栈是否为空 """ def is_empty(self): + """ 判断栈是否为空 """ return not self.__peek - """ 入栈 """ def push(self, val): + """ 入栈 """ node = ListNode(val) node.next = self.__peek self.__peek = node self.__size += 1 - """ 出栈 """ def pop(self): + """ 出栈 """ num = self.peek() self.__peek = self.__peek.next self.__size -= 1 return num - """ 访问栈顶元素 """ def peek(self): + """ 访问栈顶元素 """ # 判空处理 if not self.__peek: return None return self.__peek.val - """ 转化为列表用于打印 """ def to_list(self): + """ 转化为列表用于打印 """ arr = [] node = self.__peek while node: @@ -574,8 +575,8 @@ comments: true ```typescript title="linkedlist_stack.ts" /* 基于链表实现的栈 */ class LinkedListStack { - private stackPeek: ListNode | null; // 将头结点作为栈顶 - private stkSize: number = 0; // 栈的长度 + private stackPeek: ListNode | null; // 将头结点作为栈顶 + private stkSize: number = 0; // 栈的长度 constructor() { this.stackPeek = null; @@ -602,8 +603,7 @@ comments: true /* 出栈 */ pop(): number { const num = this.peek(); - if (!this.stackPeek) - throw new Error("栈为空"); + if (!this.stackPeek) throw new Error('栈为空'); this.stackPeek = this.stackPeek.next; this.stkSize--; return num; @@ -611,8 +611,7 @@ comments: true /* 访问栈顶元素 */ peek(): number { - if (!this.stackPeek) - throw new Error("栈为空"); + if (!this.stackPeek) throw new Error('栈为空'); return this.stackPeek.val; } @@ -953,35 +952,36 @@ comments: true === "Python" ```python title="array_stack.py" - """ 基于数组实现的栈 """ class ArrayStack: + """ 基于数组实现的栈 """ def __init__(self): + """ 构造方法 """ self.__stack = [] - """ 获取栈的长度 """ def size(self): + """ 获取栈的长度 """ return len(self.__stack) - """ 判断栈是否为空 """ def is_empty(self): + """ 判断栈是否为空 """ return self.__stack == [] - """ 入栈 """ def push(self, item): + """ 入栈 """ self.__stack.append(item) - """ 出栈 """ def pop(self): + """ 出栈 """ assert not self.is_empty(), "栈为空" return self.__stack.pop() - """ 访问栈顶元素 """ def peek(self): + """ 访问栈顶元素 """ assert not self.is_empty(), "栈为空" return self.__stack[-1] - """ 返回列表用于打印 """ def to_list(self): + """ 返回列表用于打印 """ return self.__stack ``` @@ -1044,43 +1044,43 @@ comments: true ```javascript title="array_stack.js" /* 基于数组实现的栈 */ class ArrayStack { - stack; + #stack; constructor() { - this.stack = []; + this.#stack = []; } /* 获取栈的长度 */ get size() { - return this.stack.length; + return this.#stack.length; } /* 判断栈是否为空 */ empty() { - return this.stack.length === 0; + return this.#stack.length === 0; } /* 入栈 */ push(num) { - this.stack.push(num); + this.#stack.push(num); } /* 出栈 */ pop() { if (this.empty()) throw new Error("栈为空"); - return this.stack.pop(); + return this.#stack.pop(); } /* 访问栈顶元素 */ top() { if (this.empty()) throw new Error("栈为空"); - return this.stack[this.stack.length - 1]; + return this.#stack[this.#stack.length - 1]; } /* 返回 Array */ toArray() { - return this.stack; + return this.#stack; } }; ``` diff --git a/chapter_tree/avl_tree.md b/chapter_tree/avl_tree.md index 1efe0fc74..358d198d5 100644 --- a/chapter_tree/avl_tree.md +++ b/chapter_tree/avl_tree.md @@ -194,15 +194,15 @@ G. M. Adelson-Velsky 和 E. M. Landis 在其 1962 年发表的论文 "An algorit === "Python" ```python title="avl_tree.py" - """ 获取结点高度 """ def height(self, node: Optional[TreeNode]) -> int: + """ 获取结点高度 """ # 空结点高度为 -1 ,叶结点高度为 0 if node is not None: return node.height return -1 - """ 更新结点高度 """ def __update_height(self, node: Optional[TreeNode]): + """ 更新结点高度 """ # 结点高度等于最高子树高度 + 1 node.height = max([self.height(node.left), self.height(node.right)]) + 1 ``` @@ -242,7 +242,7 @@ G. M. Adelson-Velsky 和 E. M. Landis 在其 1962 年发表的论文 "An algorit } /* 更新结点高度 */ - updateHeight(node) { + #updateHeight(node) { // 结点高度等于最高子树高度 + 1 node.height = Math.max(this.height(node.left), this.height(node.right)) + 1; } @@ -354,8 +354,8 @@ G. M. Adelson-Velsky 和 E. M. Landis 在其 1962 年发表的论文 "An algorit === "Python" ```python title="avl_tree.py" - """ 获取平衡因子 """ def balance_factor(self, node: Optional[TreeNode]) -> int: + """ 获取平衡因子 """ # 空结点平衡因子为 0 if node is None: return 0 @@ -517,8 +517,8 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影 === "Python" ```python title="avl_tree.py" - """ 右旋操作 """ def __right_rotate(self, node: Optional[TreeNode]) -> TreeNode: + """ 右旋操作 """ child = node.left grand_child = child.right # 以 child 为原点,将 node 向右旋转 @@ -553,15 +553,15 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影 ```javascript title="avl_tree.js" /* 右旋操作 */ - rightRotate(node) { + #rightRotate(node) { const child = node.left; const grandChild = child.right; // 以 child 为原点,将 node 向右旋转 child.right = node; node.left = grandChild; // 更新结点高度 - this.updateHeight(node); - this.updateHeight(child); + this.#updateHeight(node); + this.#updateHeight(child); // 返回旋转后子树的根结点 return child; } @@ -701,8 +701,8 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影 === "Python" ```python title="avl_tree.py" - """ 左旋操作 """ def __left_rotate(self, node: Optional[TreeNode]) -> TreeNode: + """ 左旋操作 """ child = node.right grand_child = child.left # 以 child 为原点,将 node 向左旋转 @@ -737,15 +737,15 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影 ```javascript title="avl_tree.js" /* 左旋操作 */ - leftRotate(node) { + #leftRotate(node) { const child = node.right; const grandChild = child.left; // 以 child 为原点,将 node 向左旋转 child.left = node; node.right = grandChild; // 更新结点高度 - this.updateHeight(node); - this.updateHeight(child); + this.#updateHeight(node); + this.#updateHeight(child); // 返回旋转后子树的根结点 return child; } @@ -940,8 +940,8 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影 === "Python" ```python title="avl_tree.py" - """ 执行旋转操作,使该子树重新恢复平衡 """ def __rotate(self, node: Optional[TreeNode]) -> TreeNode: + """ 执行旋转操作,使该子树重新恢复平衡 """ # 获取结点 node 的平衡因子 balance_factor = self.balance_factor(node) # 左偏树 @@ -1005,29 +1005,29 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影 ```javascript title="avl_tree.js" /* 执行旋转操作,使该子树重新恢复平衡 */ - rotate(node) { + #rotate(node) { // 获取结点 node 的平衡因子 const balanceFactor = this.balanceFactor(node); // 左偏树 if (balanceFactor > 1) { if (this.balanceFactor(node.left) >= 0) { // 右旋 - return this.rightRotate(node); + return this.#rightRotate(node); } else { // 先左旋后右旋 - node.left = this.leftRotate(node.left); - return this.rightRotate(node); + node.left = this.#leftRotate(node.left); + return this.#rightRotate(node); } } // 右偏树 if (balanceFactor < -1) { if (this.balanceFactor(node.right) <= 0) { // 左旋 - return this.leftRotate(node); + return this.#leftRotate(node); } else { // 先右旋后左旋 - node.right = this.rightRotate(node.right); - return this.leftRotate(node); + node.right = this.#rightRotate(node.right); + return this.#leftRotate(node); } } // 平衡树,无需旋转,直接返回 @@ -1249,13 +1249,13 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影 === "Python" ```python title="avl_tree.py" - """ 插入结点 """ def insert(self, val) -> TreeNode: + """ 插入结点 """ self.root = self.__insert_helper(self.root, val) return self.root - """ 递归插入结点(辅助方法)""" def __insert_helper(self, node: Optional[TreeNode], val: int) -> TreeNode: + """ 递归插入结点(辅助方法)""" if node is None: return TreeNode(val) # 1. 查找插入位置,并插入结点 @@ -1309,20 +1309,20 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影 ```javascript title="avl_tree.js" /* 插入结点 */ insert(val) { - this.root = this.insertHelper(this.root, val); + this.root = this.#insertHelper(this.root, val); return this.root; } /* 递归插入结点(辅助方法) */ - insertHelper(node, val) { + #insertHelper(node, val) { if (node === null) return new TreeNode(val); /* 1. 查找插入位置,并插入结点 */ - if (val < node.val) node.left = this.insertHelper(node.left, val); - else if (val > node.val) node.right = this.insertHelper(node.right, val); + if (val < node.val) node.left = this.#insertHelper(node.left, val); + else if (val > node.val) node.right = this.#insertHelper(node.right, val); else return node; // 重复结点不插入,直接返回 - this.updateHeight(node); // 更新结点高度 + this.#updateHeight(node); // 更新结点高度 /* 2. 执行旋转操作,使该子树重新恢复平衡 */ - node = this.rotate(node); + node = this.#rotate(node); // 返回子树的根结点 return node; } @@ -1571,13 +1571,13 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影 === "Python" ```python title="avl_tree.py" - """ 删除结点 """ def remove(self, val: int): + """ 删除结点 """ root = self.__remove_helper(self.root, val) return root - """ 递归删除结点(辅助方法) """ def __remove_helper(self, node: Optional[TreeNode], val: int) -> Optional[TreeNode]: + """ 递归删除结点(辅助方法) """ if node is None: return None # 1. 查找结点,并删除之 @@ -1603,8 +1603,8 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影 # 2. 执行旋转操作,使该子树重新恢复平衡 return self.__rotate(node) - """ 获取中序遍历中的下一个结点(仅适用于 root 有左子结点的情况) """ def __get_inorder_next(self, node: Optional[TreeNode]) -> Optional[TreeNode]: + """ 获取中序遍历中的下一个结点(仅适用于 root 有左子结点的情况) """ if node is None: return None # 循环访问左子结点,直到叶结点时为最小结点,跳出 @@ -1678,16 +1678,16 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影 ```javascript title="avl_tree.js" /* 删除结点 */ remove(val) { - this.root = this.removeHelper(this.root, val); + this.root = this.#removeHelper(this.root, val); return this.root; } /* 递归删除结点(辅助方法) */ - removeHelper(node, val) { + #removeHelper(node, val) { if (node === null) return null; /* 1. 查找结点,并删除之 */ - if (val < node.val) node.left = this.removeHelper(node.left, val); - else if (val > node.val) node.right = this.removeHelper(node.right, val); + if (val < node.val) node.left = this.#removeHelper(node.left, val); + else if (val > node.val) node.right = this.#removeHelper(node.right, val); else { if (node.left === null || node.right === null) { const child = node.left !== null ? node.left : node.right; @@ -1697,20 +1697,20 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影 else node = child; } else { // 子结点数量 = 2 ,则将中序遍历的下个结点删除,并用该结点替换当前结点 - const temp = this.getInOrderNext(node.right); - node.right = this.removeHelper(node.right, temp.val); + const temp = this.#getInOrderNext(node.right); + node.right = this.#removeHelper(node.right, temp.val); node.val = temp.val; } } - this.updateHeight(node); // 更新结点高度 + this.#updateHeight(node); // 更新结点高度 /* 2. 执行旋转操作,使该子树重新恢复平衡 */ - node = this.rotate(node); + node = this.#rotate(node); // 返回子树的根结点 return node; } /* 获取中序遍历中的下一个结点(仅适用于 root 有左子结点的情况) */ - getInOrderNext(node) { + #getInOrderNext(node) { if (node === null) return node; // 循环访问左子结点,直到叶结点时为最小结点,跳出 while (node.left !== null) { @@ -1745,7 +1745,7 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影 return null; } else { // 子结点数量 = 1 ,直接删除 node - node = child; + node = child; } } else { // 子结点数量 = 2 ,则将中序遍历的下个结点删除,并用该结点替换当前结点 diff --git a/chapter_tree/binary_search_tree.md b/chapter_tree/binary_search_tree.md index 19072e9f4..2dc441ac2 100755 --- a/chapter_tree/binary_search_tree.md +++ b/chapter_tree/binary_search_tree.md @@ -80,8 +80,8 @@ comments: true === "Python" ```python title="binary_search_tree.py" - """ 查找结点 """ def search(self, num: int) -> Optional[TreeNode]: + """ 查找结点 """ cur = self.root # 循环查找,越过叶结点后跳出 while cur is not None: @@ -308,8 +308,8 @@ comments: true === "Python" ```python title="binary_search_tree.py" - """ 插入结点 """ def insert(self, num: int) -> Optional[TreeNode]: + """ 插入结点 """ root = self.root # 若树为空,直接提前返回 if root is None: @@ -392,7 +392,7 @@ comments: true else cur = cur.left; } // 插入结点 val - let node = new Tree.TreeNode(num); + let node = new TreeNode(num); if (pre.val < num) pre.right = node; else pre.left = node; return node; @@ -692,8 +692,8 @@ comments: true === "Python" ```python title="binary_search_tree.py" - """ 删除结点 """ def remove(self, num: int) -> Optional[TreeNode]: + """ 删除结点 """ root = self.root # 若树为空,直接提前返回 if root is None: @@ -734,8 +734,8 @@ comments: true cur.val = tmp return cur - """ 获取中序遍历中的下一个结点(仅适用于 root 有左子结点的情况) """ def get_inorder_next(self, root: Optional[TreeNode]) -> Optional[TreeNode]: + """ 获取中序遍历中的下一个结点(仅适用于 root 有左子结点的情况) """ if root is None: return root # 循环访问左子结点,直到叶结点时为最小结点,跳出 diff --git a/chapter_tree/binary_tree_traversal.md b/chapter_tree/binary_tree_traversal.md index 15ca018af..a9ec83083 100755 --- a/chapter_tree/binary_tree_traversal.md +++ b/chapter_tree/binary_tree_traversal.md @@ -69,8 +69,8 @@ comments: true === "Python" ```python title="binary_tree_bfs.py" - """ 层序遍历 """ def level_order(root: Optional[TreeNode]): + """ 层序遍历 """ # 初始化队列,加入根结点 queue = collections.deque() queue.append(root) @@ -120,9 +120,9 @@ comments: true /* 层序遍历 */ function levelOrder(root) { // 初始化队列,加入根结点 - let queue = [root]; + const queue = [root]; // 初始化一个列表,用于保存遍历序列 - let list = []; + const list = []; while (queue.length) { let node = queue.shift(); // 队列出队 list.push(node.val); // 保存结点值 @@ -337,8 +337,8 @@ comments: true === "Python" ```python title="binary_tree_dfs.py" - """ 前序遍历 """ def pre_order(root: Optional[TreeNode]): + """ 前序遍历 """ if root is None: return # 访问优先级:根结点 -> 左子树 -> 右子树 @@ -346,8 +346,8 @@ comments: true pre_order(root=root.left) pre_order(root=root.right) - """ 中序遍历 """ def in_order(root: Optional[TreeNode]): + """ 中序遍历 """ if root is None: return # 访问优先级:左子树 -> 根结点 -> 右子树 @@ -355,8 +355,8 @@ comments: true res.append(root.val) in_order(root=root.right) - """ 后序遍历 """ def post_order(root: Optional[TreeNode]): + """ 后序遍历 """ if root is None: return # 访问优先级:左子树 -> 右子树 -> 根结点