diff --git a/chapter_array_and_linkedlist/array.md b/chapter_array_and_linkedlist/array.md index 2843c2211..4c986d422 100755 --- a/chapter_array_and_linkedlist/array.md +++ b/chapter_array_and_linkedlist/array.md @@ -494,7 +494,7 @@ elementAddr = firtstElementAddr + elementLength * elementIndex === "Python" ```python title="array.py" - def insert(nums: list[int], num: int, index: int) -> None: + def insert(nums: list[int], num: int, index: int): """在数组的索引 index 处插入元素 num""" # 把索引 index 以及之后的所有元素向后移动一位 for i in range(len(nums) - 1, index, -1): @@ -649,7 +649,7 @@ elementAddr = firtstElementAddr + elementLength * elementIndex === "Python" ```python title="array.py" - def remove(nums: list[int], index: int) -> None: + def remove(nums: list[int], index: int): """删除索引 index 处元素""" # 把索引 index 之后的所有元素向前移动一位 for i in range(index, len(nums) - 1): @@ -798,7 +798,7 @@ elementAddr = firtstElementAddr + elementLength * elementIndex === "Python" ```python title="array.py" - def traverse(nums: list[int]) -> None: + def traverse(nums: list[int]): """遍历数组""" count = 0 # 通过索引遍历数组 diff --git a/chapter_array_and_linkedlist/linked_list.md b/chapter_array_and_linkedlist/linked_list.md index b34d5f694..7e99e9e13 100755 --- a/chapter_array_and_linkedlist/linked_list.md +++ b/chapter_array_and_linkedlist/linked_list.md @@ -117,8 +117,7 @@ comments: true ```csharp title="" /* 链表节点类 */ - class ListNode - { + class ListNode { int val; // 节点值 ListNode next; // 指向下一节点的引用 ListNode(int x) => val = x; //构造函数 @@ -400,7 +399,7 @@ comments: true === "Python" ```python title="linked_list.py" - def insert(n0: ListNode, P: ListNode) -> None: + def insert(n0: ListNode, P: ListNode): """在链表的节点 n0 之后插入节点 P""" n1 = n0.next P.next = n1 @@ -534,7 +533,7 @@ comments: true === "Python" ```python title="linked_list.py" - def remove(n0: ListNode) -> None: + def remove(n0: ListNode): """删除链表的节点 n0 之后的首个节点""" if not n0.next: return diff --git a/chapter_array_and_linkedlist/list.md b/chapter_array_and_linkedlist/list.md index b6eedf3d3..5dd12b9fa 100755 --- a/chapter_array_and_linkedlist/list.md +++ b/chapter_array_and_linkedlist/list.md @@ -543,15 +543,13 @@ comments: true ```csharp title="list.cs" /* 通过索引遍历列表 */ int count = 0; - for (int i = 0; i < list.Count(); i++) - { + for (int i = 0; i < list.Count; i++) { count++; } /* 直接遍历列表元素 */ count = 0; - foreach (int n in list) - { + foreach (int n in list) { count++; } ``` @@ -1029,13 +1027,13 @@ comments: true raise IndexError("索引越界") return self.__nums[index] - def set(self, num: int, index: int) -> None: + def set(self, num: int, index: int): """更新元素""" if index < 0 or index >= self.__size: raise IndexError("索引越界") self.__nums[index] = num - def add(self, num: int) -> None: + def add(self, num: int): """尾部添加元素""" # 元素数量超出容量时,触发扩容机制 if self.size() == self.capacity(): @@ -1043,7 +1041,7 @@ comments: true self.__nums[self.__size] = num self.__size += 1 - def insert(self, num: int, index: int) -> None: + def insert(self, num: int, index: int): """中间插入元素""" if index < 0 or index >= self.__size: raise IndexError("索引越界") @@ -1070,7 +1068,7 @@ comments: true # 返回被删除元素 return num - def extend_capacity(self) -> None: + def extend_capacity(self): """列表扩容""" # 新建一个长度为原数组 __extend_ratio 倍的新数组,并将原数组拷贝到新数组 self.__nums = self.__nums + [0] * self.capacity() * (self.__extend_ratio - 1) @@ -1583,7 +1581,7 @@ comments: true /* 列表扩容 */ public void extendCapacity() { // 新建一个长度为 numsCapacity * extendRatio 的数组,并将原数组拷贝到新数组 - System.Array.Resize(ref nums, numsCapacity * extendRatio); + Array.Resize(ref nums, numsCapacity * extendRatio); // 更新列表容量 numsCapacity = nums.Length; } diff --git a/chapter_backtracking/backtracking_algorithm.md b/chapter_backtracking/backtracking_algorithm.md index 3b3fccaca..b323008bf 100644 --- a/chapter_backtracking/backtracking_algorithm.md +++ b/chapter_backtracking/backtracking_algorithm.md @@ -51,7 +51,7 @@ comments: true === "Python" ```python title="preorder_traversal_i_compact.py" - def pre_order(root: TreeNode) -> None: + def pre_order(root: TreeNode): """前序遍历:例题一""" if root is None: return @@ -228,7 +228,7 @@ comments: true === "Python" ```python title="preorder_traversal_ii_compact.py" - def pre_order(root: TreeNode) -> None: + def pre_order(root: TreeNode): """前序遍历:例题二""" if root is None: return @@ -413,12 +413,9 @@ comments: true !!! question "例题三" - 在二叉树中搜索所有值为 $7$ 的节点,请返回根节点到这些节点的路径,**要求路径中只存在一个值为 $7$ 的节点,并且不允许有值为 $3$ 的节点**。 + 在二叉树中搜索所有值为 $7$ 的节点,请返回根节点到这些节点的路径,**并要求路径中不包含值为 $3$ 的节点**。 -在例题二的基础上添加剪枝操作,包括: - -- 当遇到值为 $7$ 的节点时,记录解并返回,停止搜索。 -- 当遇到值为 $3$ 的节点时,则直接返回,停止搜索。 +为了满足以上约束条件,**我们需要添加剪枝操作**:在搜索过程中,若遇到值为 $3$ 的节点,则提前返回,停止继续搜索。 === "Java" @@ -471,7 +468,7 @@ comments: true === "Python" ```python title="preorder_traversal_iii_compact.py" - def pre_order(root: TreeNode) -> None: + def pre_order(root: TreeNode): """前序遍历:例题三""" # 剪枝 if root is None or root.val == 3: @@ -631,30 +628,13 @@ comments: true [class]{}-[func]{preOrder} ``` -剪枝是一个非常形象的名词。在搜索过程中,**我们利用约束条件“剪掉”了不满足约束条件的搜索分支**,避免许多无意义的尝试,从而提升搜索效率。 +剪枝是一个非常形象的名词。在搜索过程中,**我们“剪掉”了不满足约束条件的搜索分支**,避免许多无意义的尝试,从而实现搜索效率的提高。 ![根据约束条件剪枝](backtracking_algorithm.assets/preorder_find_constrained_paths.png)

