diff --git a/chapter_computational_complexity/performance_evaluation.md b/chapter_computational_complexity/performance_evaluation.md index 76d5586b3..d3181363e 100644 --- a/chapter_computational_complexity/performance_evaluation.md +++ b/chapter_computational_complexity/performance_evaluation.md @@ -4,8 +4,6 @@ comments: true # 2.1.   算法效率评估 -## 2.1.1.   算法评价维度 - 在算法设计中,我们先后追求以下两个层面的目标: 1. **找到问题解法**:算法需要在规定的输入范围内,可靠地求得问题的正确解。 @@ -18,9 +16,9 @@ comments: true 简而言之,**我们的目标是设计“既快又省”的数据结构与算法**。而有效地评估算法效率至关重要,因为只有了解评价标准,我们才能对比分析各种算法,从而指导算法设计与优化过程。 -## 2.1.2.   效率评估方法 +效率评估方法主要分为两种:实际测试和理论估算。 -### 实际测试 +## 2.1.1.   实际测试 假设我们现在有算法 `A` 和算法 `B` ,它们都能解决同一问题,现在需要对比这两个算法的效率。最直接的方法是找一台计算机,运行这两个算法,并监控记录它们的运行时间和内存占用情况。这种评估方式能够反映真实情况,但也存在较大局限性。 @@ -28,7 +26,7 @@ comments: true **展开完整测试非常耗费资源**。随着输入数据量的变化,算法会表现出不同的效率。例如,在输入数据量较小时,算法 `A` 的运行时间比算法 `B` 更少;而输入数据量较大时,测试结果可能恰恰相反。因此,为了得到有说服力的结论,我们需要测试各种规模的输入数据,而这样需要耗费大量的计算资源。 -### 理论估算 +## 2.1.2.   理论估算 由于实际测试具有较大的局限性,我们可以考虑仅通过一些计算来评估算法的效率。这种估算方法被称为「渐近复杂度分析 Asymptotic Complexity Analysis」,简称为「复杂度分析」。 diff --git a/chapter_divide_and_conquer/summary.md b/chapter_divide_and_conquer/summary.md index 9ed78a801..b7a6861d3 100644 --- a/chapter_divide_and_conquer/summary.md +++ b/chapter_divide_and_conquer/summary.md @@ -8,7 +8,7 @@ status: new - 分治算法是一种常见的算法设计策略,包括分(划分)和治(合并)两个阶段,通常基于递归实现。 - 判断是否是分治算法问题的依据包括:问题能否被分解、子问题是否独立、子问题是否可以被合并。 - 归并排序是分治策略的典型应用,其递归地将数组划分为等长的两个子数组,直到只剩一个元素时开始逐层合并,从而完成排序。 -- 引入分治策略往往可以带来算法效率的提升。一方面,分治策略减少了计算吧操作数量;另一方面,分治后有利于系统的并行优化。 +- 引入分治策略往往可以带来算法效率的提升。一方面,分治策略减少了计算操作数量;另一方面,分治后有利于系统的并行优化。 - 分治既可以解决许多算法问题,也广泛应用于数据结构与算法设计中,处处可见其身影。 - 相较于暴力搜索,自适应搜索效率更高。时间复杂度为 $O(\log n)$ 的搜索算法通常都是基于分治策略实现的。 - 二分查找是分治思想的另一个典型应用,它不包含将子问题的解进行合并的步骤。我们可以通过递归分治实现二分查找。 diff --git a/chapter_greedy/greedy_algorithm.md b/chapter_greedy/greedy_algorithm.md index 5c74efbda..345e67a9a 100644 --- a/chapter_greedy/greedy_algorithm.md +++ b/chapter_greedy/greedy_algorithm.md @@ -37,7 +37,7 @@ status: new // 循环进行贪心选择,直到无剩余金额 while (amt > 0) { // 找到小于且最接近剩余金额的硬币 - while (coins[i] > amt) { + while (i > 0 && coins[i] > amt) { i--; } // 选择 coins[i] @@ -60,7 +60,7 @@ status: new // 循环进行贪心选择,直到无剩余金额 while (amt > 0) { // 找到小于且最接近剩余金额的硬币 - while (coins[i] > amt) { + while (i > 0 && coins[i] > amt) { i--; } // 选择 coins[i] @@ -83,7 +83,7 @@ status: new # 循环进行贪心选择,直到无剩余金额 while amt > 0: # 找到小于且最接近剩余金额的硬币 - while coins[i] > amt: + while i > 0 and coins[i] > amt: i -= 1 # 选择 coins[i] amt -= coins[i] @@ -103,7 +103,7 @@ status: new // 循环进行贪心选择,直到无剩余金额 for amt > 0 { // 找到小于且最接近剩余金额的硬币 - for coins[i] > amt { + for i > 0 && coins[i] > amt { i-- } // 选择 coins[i] @@ -147,7 +147,7 @@ status: new // 循环进行贪心选择,直到无剩余金额 while (amt > 0) { // 找到小于且最接近剩余金额的硬币 - while (coins[i] > amt) { + while (i > 0 && coins[i] > amt) { i--; } // 选择 coins[i] @@ -188,7 +188,7 @@ status: new // 循环进行贪心选择,直到无剩余金额 while amt > 0 { // 找到小于且最接近剩余金额的硬币 - while coins[i] > amt { + while i > 0 && coins[i] > amt { i -= 1; } // 选择 coins[i] diff --git a/chapter_heap/top_k.md b/chapter_heap/top_k.md index 8f73eca63..ccfc8852c 100644 --- a/chapter_heap/top_k.md +++ b/chapter_heap/top_k.md @@ -82,14 +82,14 @@ comments: true Queue heap = new PriorityQueue(); // 将数组的前 k 个元素入堆 for (int i = 0; i < k; i++) { - heap.add(nums[i]); + heap.offer(nums[i]); } // 从第 k+1 个元素开始,保持堆的长度为 k for (int i = k; i < nums.length; i++) { // 若当前元素大于堆顶元素,则将堆顶元素出堆、当前元素入堆 if (nums[i] > heap.peek()) { heap.poll(); - heap.add(nums[i]); + heap.offer(nums[i]); } } return heap; diff --git a/chapter_tree/binary_search_tree.md b/chapter_tree/binary_search_tree.md index 3f4ba6218..21bb375d1 100755 --- a/chapter_tree/binary_search_tree.md +++ b/chapter_tree/binary_search_tree.md @@ -15,6 +15,8 @@ comments: true ## 7.4.1.   二叉搜索树的操作 +我们将二叉搜索树封装为一个类 `ArrayBinaryTree` ,并声明一个成员变量 `root` ,指向树的根节点。 + ### 查找节点 给定目标节点值 `num` ,可以根据二叉搜索树的性质来查找。我们声明一个节点 `cur` ,从二叉树的根节点 `root` 出发,循环比较节点值 `cur.val` 和 `num` 之间的大小关系