Skip to content

Commit

Permalink
Polish the content
Browse files Browse the repository at this point in the history
Polish the chapter preface, introduction and complexity anlysis
  • Loading branch information
krahets committed Aug 8, 2023
1 parent 9ed16db commit 932d146
Show file tree
Hide file tree
Showing 26 changed files with 215 additions and 182 deletions.
2 changes: 1 addition & 1 deletion codes/c/chapter_computational_complexity/time_complexity.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ int bubbleSort(int *nums, int n) {
int exponential(int n) {
int count = 0;
int bas = 1;
// cell 每轮一分为二,形成数列 1, 2, 4, 8, ..., 2^(n-1)
// 细胞每轮一分为二,形成数列 1, 2, 4, 8, ..., 2^(n-1)
for (int i = 0; i < n; i++) {
for (int j = 0; j < bas; j++) {
count++;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ int bubbleSort(vector<int> &nums) {
/* 指数阶(循环实现) */
int exponential(int n) {
int count = 0, base = 1;
// cell 每轮一分为二,形成数列 1, 2, 4, 8, ..., 2^(n-1)
// 细胞每轮一分为二,形成数列 1, 2, 4, 8, ..., 2^(n-1)
for (int i = 0; i < n; i++) {
for (int j = 0; j < base; j++) {
count++;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ static int bubbleSort(int[] nums) {
/* 指数阶(循环实现) */
static int exponential(int n) {
int count = 0, bas = 1;
// cell 每轮一分为二,形成数列 1, 2, 4, 8, ..., 2^(n-1)
// 细胞每轮一分为二,形成数列 1, 2, 4, 8, ..., 2^(n-1)
for (int i = 0; i < n; i++) {
for (int j = 0; j < bas; j++) {
count++;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ int bubbleSort(List<int> nums) {
/* 指数阶(循环实现) */
int exponential(int n) {
int count = 0, base = 1;
// cell 每轮一分为二,形成数列 1, 2, 4, 8, ..., 2^(n-1)
// 细胞每轮一分为二,形成数列 1, 2, 4, 8, ..., 2^(n-1)
for (var i = 0; i < n; i++) {
for (var j = 0; j < base; j++) {
count++;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func bubbleSort(nums []int) int {
/* 指数阶(循环实现)*/
func exponential(n int) int {
count, base := 0, 1
// cell 每轮一分为二,形成数列 1, 2, 4, 8, ..., 2^(n-1)
// 细胞每轮一分为二,形成数列 1, 2, 4, 8, ..., 2^(n-1)
for i := 0; i < n; i++ {
for j := 0; j < base; j++ {
count++
Expand Down
26 changes: 13 additions & 13 deletions codes/go/chapter_hashing/array_hash_map_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,42 +11,42 @@ import (

func TestArrayHashMap(t *testing.T) {
/* 初始化哈希表 */
mapp := newArrayHashMap()
hmap := newArrayHashMap()

/* 添加操作 */
// 在哈希表中添加键值对 (key, value)
mapp.put(12836, "小哈")
mapp.put(15937, "小啰")
mapp.put(16750, "小算")
mapp.put(13276, "小法")
mapp.put(10583, "小鸭")
hmap.put(12836, "小哈")
hmap.put(15937, "小啰")
hmap.put(16750, "小算")
hmap.put(13276, "小法")
hmap.put(10583, "小鸭")
fmt.Println("\n添加完成后,哈希表为\nKey -> Value")
mapp.print()
hmap.print()

/* 查询操作 */
// 向哈希表输入键 key ,得到值 value
name := mapp.get(15937)
name := hmap.get(15937)
fmt.Println("\n输入学号 15937 ,查询到姓名 " + name)

/* 删除操作 */
// 在哈希表中删除键值对 (key, value)
mapp.remove(10583)
hmap.remove(10583)
fmt.Println("\n删除 10583 后,哈希表为\nKey -> Value")
mapp.print()
hmap.print()

/* 遍历哈希表 */
fmt.Println("\n遍历键值对 Key->Value")
for _, kv := range mapp.pairSet() {
for _, kv := range hmap.pairSet() {
fmt.Println(kv.key, " -> ", kv.val)
}

fmt.Println("\n单独遍历键 Key")
for _, key := range mapp.keySet() {
for _, key := range hmap.keySet() {
fmt.Println(key)
}

fmt.Println("\n单独遍历值 Value")
for _, val := range mapp.valueSet() {
for _, val := range hmap.valueSet() {
fmt.Println(val)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ static int bubbleSort(int[] nums) {
/* 指数阶(循环实现) */
static int exponential(int n) {
int count = 0, base = 1;
// cell 每轮一分为二,形成数列 1, 2, 4, 8, ..., 2^(n-1)
// 细胞每轮一分为二,形成数列 1, 2, 4, 8, ..., 2^(n-1)
for (int i = 0; i < n; i++) {
for (int j = 0; j < base; j++) {
count++;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ function bubbleSort(nums) {
function exponential(n) {
let count = 0,
base = 1;
// cell 每轮一分为二,形成数列 1, 2, 4, 8, ..., 2^(n-1)
// 细胞每轮一分为二,形成数列 1, 2, 4, 8, ..., 2^(n-1)
for (let i = 0; i < n; i++) {
for (let j = 0; j < base; j++) {
count++;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ def linear(n: int):
# 长度为 n 的列表占用 O(n) 空间
nums = [0] * n
# 长度为 n 的哈希表占用 O(n) 空间
mapp = dict[int, str]()
hmap = dict[int, str]()
for i in range(n):
mapp[i] = str(i)
hmap[i] = str(i)


def linear_recur(n: int):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def exponential(n: int) -> int:
"""指数阶(循环实现)"""
count = 0
base = 1
# cell 每轮一分为二,形成数列 1, 2, 4, 8, ..., 2^(n-1)
# 细胞每轮一分为二,形成数列 1, 2, 4, 8, ..., 2^(n-1)
for _ in range(n):
for _ in range(base):
count += 1
Expand Down
26 changes: 13 additions & 13 deletions codes/python/chapter_hashing/array_hash_map.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,38 +80,38 @@ def print(self):
"""Driver Code"""
if __name__ == "__main__":
# 初始化哈希表
mapp = ArrayHashMap()
hmap = ArrayHashMap()

# 添加操作
# 在哈希表中添加键值对 (key, value)
mapp.put(12836, "小哈")
mapp.put(15937, "小啰")
mapp.put(16750, "小算")
mapp.put(13276, "小法")
mapp.put(10583, "小鸭")
hmap.put(12836, "小哈")
hmap.put(15937, "小啰")
hmap.put(16750, "小算")
hmap.put(13276, "小法")
hmap.put(10583, "小鸭")
print("\n添加完成后,哈希表为\nKey -> Value")
mapp.print()
hmap.print()

# 查询操作
# 向哈希表输入键 key ,得到值 value
name = mapp.get(15937)
name = hmap.get(15937)
print("\n输入学号 15937 ,查询到姓名 " + name)

# 删除操作
# 在哈希表中删除键值对 (key, value)
mapp.remove(10583)
hmap.remove(10583)
print("\n删除 10583 后,哈希表为\nKey -> Value")
mapp.print()
hmap.print()

# 遍历哈希表
print("\n遍历键值对 Key->Value")
for pair in mapp.entry_set():
for pair in hmap.entry_set():
print(pair.key, "->", pair.val)

print("\n单独遍历键 Key")
for key in mapp.key_set():
for key in hmap.key_set():
print(key)

print("\n单独遍历值 Value")
for val in mapp.value_set():
for val in hmap.value_set():
print(val)
26 changes: 13 additions & 13 deletions codes/python/chapter_hashing/hash_map.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,38 +12,38 @@
"""Driver Code"""
if __name__ == "__main__":
# 初始化哈希表
mapp = dict[int, str]()
hmap = dict[int, str]()

# 添加操作
# 在哈希表中添加键值对 (key, value)
mapp[12836] = "小哈"
mapp[15937] = "小啰"
mapp[16750] = "小算"
mapp[13276] = "小法"
mapp[10583] = "小鸭"
hmap[12836] = "小哈"
hmap[15937] = "小啰"
hmap[16750] = "小算"
hmap[13276] = "小法"
hmap[10583] = "小鸭"
print("\n添加完成后,哈希表为\nKey -> Value")
print_dict(mapp)
print_dict(hmap)

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

# 删除操作
# 在哈希表中删除键值对 (key, value)
mapp.pop(10583)
hmap.pop(10583)
print("\n删除 10583 后,哈希表为\nKey -> Value")
print_dict(mapp)
print_dict(hmap)

# 遍历哈希表
print("\n遍历键值对 Key->Value")
for key, value in mapp.items():
for key, value in hmap.items():
print(key, "->", value)

print("\n单独遍历键 Key")
for key in mapp.keys():
for key in hmap.keys():
print(key)

print("\n单独遍历值 Value")
for val in mapp.values():
for val in hmap.values():
print(val)
8 changes: 4 additions & 4 deletions codes/python/chapter_searching/hashing_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,20 @@
from modules import *


def hashing_search_array(mapp: dict[int, int], target: int) -> int:
def hashing_search_array(hmap: dict[int, int], target: int) -> int:
"""哈希查找(数组)"""
# 哈希表的 key: 目标元素,value: 索引
# 若哈希表中无此 key ,返回 -1
return mapp.get(target, -1)
return hmap.get(target, -1)


def hashing_search_linkedlist(
mapp: dict[int, ListNode], target: int
hmap: dict[int, ListNode], target: int
) -> ListNode | None:
"""哈希查找(链表)"""
# 哈希表的 key: 目标元素,value: 节点对象
# 若哈希表中无此 key ,返回 None
return mapp.get(target, None)
return hmap.get(target, None)


"""Driver Code"""
Expand Down
4 changes: 2 additions & 2 deletions codes/python/modules/print_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ def print_tree(
print_tree(root.left, trunk, False)


def print_dict(mapp: dict):
def print_dict(hmap: dict):
"""Print a dict"""
for key, value in mapp.items():
for key, value in hmap.items():
print(key, "->", value)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ fn bubble_sort(nums: &mut [i32]) -> i32 {
fn exponential(n: i32) -> i32 {
let mut count = 0;
let mut base = 1;
// cell 每轮一分为二,形成数列 1, 2, 4, 8, ..., 2^(n-1)
// 细胞每轮一分为二,形成数列 1, 2, 4, 8, ..., 2^(n-1)
for _ in 0..n {
for _ in 0..base {
count += 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func bubbleSort(nums: inout [Int]) -> Int {
func exponential(n: Int) -> Int {
var count = 0
var base = 1
// cell 每轮一分为二,形成数列 1, 2, 4, 8, ..., 2^(n-1)
// 细胞每轮一分为二,形成数列 1, 2, 4, 8, ..., 2^(n-1)
for _ in 0 ..< n {
for _ in 0 ..< base {
count += 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ function bubbleSort(nums: number[]): number {
function exponential(n: number): number {
let count = 0,
base = 1;
// cell 每轮一分为二,形成数列 1, 2, 4, 8, ..., 2^(n-1)
// 细胞每轮一分为二,形成数列 1, 2, 4, 8, ..., 2^(n-1)
for (let i = 0; i < n; i++) {
for (let j = 0; j < base; j++) {
count++;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ fn exponential(n: i32) i32 {
var count: i32 = 0;
var bas: i32 = 1;
var i: i32 = 0;
// cell 每轮一分为二,形成数列 1, 2, 4, 8, ..., 2^(n-1)
// 细胞每轮一分为二,形成数列 1, 2, 4, 8, ..., 2^(n-1)
while (i < n) : (i += 1) {
var j: i32 = 0;
while (j < bas) : (j += 1) {
Expand Down
28 changes: 15 additions & 13 deletions docs/chapter_computational_complexity/performance_evaluation.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,46 @@

## 算法评价维度

从总体上看,算法设计追求以下两个层面的目标
在算法设计中,我们先后追求以下两个层面的目标

1. **找到问题解法**算法需要在规定的输入范围内,可靠地求得问题的正确解。
2. **寻求最优解法**同一个问题可能存在多种解法,我们希望找到尽可能高效的算法。
1. **找到问题解法**算法需要在规定的输入范围内,可靠地求得问题的正确解。
2. **寻求最优解法**同一个问题可能存在多种解法,我们希望找到尽可能高效的算法。

因此,在能够解决问题的前提下,算法效率成为主要的评价维度,主要包括
因此在能够解决问题的前提下,算法效率成为主要的评价维度,包括

- **时间效率**,即算法运行速度的快慢。
- **空间效率**,即算法占用内存空间的大小。

简而言之,**我们的目标是设计“既快又省”的数据结构与算法**掌握评估算法效率的方法则至关重要,因为只有了解评价标准,我们才能进行算法之间的对比分析,从而指导算法设计与优化过程。
简而言之,**我们的目标是设计“既快又省”的数据结构与算法**而有效地评估算法效率至关重要,因为只有了解评价标准,我们才能对比分析各种算法,从而指导算法设计与优化过程。

## 效率评估方法

### 实际测试

假设我们现在有算法 A 和算法 B,它们都能解决同一问题,现在需要对比这两个算法的效率。我们最直接的方法就是找一台计算机,运行这两个算法,并监控记录它们的运行时间和内存占用情况。这种评估方式能够反映真实情况,但也存在较大局限性。
假设我们现在有算法 `A` 和算法 `B` ,它们都能解决同一问题,现在需要对比这两个算法的效率。最直接的方法是找一台计算机,运行这两个算法,并监控记录它们的运行时间和内存占用情况。这种评估方式能够反映真实情况,但也存在较大局限性。

**难以排除测试环境的干扰因素**。硬件配置会影响算法的性能表现。例如,在某台计算机中,算法 A 的运行时间比算法 B 短;但在另一台配置不同的计算机中,我们可能得到相反的测试结果。这意味着我们需要在各种机器上进行测试,而这是不现实的。
**难以排除测试环境的干扰因素**。硬件配置会影响算法的性能表现。比如在某台计算机中,算法 `A` 的运行时间比算法 `B` 短;但在另一台配置不同的计算机中,我们可能得到相反的测试结果。这意味着我们需要在各种机器上进行测试,统计平均效率,而这是不现实的。

**展开完整测试非常耗费资源**。随着输入数据量的变化,算法会表现出不同的效率。例如,输入数据量较小时,算法 A 的运行时间可能短于算法 B;而输入数据量较大时,测试结果可能相反。因此,为了得到有说服力的结论,我们需要测试各种规模的输入数据,这样需要占用大量的计算资源
**展开完整测试非常耗费资源**。随着输入数据量的变化,算法会表现出不同的效率。例如,在输入数据量较小时,算法 `A` 的运行时间比算法 `B` 更少;而输入数据量较大时,测试结果可能恰恰相反。因此,为了得到有说服力的结论,我们需要测试各种规模的输入数据,而这样需要耗费大量的计算资源

### 理论估算

由于实际测试具有较大的局限性,我们可以考虑仅通过一些计算来评估算法的效率。这种估算方法被称为「复杂度分析 Complexity Analysis」或「渐近复杂度分析 Asymptotic Complexity Analysis」。
由于实际测试具有较大的局限性,我们可以考虑仅通过一些计算来评估算法的效率。这种估算方法被称为「渐近复杂度分析 Asymptotic Complexity Analysis」,简称为「复杂度分析」。

**复杂度分析评估的是算法运行效率随着输入数据量增多时的增长趋势**。这个定义有些拗口,我们可以将其分为三个重点来理解:

- “算法运行效率”可分为“运行时间”和“占用空间”,因此我们可以将复杂度分为「时间复杂度 Time Complexity」和「空间复杂度 Space Complexity」。
- “算法运行效率”可分为运行时间和占用空间两部分,与之对应地,复杂度可分为「时间复杂度 Time Complexity」和「空间复杂度 Space Complexity」。
- “随着输入数据量增多时”表示复杂度与输入数据量有关,反映了算法运行效率与输入数据量之间的关系。
- “增长趋势”表示复杂度分析关注的是算法时间与空间的增长趋势,而非具体的运行时间或占用空间。

**复杂度分析克服了实际测试方法的弊端**。首先,它独立于测试环境,因此分析结果适用于所有运行平台。其次,它可以体现不同数据量下的算法效率,尤其是在大数据量下的算法性能。

如果你对复杂度分析的概念仍感到困惑,无需担心,我们会在后续章节详细介绍。

## 复杂度分析重要性
## 复杂度的重要性

复杂度分析为我们提供了一把评估算法效率的“标尺”,告诉我们执行某个算法所需的时间和空间资源,并使我们能够对比不同算法之间的效率。
复杂度分析为我们提供了一把评估算法效率的“标尺”,帮助我们衡量了执行某个算法所需的时间和空间资源,并使我们能够对比不同算法之间的效率。

复杂度是个数学概念,对于初学者可能比较抽象,学习难度相对较高。从这个角度看,复杂度分析可能不太适合作为第一章的内容。然而,当我们讨论某个数据结构或算法的特点时,我们难以避免要分析其运行速度和空间使用情况。**因此,在深入学习数据结构与算法之前,建议读者先对复杂度建立初步的了解,并能够完成简单案例的复杂度分析**
复杂度是个数学概念,对于初学者可能比较抽象,学习难度相对较高。从这个角度看,复杂度分析可能不太适合作为第一章的内容。

然而,当我们讨论某个数据结构或算法的特点时,难以避免要分析其运行速度和空间使用情况。因此,在深入学习数据结构与算法之前,**建议你先对复杂度建立初步的了解,能够完成简单算法的复杂度分析**
Loading

0 comments on commit 932d146

Please sign in to comment.