Fig. 根据约束条件剪枝

-## 13.1.3.   常用术语 - -为了更清晰地分析算法问题,我们总结一下回溯算法中常用术语的含义,并对照例题三给出对应示例。 - -| 名词 | 定义 | 例题三 | -| ------------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------- | -| 解 Solution | 解是满足问题特定条件的答案,可能有一个或多个 | 根节点到节点 $7$ 的满足约束条件的所有路径 | -| 约束条件 Constraint | 约束条件是问题中限制解的可行性的条件,通常用于剪枝 | 路径中不包含节点 $3$ ,只包含一个节点 $7$ | -| 状态 State | 状态表示问题在某一时刻的情况,包括已经做出的选择 | 当前已访问的节点路径,即 `path` 节点列表 | -| 尝试 Attempt | 尝试是根据可用选择来探索解空间的过程,包括做出选择,更新状态,检查是否为解 | 递归访问左(右)子节点,将节点添加进 `path` ,判断节点的值是否为 $7$ | -| 回退 Backtracking | 回退指遇到不满足约束条件的状态时,撤销前面做出的选择,回到上一个状态 | 当越过叶结点、结束结点访问、遇到值为 $3$ 的节点时终止搜索,函数返回 | -| 剪枝 Pruning | 剪枝是根据问题特性和约束条件避免无意义的搜索路径的方法,可提高搜索效率 | 当遇到值为 $3$ 的节点时,则终止继续搜索 | - -!!! tip - - 问题、解、状态等概念是通用的,在分治、回溯、动态规划、贪心等算法中都有涉及。 - -## 13.1.4.   框架代码 +## 13.1.3.   框架代码 接下来,我们尝试将回溯的“尝试、回退、剪枝”的主体框架提炼出来,提升代码的通用性。 @@ -669,6 +649,7 @@ comments: true if (isSolution(state)) { // 记录解 recordSolution(state, res); + // 停止继续搜索 return; } // 遍历所有选择 @@ -694,6 +675,7 @@ comments: true if (isSolution(state)) { // 记录解 recordSolution(state, res); + // 停止继续搜索 return; } // 遍历所有选择 @@ -713,12 +695,13 @@ comments: true === "Python" ```python title="" - def backtrack(state: State, choices: list[choice], res: list[state]) -> None: + def backtrack(state: State, choices: list[choice], res: list[state]): """回溯算法框架""" # 判断是否为解 if is_solution(state): # 记录解 record_solution(state, res) + # 停止继续搜索 return # 遍历所有选择 for choice in choices: @@ -740,6 +723,7 @@ comments: true if isSolution(state) { // 记录解 recordSolution(state, res) + // 停止继续搜索 return } // 遍历所有选择 @@ -765,6 +749,7 @@ comments: true if (isSolution(state)) { // 记录解 recordSolution(state, res); + // 停止继续搜索 return; } // 遍历所有选择 @@ -790,6 +775,7 @@ comments: true if (isSolution(state)) { // 记录解 recordSolution(state, res); + // 停止继续搜索 return; } // 遍历所有选择 @@ -815,6 +801,7 @@ comments: true if (isSolution(state)) { // 记录解 recordSolution(state, res, numRes); + // 停止继续搜索 return; } // 遍历所有选择 @@ -840,6 +827,7 @@ comments: true if (isSolution(state)) { // 记录解 recordSolution(state, res); + // 停止继续搜索 return; } // 遍历所有选择 @@ -865,6 +853,7 @@ comments: true if isSolution(state: state) { // 记录解 recordSolution(state: state, res: &res) + // 停止继续搜索 return } // 遍历所有选择 @@ -896,6 +885,7 @@ comments: true if (isSolution(state)) { // 记录解 recordSolution(state, res); + // 停止继续搜索 return; } // 遍历所有选择 @@ -912,7 +902,7 @@ comments: true } ``` -下面,我们基于框架代码来解决例题三:状态 `state` 为节点遍历路径,选择 `choices` 为当前节点的左子节点和右子节点,结果 `res` 是路径列表。 +接下来,我们基于框架代码来解决例题三。状态 `state` 为节点遍历路径,选择 `choices` 为当前节点的左子节点和右子节点,结果 `res` 是路径列表。 === "Java" @@ -948,7 +938,6 @@ comments: true if (isSolution(state)) { // 记录解 recordSolution(state, res); - return; } // 遍历所有选择 for (TreeNode choice : choices) { @@ -999,7 +988,6 @@ comments: true if (isSolution(state)) { // 记录解 recordSolution(state, res); - return; } // 遍历所有选择 for (TreeNode *choice : choices) { @@ -1048,7 +1036,6 @@ comments: true if is_solution(state): # 记录解 record_solution(state, res) - return # 遍历所有选择 for choice in choices: # 剪枝:检查选择是否合法 @@ -1148,7 +1135,6 @@ comments: true if (isSolution(state)) { // 记录解 recordSolution(state, res); - return; } // 遍历所有选择 for (const choice of choices) { @@ -1203,7 +1189,6 @@ comments: true if (isSolution(state)) { // 记录解 recordSolution(state, res); - return; } // 遍历所有选择 for (const choice of choices) { @@ -1270,7 +1255,6 @@ comments: true if (isSolution(state)) { // 记录解 recordSolution(state, res); - return; } // 遍历所有选择 foreach (TreeNode choice in choices) { @@ -1320,7 +1304,6 @@ comments: true // 检查是否为解 if isSolution(state: state) { recordSolution(state: state, res: &res) - return } // 遍历所有选择 for choice in choices { @@ -1369,7 +1352,30 @@ comments: true [class]{}-[func]{backtrack} ``` -相比基于前序遍历的代码实现,基于回溯算法框架的代码实现虽然显得啰嗦,但通用性更好。实际上,**许多回溯问题都可以在该框架下解决**。我们只需根据具体问题来定义 `state` 和 `choices` ,并实现框架中的各个方法。 +根据题意,当找到值为 7 的节点后应该继续搜索,**因此我们需要将记录解之后的 `return` 语句删除**。下图对比了保留或删除 `return` 语句的搜索过程。 + +![保留与删除 return 的搜索过程对比](backtracking_algorithm.assets/backtrack_remove_return_or_not.png) + +

Fig. 保留与删除 return 的搜索过程对比

+ +相比基于前序遍历的代码实现,基于回溯算法框架的代码实现虽然显得啰嗦,但通用性更好。实际上,**许多回溯问题都可以在该框架下解决**。我们只需根据具体问题来定义 `state` 和 `choices` ,并实现框架中的各个方法即可。 + +## 13.1.4.   常用术语 + +为了更清晰地分析算法问题,我们总结一下回溯算法中常用术语的含义,并对照例题三给出对应示例。 + +| 名词 | 定义 | 例题三 | +| ------------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------- | +| 解 Solution | 解是满足问题特定条件的答案,可能有一个或多个 | 根节点到节点 $7$ 的满足约束条件的所有路径 | +| 约束条件 Constraint | 约束条件是问题中限制解的可行性的条件,通常用于剪枝 | 路径中不包含节点 $3$ ,只包含一个节点 $7$ | +| 状态 State | 状态表示问题在某一时刻的情况,包括已经做出的选择 | 当前已访问的节点路径,即 `path` 节点列表 | +| 尝试 Attempt | 尝试是根据可用选择来探索解空间的过程,包括做出选择,更新状态,检查是否为解 | 递归访问左(右)子节点,将节点添加进 `path` ,判断节点的值是否为 $7$ | +| 回退 Backtracking | 回退指遇到不满足约束条件的状态时,撤销前面做出的选择,回到上一个状态 | 当越过叶结点、结束结点访问、遇到值为 $3$ 的节点时终止搜索,函数返回 | +| 剪枝 Pruning | 剪枝是根据问题特性和约束条件避免无意义的搜索路径的方法,可提高搜索效率 | 当遇到值为 $3$ 的节点时,则终止继续搜索 | + +!!! tip + + 问题、解、状态等概念是通用的,在分治、回溯、动态规划、贪心等算法中都有涉及。 ## 13.1.5.   优势与局限性 diff --git a/chapter_computational_complexity/space_complexity.md b/chapter_computational_complexity/space_complexity.md index cba009a9f..05bebf69a 100755 --- a/chapter_computational_complexity/space_complexity.md +++ b/chapter_computational_complexity/space_complexity.md @@ -206,22 +206,19 @@ comments: true ```csharp title="" /* 类 */ - class Node - { + class Node { int val; Node next; Node(int x) { val = x; } } /* 函数 */ - int function() - { + int function() { // do something... return 0; } - int algorithm(int n) // 输入数据 - { + int algorithm(int n) { // 输入数据 const int a = 0; // 暂存数据(常量) int b = 0; // 暂存数据(变量) Node node = new Node(0); // 暂存数据(对象) @@ -323,7 +320,7 @@ comments: true === "Python" ```python title="" - def algorithm(n: int) -> None: + def algorithm(n: int): a = 0 # O(1) b = [0] * 10000 # O(1) if n > 10: @@ -382,12 +379,10 @@ comments: true === "C#" ```csharp title="" - void algorithm(int n) - { + void algorithm(int n) { int a = 0; // O(1) int[] b = new int[10000]; // O(1) - if (n > 10) - { + if (n > 10) { int[] nums = new int[n]; // O(n) } } @@ -472,7 +467,7 @@ comments: true # do something return 0 - def loop(n: int) -> None: + def loop(n: int): """循环 O(1)""" for _ in range(n): function() @@ -570,22 +565,18 @@ comments: true === "C#" ```csharp title="" - int function() - { + int function() { // do something return 0; } /* 循环 O(1) */ - void loop(int n) - { - for (int i = 0; i < n; i++) - { + void loop(int n) { + for (int i = 0; i < n; i++) { function(); } } /* 递归 O(n) */ - int recur(int n) - { + int recur(int n) { if (n == 1) return 1; return recur(n - 1); } @@ -712,7 +703,7 @@ $$ === "Python" ```python title="space_complexity.py" - def constant(n: int) -> None: + def constant(n: int): """常数阶""" # 常量、变量、对象占用 O(1) 空间 a = 0 @@ -951,7 +942,7 @@ $$ === "Python" ```python title="space_complexity.py" - def linear(n: int) -> None: + def linear(n: int): """线性阶""" # 长度为 n 的列表占用 O(n) 空间 nums = [0] * n @@ -1178,7 +1169,7 @@ $$ === "Python" ```python title="space_complexity.py" - def linear_recur(n: int) -> None: + def linear_recur(n: int): """线性阶(递归实现)""" print("递归 n =", n) if n == 1: @@ -1326,7 +1317,7 @@ $$ === "Python" ```python title="space_complexity.py" - def quadratic(n: int) -> None: + def quadratic(n: int): """平方阶""" # 二维列表占用 O(n^2) 空间 num_matrix = [[0] * n for _ in range(n)] @@ -1568,8 +1559,9 @@ $$ return 0; int *nums = malloc(sizeof(int) * n); printf("递归 n = %d 中的 nums 长度 = %d\r\n", n, n); + int res = quadraticRecur(n - 1) free(nums); - return quadraticRecur(n - 1); + return res; } ``` diff --git a/chapter_computational_complexity/time_complexity.md b/chapter_computational_complexity/time_complexity.md index 01249f8ef..43a4b24cd 100755 --- a/chapter_computational_complexity/time_complexity.md +++ b/chapter_computational_complexity/time_complexity.md @@ -52,7 +52,7 @@ $$ ```python title="" # 在某运行平台下 - def algorithm(n: int) -> None: + def algorithm(n: int): a = 2 # 1 ns a = a + 1 # 1 ns a = a * 2 # 10 ns @@ -66,12 +66,12 @@ $$ ```go title="" // 在某运行平台下 func algorithm(n int) { - a := 2 // 1 ns - a = a + 1 // 1 ns - a = a * 2 // 10 ns + a := 2 // 1 ns + a = a + 1 // 1 ns + a = a * 2 // 10 ns // 循环 n 次 - for i := 0; i < n; i++ { // 1 ns - fmt.Println(a) // 5 ns + for i := 0; i < n; i++ { // 1 ns + fmt.Println(a) // 5 ns } } ``` @@ -125,15 +125,13 @@ $$ ```csharp title="" // 在某运行平台下 - void algorithm(int n) - { + void algorithm(int n) { int a = 2; // 1 ns a = a + 1; // 1 ns a = a * 2; // 10 ns // 循环 n 次 - for (int i = 0; i < n; i++) - { // 1 ns ,每轮都要执行 i++ - Console.WriteLine(0); // 5 ns + for (int i = 0; i < n; i++) { // 1 ns ,每轮都要执行 i++ + Console.WriteLine(0); // 5 ns } } ``` @@ -232,14 +230,14 @@ $$ ```python title="" # 算法 A 时间复杂度:常数阶 - def algorithm_A(n: int) -> None: + def algorithm_A(n: int): print(0) # 算法 B 时间复杂度:线性阶 - def algorithm_B(n: int) -> None: + def algorithm_B(n: int): for _ in range(n): print(0) # 算法 C 时间复杂度:常数阶 - def algorithm_C(n: int) -> None: + def algorithm_C(n: int): for _ in range(1000000): print(0) ``` @@ -333,23 +331,18 @@ $$ ```csharp title="" // 算法 A 时间复杂度:常数阶 - void algorithm_A(int n) - { + void algorithm_A(int n) { Console.WriteLine(0); } // 算法 B 时间复杂度:线性阶 - void algorithm_B(int n) - { - for (int i = 0; i < n; i++) - { + void algorithm_B(int n) { + for (int i = 0; i < n; i++) { Console.WriteLine(0); } } // 算法 C 时间复杂度:常数阶 - void algorithm_C(int n) - { - for (int i = 0; i < 1000000; i++) - { + void algorithm_C(int n) { + for (int i = 0; i < 1000000; i++) { Console.WriteLine(0); } } @@ -456,7 +449,7 @@ $$ === "Python" ```python title="" - def algorithm(n: int) -> None: + def algorithm(n: int): a = 1 # +1 a = a + 1 # +1 a = a * 2 # +1 @@ -524,14 +517,12 @@ $$ === "C#" ```csharp title="" - void algorithm(int n) - { + void algorithm(int n) { int a = 1; // +1 a = a + 1; // +1 a = a * 2; // +1 // 循环 n 次 - for (int i = 0; i < n; i++) // +1(每轮都执行 i ++) - { + for (int i = 0; i < n; i++) { // +1(每轮都执行 i ++) Console.WriteLine(0); // +1 } } @@ -661,7 +652,7 @@ $$ === "Python" ```python title="" - def algorithm(n: int) -> None: + def algorithm(n: int): a = 1 # +0(技巧 1) a = a + n # +0(技巧 1) # +n(技巧 2) @@ -752,20 +743,16 @@ $$ === "C#" ```csharp title="" - void algorithm(int n) - { + void algorithm(int n) { int a = 1; // +0(技巧 1) a = a + n; // +0(技巧 1) // +n(技巧 2) - for (int i = 0; i < 5 * n + 1; i++) - { + for (int i = 0; i < 5 * n + 1; i++) { Console.WriteLine(0); } // +n*n(技巧 3) - for (int i = 0; i < 2 * n; i++) - { - for (int j = 0; j < n + 1; j++) - { + for (int i = 0; i < 2 * n; i++) { + for (int j = 0; j < n + 1; j++) { Console.WriteLine(0); } } @@ -1662,9 +1649,7 @@ $$ for (int j = 0; j < i; j++) { if (nums[j] > nums[j + 1]) { // 交换 nums[j] 与 nums[j + 1] - int tmp = nums[j]; - nums[j] = nums[j + 1]; - nums[j + 1] = tmp; + (nums[j + 1], nums[j]) = (nums[j], nums[j + 1]); count += 3; // 元素交换包含 3 个单元操作 } } diff --git a/chapter_graph/graph_operations.md b/chapter_graph/graph_operations.md index 252cde054..76f34c1a5 100644 --- a/chapter_graph/graph_operations.md +++ b/chapter_graph/graph_operations.md @@ -221,7 +221,7 @@ comments: true # 邻接矩阵,行列索引对应“顶点索引” adj_mat: list[list[int]] = [] - def __init__(self, vertices: list[int], edges: list[list[int]]) -> None: + def __init__(self, vertices: list[int], edges: list[list[int]]): """构造方法""" self.vertices: list[int] = [] self.adj_mat: list[list[int]] = [] @@ -237,7 +237,7 @@ comments: true """获取顶点数量""" return len(self.vertices) - def add_vertex(self, val: int) -> None: + def add_vertex(self, val: int): """添加顶点""" n = self.size() # 向顶点列表中添加新顶点的值 @@ -249,7 +249,7 @@ comments: true for row in self.adj_mat: row.append(0) - def remove_vertex(self, index: int) -> None: + def remove_vertex(self, index: int): """删除顶点""" if index >= self.size(): raise IndexError() @@ -261,7 +261,7 @@ comments: true for row in self.adj_mat: row.pop(index) - def add_edge(self, i: int, j: int) -> None: + def add_edge(self, i: int, j: int): """添加边""" # 参数 i, j 对应 vertices 元素索引 # 索引越界与相等处理 @@ -271,7 +271,7 @@ comments: true self.adj_mat[i][j] = 1 self.adj_mat[j][i] = 1 - def remove_edge(self, i: int, j: int) -> None: + def remove_edge(self, i: int, j: int): """删除边""" # 参数 i, j 对应 vertices 元素索引 # 索引越界与相等处理 @@ -280,7 +280,7 @@ comments: true self.adj_mat[i][j] = 0 self.adj_mat[j][i] = 0 - def print(self) -> None: + def print(self): """打印邻接矩阵""" print("顶点列表 =", self.vertices) print("邻接矩阵 =") @@ -1218,7 +1218,7 @@ comments: true class GraphAdjList: """基于邻接表实现的无向图类""" - def __init__(self, edges: list[list[Vertex]]) -> None: + def __init__(self, edges: list[list[Vertex]]): """构造方法""" # 邻接表,key: 顶点,value:该顶点的所有邻接顶点 self.adj_list = dict[Vertex, Vertex]() @@ -1232,7 +1232,7 @@ comments: true """获取顶点数量""" return len(self.adj_list) - def add_edge(self, vet1: Vertex, vet2: Vertex) -> None: + def add_edge(self, vet1: Vertex, vet2: Vertex): """添加边""" if vet1 not in self.adj_list or vet2 not in self.adj_list or vet1 == vet2: raise ValueError() @@ -1240,7 +1240,7 @@ comments: true self.adj_list[vet1].append(vet2) self.adj_list[vet2].append(vet1) - def remove_edge(self, vet1: Vertex, vet2: Vertex) -> None: + def remove_edge(self, vet1: Vertex, vet2: Vertex): """删除边""" if vet1 not in self.adj_list or vet2 not in self.adj_list or vet1 == vet2: raise ValueError() @@ -1248,14 +1248,14 @@ comments: true self.adj_list[vet1].remove(vet2) self.adj_list[vet2].remove(vet1) - def add_vertex(self, vet: Vertex) -> None: + def add_vertex(self, vet: Vertex): """添加顶点""" if vet in self.adj_list: return # 在邻接表中添加一个新链表 self.adj_list[vet] = [] - def remove_vertex(self, vet: Vertex) -> None: + def remove_vertex(self, vet: Vertex): """删除顶点""" if vet not in self.adj_list: raise ValueError() @@ -1266,7 +1266,7 @@ comments: true if vet in self.adj_list[vertex]: self.adj_list[vertex].remove(vet) - def print(self) -> None: + def print(self): """打印邻接表""" print("邻接表 =") for vertex in self.adj_list: diff --git a/chapter_hashing/hash_collision.md b/chapter_hashing/hash_collision.md index fdc22da3d..538094f31 100644 --- a/chapter_hashing/hash_collision.md +++ b/chapter_hashing/hash_collision.md @@ -1170,7 +1170,7 @@ comments: true if pair not in [None, self.removed]: self.put(pair.key, pair.val) - def print(self) -> None: + def print(self): """打印哈希表""" for pair in self.buckets: if pair is not None: diff --git a/chapter_hashing/hash_map.md b/chapter_hashing/hash_map.md index a26c9bea3..ed2098f61 100755 --- a/chapter_hashing/hash_map.md +++ b/chapter_hashing/hash_map.md @@ -374,18 +374,15 @@ comments: true ```csharp title="hash_map.cs" /* 遍历哈希表 */ // 遍历键值对 Key->Value - foreach (var kv in map) - { + foreach (var kv in map) { Console.WriteLine(kv.Key + " -> " + kv.Value); } // 单独遍历键 key - foreach (int key in map.Keys) - { + foreach (int key in map.Keys) { Console.WriteLine(key); } // 单独遍历值 value - foreach (String val in map.Values) - { + foreach (String val in map.Values) { Console.WriteLine(val); } ``` diff --git a/chapter_searching/replace_linear_by_hashing.md b/chapter_searching/replace_linear_by_hashing.md index 0d65d0ca1..d336feb6f 100755 --- a/chapter_searching/replace_linear_by_hashing.md +++ b/chapter_searching/replace_linear_by_hashing.md @@ -152,7 +152,7 @@ comments: true return new int[] { i, j }; } } - return new int[0]; + return Array.Empty(); } ``` @@ -402,7 +402,7 @@ comments: true } dic.Add(nums[i], i); } - return new int[0]; + return Array.Empty(); } ``` diff --git a/chapter_sorting/bubble_sort.md b/chapter_sorting/bubble_sort.md index 8d5d1bca2..f55a3065a 100755 --- a/chapter_sorting/bubble_sort.md +++ b/chapter_sorting/bubble_sort.md @@ -84,7 +84,7 @@ comments: true === "Python" ```python title="bubble_sort.py" - def bubble_sort(nums: list[int]) -> None: + def bubble_sort(nums: list[int]): """冒泡排序""" n = len(nums) # 外循环:未排序区间为 [0, i] @@ -311,7 +311,7 @@ comments: true === "Python" ```python title="bubble_sort.py" - def bubble_sort_with_flag(nums: list[int]) -> None: + def bubble_sort_with_flag(nums: list[int]): """冒泡排序(标志优化)""" n = len(nums) # 外循环:未排序区间为 [0, i] diff --git a/chapter_sorting/bucket_sort.md b/chapter_sorting/bucket_sort.md index d0a268ca2..0a2caeafa 100644 --- a/chapter_sorting/bucket_sort.md +++ b/chapter_sorting/bucket_sort.md @@ -86,7 +86,7 @@ comments: true === "Python" ```python title="bucket_sort.py" - def bucket_sort(nums: list[float]) -> None: + def bucket_sort(nums: list[float]): """桶排序""" # 初始化 k = n/2 个桶,预期向每个桶分配 2 个元素 k = len(nums) // 2 diff --git a/chapter_sorting/counting_sort.md b/chapter_sorting/counting_sort.md index 0b4f101f5..d8756125f 100644 --- a/chapter_sorting/counting_sort.md +++ b/chapter_sorting/counting_sort.md @@ -75,7 +75,7 @@ comments: true === "Python" ```python title="counting_sort.py" - def counting_sort_naive(nums: list[int]) -> None: + def counting_sort_naive(nums: list[int]): """计数排序""" # 简单实现,无法用于排序对象 # 1. 统计数组最大元素 m @@ -416,7 +416,7 @@ $$ === "Python" ```python title="counting_sort.py" - def counting_sort(nums: list[int]) -> None: + def counting_sort(nums: list[int]): """计数排序""" # 完整实现,可排序对象,并且是稳定排序 # 1. 统计数组最大元素 m diff --git a/chapter_sorting/insertion_sort.md b/chapter_sorting/insertion_sort.md index c6c208691..b351d030e 100755 --- a/chapter_sorting/insertion_sort.md +++ b/chapter_sorting/insertion_sort.md @@ -66,7 +66,7 @@ comments: true === "Python" ```python title="insertion_sort.py" - def insertion_sort(nums: list[int]) -> None: + def insertion_sort(nums: list[int]): """插入排序""" # 外循环:已排序区间为 [0, i-1] for i in range(1, len(nums)): diff --git a/chapter_sorting/merge_sort.md b/chapter_sorting/merge_sort.md index b339803a1..6cc974023 100755 --- a/chapter_sorting/merge_sort.md +++ b/chapter_sorting/merge_sort.md @@ -146,7 +146,7 @@ comments: true === "Python" ```python title="merge_sort.py" - def merge(nums: list[int], left: int, mid: int, right: int) -> None: + def merge(nums: list[int], left: int, mid: int, right: int): """合并左子数组和右子数组""" # 左子数组区间 [left, mid] # 右子数组区间 [mid + 1, right] @@ -176,7 +176,7 @@ comments: true nums[k] = tmp[j] j += 1 - def merge_sort(nums: list[int], left: int, right: int) -> None: + def merge_sort(nums: list[int], left: int, right: int): """归并排序""" # 终止条件 if left >= right: diff --git a/chapter_sorting/quick_sort.md b/chapter_sorting/quick_sort.md index 1eb0cf7e5..c916f0171 100755 --- a/chapter_sorting/quick_sort.md +++ b/chapter_sorting/quick_sort.md @@ -382,7 +382,7 @@ comments: true === "Python" ```python title="quick_sort.py" - def quick_sort(self, nums: list[int], left: int, right: int) -> None: + def quick_sort(self, nums: list[int], left: int, right: int): """快速排序""" # 子数组长度为 1 时终止递归 if left >= right: @@ -1027,7 +1027,7 @@ comments: true === "Python" ```python title="quick_sort.py" - def quick_sort(self, nums: list[int], left: int, right: int) -> None: + def quick_sort(self, nums: list[int], left: int, right: int): """快速排序(尾递归优化)""" # 子数组长度为 1 时终止 while left < right: diff --git a/chapter_sorting/radix_sort.md b/chapter_sorting/radix_sort.md index 0f012cc65..e4600a2b1 100644 --- a/chapter_sorting/radix_sort.md +++ b/chapter_sorting/radix_sort.md @@ -141,7 +141,7 @@ $$ # 传入 exp 而非 k 可以避免在此重复执行昂贵的次方计算 return (num // exp) % 10 - def counting_sort_digit(nums: list[int], exp: int) -> None: + def counting_sort_digit(nums: list[int], exp: int): """计数排序(根据 nums 第 k 位排序)""" # 十进制的位范围为 0~9 ,因此需要长度为 10 的桶 counter = [0] * 10 @@ -164,7 +164,7 @@ $$ for i in range(n): nums[i] = res[i] - def radix_sort(nums: list[int]) -> None: + def radix_sort(nums: list[int]): """基数排序""" # 获取数组的最大元素,用于判断最大位数 m = max(nums) diff --git a/chapter_stack_and_queue/deque.md b/chapter_stack_and_queue/deque.md index 218b8f8c0..09845e342 100644 --- a/chapter_stack_and_queue/deque.md +++ b/chapter_stack_and_queue/deque.md @@ -625,7 +625,7 @@ comments: true class ListNode: """双向链表节点""" - def __init__(self, val: int) -> None: + def __init__(self, val: int): """构造方法""" self.val: int = val self.next: ListNode | None = None # 后继节点引用(指针) @@ -634,7 +634,7 @@ comments: true class LinkedListDeque: """基于双向链表实现的双向队列""" - def __init__(self) -> None: + def __init__(self): """构造方法""" self.front: ListNode | None = None # 头节点 front self.rear: ListNode | None = None # 尾节点 rear @@ -648,7 +648,7 @@ comments: true """判断双向队列是否为空""" return self.size() == 0 - def push(self, num: int, is_front: bool) -> None: + def push(self, num: int, is_front: bool): """入队操作""" node = ListNode(num) # 若链表为空,则令 front, rear 都指向 node @@ -668,11 +668,11 @@ comments: true self.rear = node # 更新尾节点 self.__size += 1 # 更新队列长度 - def push_first(self, num: int) -> None: + def push_first(self, num: int): """队首入队""" self.push(num, True) - def push_last(self, num: int) -> None: + def push_last(self, num: int): """队尾入队""" self.push(num, False) @@ -2042,7 +2042,7 @@ comments: true class ArrayDeque: """基于环形数组实现的双向队列""" - def __init__(self, capacity: int) -> None: + def __init__(self, capacity: int): """构造方法""" self.__nums: list[int] = [0] * capacity self.__front: int = 0 @@ -2067,7 +2067,7 @@ comments: true # 当 i 越过数组头部后,回到尾部 return (i + self.capacity()) % self.capacity() - def push_first(self, num: int) -> None: + def push_first(self, num: int): """队首入队""" if self.__size == self.capacity(): print("双向队列已满") @@ -2079,7 +2079,7 @@ comments: true self.__nums[self.__front] = num self.__size += 1 - def push_last(self, num: int) -> None: + def push_last(self, num: int): """队尾入队""" if self.__size == self.capacity(): print("双向队列已满") diff --git a/chapter_stack_and_queue/queue.md b/chapter_stack_and_queue/queue.md index 05bdc92df..168affff1 100755 --- a/chapter_stack_and_queue/queue.md +++ b/chapter_stack_and_queue/queue.md @@ -218,10 +218,10 @@ comments: true int pop = queue.Dequeue(); /* 获取队列的长度 */ - int size = queue.Count(); + int size = queue.Count; /* 判断队列是否为空 */ - bool isEmpty = queue.Count() == 0; + bool isEmpty = queue.Count == 0; ``` === "Swift" @@ -471,7 +471,7 @@ comments: true """判断队列是否为空""" return not self.__front - def push(self, num: int) -> None: + def push(self, num: int): """入队""" # 尾节点后添加 num node = ListNode(num) @@ -1272,7 +1272,7 @@ comments: true class ArrayQueue: """基于环形数组实现的队列""" - def __init__(self, size: int) -> None: + def __init__(self, size: int): """构造方法""" self.__nums: list[int] = [0] * size # 用于存储队列元素的数组 self.__front: int = 0 # 队首指针,指向队首元素 @@ -1290,7 +1290,7 @@ comments: true """判断队列是否为空""" return self.__size == 0 - def push(self, num: int) -> None: + def push(self, num: int): """入队""" if self.__size == self.capacity(): raise IndexError("队列已满") diff --git a/chapter_stack_and_queue/stack.md b/chapter_stack_and_queue/stack.md index 04856a808..e770dce0f 100755 --- a/chapter_stack_and_queue/stack.md +++ b/chapter_stack_and_queue/stack.md @@ -217,10 +217,10 @@ comments: true int pop = stack.Pop(); /* 获取栈的长度 */ - int size = stack.Count(); + int size = stack.Count; /* 判断是否为空 */ - bool isEmpty = stack.Count()==0; + bool isEmpty = stack.Count == 0; ``` === "Swift" @@ -451,7 +451,7 @@ comments: true """判断栈是否为空""" return not self.__peek - def push(self, val: int) -> None: + def push(self, val: int): """入栈""" node = ListNode(val) node.next = self.__peek @@ -1102,7 +1102,7 @@ comments: true class ArrayStack: """基于数组实现的栈""" - def __init__(self) -> None: + def __init__(self): """构造方法""" self.__stack: list[int] = [] @@ -1114,7 +1114,7 @@ comments: true """判断栈是否为空""" return self.__stack == [] - def push(self, item: int) -> None: + def push(self, item: int): """入栈""" self.__stack.append(item) diff --git a/chapter_tree/avl_tree.md b/chapter_tree/avl_tree.md index e1335440a..e95a2817e 100644 --- a/chapter_tree/avl_tree.md +++ b/chapter_tree/avl_tree.md @@ -1448,7 +1448,7 @@ AVL 树的特点在于「旋转 Rotation」操作,它能够在不影响二叉 === "Python" ```python title="avl_tree.py" - def insert(self, val) -> None: + def insert(self, val): """插入节点""" self.root = self.__insert_helper(self.root, val) @@ -1797,7 +1797,7 @@ AVL 树的特点在于「旋转 Rotation」操作,它能够在不影响二叉 === "Python" ```python title="avl_tree.py" - def remove(self, val: int) -> None: + def remove(self, val: int): """删除节点""" self.root = self.__remove_helper(self.root, val) diff --git a/chapter_tree/binary_search_tree.md b/chapter_tree/binary_search_tree.md index 0c2979ca0..e7d711de8 100755 --- a/chapter_tree/binary_search_tree.md +++ b/chapter_tree/binary_search_tree.md @@ -349,7 +349,7 @@ comments: true === "Python" ```python title="binary_search_tree.py" - def insert(self, num: int) -> None: + def insert(self, num: int): """插入节点""" # 若树为空,直接提前返回 if self.root is None: @@ -769,7 +769,7 @@ comments: true === "Python" ```python title="binary_search_tree.py" - def remove(self, num: int) -> None: + def remove(self, num: int): """删除节点""" # 若树为空,直接提前返回 if self.root is None: diff --git a/chapter_tree/binary_tree_traversal.md b/chapter_tree/binary_tree_traversal.md index aa10337ba..87f4158ae 100755 --- a/chapter_tree/binary_tree_traversal.md +++ b/chapter_tree/binary_tree_traversal.md @@ -385,7 +385,7 @@ comments: true === "Python" ```python title="binary_tree_dfs.py" - def pre_order(root: TreeNode | None) -> None: + def pre_order(root: TreeNode | None): """前序遍历""" if root is None: return @@ -394,7 +394,7 @@ comments: true pre_order(root=root.left) pre_order(root=root.right) - def in_order(root: TreeNode | None) -> None: + def in_order(root: TreeNode | None): """中序遍历""" if root is None: return @@ -403,7 +403,7 @@ comments: true res.append(root.val) in_order(root=root.right) - def post_order(root: TreeNode | None) -> None: + def post_order(root: TreeNode | None): """后序遍历""" if root is None: return