From ac0da11157787e3dc9e020cdf3c88b3c7d7339b0 Mon Sep 17 00:00:00 2001 From: Yudong Jin Date: Tue, 21 Jan 2025 20:00:58 +0800 Subject: [PATCH] Bug fixes and improvements (#1627) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update Copyright 2024 to 2025. * Fix the flex of .profile-cell for mobile devices. * Update performance_evaluation.md * 抛出 -> 给出 * Sync zh and zh-hant version. * Improve the landing page of the English version. * Bug fixes * Fix readme-typing-svg * Update readme-typing-svg * Bug fixes * sync zh and zh-hant versions. --- .../performance_evaluation.md | 2 +- docs/chapter_hashing/hash_algorithm.md | 2 +- docs/index.html | 2 +- .../linkedlist_deque.py | 4 +- en/docs/index.html | 30 ++++----- mkdocs.yml | 2 +- overrides/stylesheets/extra.css | 65 +++++++++++-------- .../linkedlist_deque.py | 4 +- .../chapter_array_and_linkedlist/array.rs | 8 +-- .../linked_list.rs | 48 ++++++++------ zh-hant/codes/rust/src/include/vertex.rs | 8 ++- .../performance_evaluation.md | 2 +- .../dp_solution_pipeline.md | 2 +- .../docs/chapter_hashing/hash_algorithm.md | 2 +- zh-hant/docs/chapter_sorting/heap_sort.md | 2 +- zh-hant/docs/chapter_tree/binary_tree.md | 4 ++ zh-hant/docs/index.html | 4 +- 17 files changed, 112 insertions(+), 79 deletions(-) diff --git a/docs/chapter_computational_complexity/performance_evaluation.md b/docs/chapter_computational_complexity/performance_evaluation.md index 8ede9795a..a6fb227b7 100644 --- a/docs/chapter_computational_complexity/performance_evaluation.md +++ b/docs/chapter_computational_complexity/performance_evaluation.md @@ -24,7 +24,7 @@ ## 理论估算 -由于实际测试具有较大的局限性,因此我们可以考虑仅通过一些计算来评估算法的效率。这种估算方法被称为渐近复杂度分析(asymptotic complexity analysis),简称复杂度分析。 +由于实际测试具有较大的局限性,我们可以考虑仅通过一些计算来评估算法的效率。这种估算方法被称为渐近复杂度分析(asymptotic complexity analysis),简称复杂度分析。 复杂度分析能够体现算法运行所需的时间和空间资源与输入数据大小之间的关系。**它描述了随着输入数据大小的增加,算法执行所需时间和空间的增长趋势**。这个定义有些拗口,我们可以将其分为三个重点来理解。 diff --git a/docs/chapter_hashing/hash_algorithm.md b/docs/chapter_hashing/hash_algorithm.md index 25fae1539..3b911432a 100644 --- a/docs/chapter_hashing/hash_algorithm.md +++ b/docs/chapter_hashing/hash_algorithm.md @@ -52,7 +52,7 @@ index = hash(key) % capacity 观察发现,每种哈希算法的最后一步都是对大质数 $1000000007$ 取模,以确保哈希值在合适的范围内。值得思考的是,为什么要强调对质数取模,或者说对合数取模的弊端是什么?这是一个有趣的问题。 -先抛出结论:**使用大质数作为模数,可以最大化地保证哈希值的均匀分布**。因为质数不与其他数字存在公约数,可以减少因取模操作而产生的周期性模式,从而避免哈希冲突。 +先给出结论:**使用大质数作为模数,可以最大化地保证哈希值的均匀分布**。因为质数不与其他数字存在公约数,可以减少因取模操作而产生的周期性模式,从而避免哈希冲突。 举个例子,假设我们选择合数 $9$ 作为模数,它可以被 $3$ 整除,那么所有可以被 $3$ 整除的 `key` 都会被映射到 $0$、$3$、$6$ 这三个哈希值。 diff --git a/docs/index.html b/docs/index.html index d45c646ee..5e8b0888a 100644 --- a/docs/index.html +++ b/docs/index.html @@ -349,7 +349,7 @@

贡献者

本书在开源社区一百多位贡献者的共同努力下不断完善,感谢他们付出的时间与精力!

- Contributors + Contributors diff --git a/en/codes/python/chapter_stack_and_queue/linkedlist_deque.py b/en/codes/python/chapter_stack_and_queue/linkedlist_deque.py index fa3a5a2fc..a2cea2099 100644 --- a/en/codes/python/chapter_stack_and_queue/linkedlist_deque.py +++ b/en/codes/python/chapter_stack_and_queue/linkedlist_deque.py @@ -69,7 +69,7 @@ class LinkedListDeque: val: int = self._front.val # Temporarily store the head node value # Remove head node fnext: ListNode | None = self._front.next - if fnext != None: + if fnext is not None: fnext.prev = None self._front.next = None self._front = fnext # Update head node @@ -78,7 +78,7 @@ class LinkedListDeque: val: int = self._rear.val # Temporarily store the tail node value # Remove tail node rprev: ListNode | None = self._rear.prev - if rprev != None: + if rprev is not None: rprev.next = None self._rear.prev = None self._rear = rprev # Update tail node diff --git a/en/docs/index.html b/en/docs/index.html index fe6773e7e..dbedfcc7e 100644 --- a/en/docs/index.html +++ b/en/docs/index.html @@ -7,15 +7,15 @@ - Encounter with Algorithms + Encounter with Algos - Complexity analysis + Complexity analysis - Array and linked list + Array and linked list @@ -23,7 +23,7 @@ - Hash table + Hash table @@ -43,7 +43,7 @@ - Sorting + Sorting @@ -51,11 +51,11 @@ - Backtracking + Backtracking - Dynamic programming + Dynamic programming @@ -65,7 +65,7 @@
- +

Data structures and algorithms crash course with animated illustrations and off-the-shelf code @@ -113,7 +113,7 @@

-

500 animated illustrations, 14 programming languages, and 3000 community Q&As to help you quickly get started with data structures and algorithms

+

500 animated illustrations, 14 programming languages, and 3000 community Q&As to help you dive into data structures and algorithms.

@@ -144,7 +144,7 @@
- Read online + Web @@ -155,7 +155,7 @@
- Download PDF + PDF @@ -195,7 +195,7 @@

Animated illustrations

-

It's crafted for ease of understanding, ensuring a smooth learning journey.

+

It’s crafted for a smooth learning experience.

"A picture is worth a thousand words."

@@ -212,7 +212,7 @@

Off-the-shelf code

-

Featuring multiple programming languages, all runnable with a single click.

+

One click to run code in multiple languages.

"Talk is cheap. Show me the code."

@@ -227,7 +227,7 @@

Learning together

-

Welcome discussions and questions with open arms.

+

Don’t hesitate to ask or share your thoughts.

"Learning by teaching."

@@ -416,7 +416,7 @@

Contributors

This book has been refined by the efforts of over 180 contributors. We sincerely thank them for their invaluable time and contributions!

- Contributors + Contributors diff --git a/mkdocs.yml b/mkdocs.yml index f52015a57..b5db4c422 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -12,7 +12,7 @@ edit_uri: tree/main/docs version: 1.2.0 # Copyright -copyright: Copyright © 2024 krahets
The website content is licensed under CC BY-NC-SA 4.0 +copyright: Copyright © 2025 krahets
The website content is licensed under CC BY-NC-SA 4.0 # Configuration theme: diff --git a/overrides/stylesheets/extra.css b/overrides/stylesheets/extra.css index 06421472a..2d4af7f0f 100644 --- a/overrides/stylesheets/extra.css +++ b/overrides/stylesheets/extra.css @@ -1,7 +1,7 @@ /* Color Settings */ /* https://github.com/squidfunk/mkdocs-material/blob/6b5035f5580f97532d664e3d1babf5f320e88ee9/src/assets/stylesheets/main/_colors.scss */ /* https://squidfunk.github.io/mkdocs-material/setup/changing-the-colors/#custom-colors */ -:root > * { +:root>* { --md-primary-fg-color: #ffffff; --md-primary-bg-color: #1d1d20; @@ -69,8 +69,10 @@ .md-header--landing { box-shadow: none; transition: none; - backdrop-filter: saturate(180%) blur(20px); /* Gaussian blur */ - -webkit-backdrop-filter: saturate(180%) blur(20px); /* Safari */ + backdrop-filter: saturate(180%) blur(20px); + /* Gaussian blur */ + -webkit-backdrop-filter: saturate(180%) blur(20px); + /* Safari */ background-color: var(--md-header-bg-color); } @@ -159,7 +161,7 @@ body { /* max height of code block */ /* https://github.com/squidfunk/mkdocs-material/issues/3444 */ -.md-typeset pre > code { +.md-typeset pre>code { max-height: 25rem; } @@ -176,7 +178,8 @@ body { align-items: center; justify-content: center; margin: 0 auto; - width: 100%; /* Default to full width */ + width: 100%; + /* Default to full width */ } /* Admonition for python tutor */ @@ -192,12 +195,13 @@ body { box-shadow: var(--md-shadow-z1); } -.md-typeset .pythontutor > .admonition-title, -.md-typeset .pythontutor > summary { +.md-typeset .pythontutor>.admonition-title, +.md-typeset .pythontutor>summary { background-color: var(--md-code-bg-color); } -.md-typeset .pythontutor > .admonition-title::before, -.md-typeset .pythontutor > summary::before { + +.md-typeset .pythontutor>.admonition-title::before, +.md-typeset .pythontutor>summary::before { background-color: rgb(55, 118, 171); -webkit-mask-image: var(--md-admonition-icon--pythontutor); mask-image: var(--md-admonition-icon--pythontutor); @@ -301,7 +305,7 @@ body { a:hover .device-on-hover { filter: drop-shadow(0 0 0.2rem rgba(0, 0, 0, 0.15)); - transform: scale(1.02); + transform: scale(1.01); } /* text button */ @@ -363,27 +367,27 @@ a:hover .text-button span { } /* hover on the planets */ -.hero-div > a > img { +.hero-div>a>img { width: auto; position: absolute; transition: transform 0.3s ease-in-out, filter 0.3s ease-in-out; } -.hero-div > a > span { +.hero-div>a>span { margin: 0; position: absolute; transform: translateX(-50%) translateY(-50%); - white-space: nowrap; /* prevent line breaks */ + white-space: nowrap; + /* prevent line breaks */ color: white; } -.hero-div > a:hover > img { - filter: brightness(1.15) saturate(1.1) - drop-shadow(0 0 0.5rem rgba(255, 255, 255, 0.2)); +.hero-div>a:hover>img { + filter: brightness(1.15) saturate(1.1) drop-shadow(0 0 0.5rem rgba(255, 255, 255, 0.2)); transform: scale(1.03); } -.hero-div > a:hover > span { +.hero-div>a:hover>span { text-decoration: underline; color: var(--md-typeset-btn-color); } @@ -420,13 +424,14 @@ a:hover .text-button span { .intro-image { flex-shrink: 0; flex-grow: 0; - width: 55%; + width: 50%; border-radius: 0.5em; box-shadow: var(--md-shadow-z2); } .intro-text { - flex-grow: 1; /* fill the space */ + flex-grow: 1; + /* fill the space */ display: flex; flex-direction: column; justify-content: center; @@ -436,7 +441,7 @@ a:hover .text-button span { margin: 2em; } -.intro-text > div { +.intro-text>div { align-self: flex-start; width: auto; margin: 0 auto; @@ -461,9 +466,8 @@ a:hover .text-button span { } .profile-cell { - flex: 1; /* even distribution */ - flex-basis: 20%; - margin: 1em 0.5em; + flex: 1 1 15%; + margin: 1em 0; text-align: center; } @@ -494,12 +498,16 @@ a:hover .text-button span { } } -/* Hide table of contents */ +/* mobile devices */ @media screen and (max-width: 60em) { .home-div { font-size: 0.75rem; } + .hero-div { + margin-top: -4rem; + } + .intro-container { flex-direction: column; } @@ -524,11 +532,16 @@ a:hover .text-button span { .text-button { margin: 0.7em auto; } + + .profile-cell { + flex: 1 1 30%; + } } .video-container { position: relative; - padding-bottom: 56.25%; /* 16:9 */ + padding-bottom: 56.25%; + /* 16:9 */ height: 0; } @@ -538,4 +551,4 @@ a:hover .text-button span { left: 0; width: 100%; height: 100%; -} +} \ No newline at end of file diff --git a/zh-hant/codes/python/chapter_stack_and_queue/linkedlist_deque.py b/zh-hant/codes/python/chapter_stack_and_queue/linkedlist_deque.py index 67b298510..c7b174272 100644 --- a/zh-hant/codes/python/chapter_stack_and_queue/linkedlist_deque.py +++ b/zh-hant/codes/python/chapter_stack_and_queue/linkedlist_deque.py @@ -69,7 +69,7 @@ class LinkedListDeque: val: int = self._front.val # 暫存頭節點值 # 刪除頭節點 fnext: ListNode | None = self._front.next - if fnext != None: + if fnext is not None: fnext.prev = None self._front.next = None self._front = fnext # 更新頭節點 @@ -78,7 +78,7 @@ class LinkedListDeque: val: int = self._rear.val # 暫存尾節點值 # 刪除尾節點 rprev: ListNode | None = self._rear.prev - if rprev != None: + if rprev is not None: rprev.next = None self._rear.prev = None self._rear = rprev # 更新尾節點 diff --git a/zh-hant/codes/rust/chapter_array_and_linkedlist/array.rs b/zh-hant/codes/rust/chapter_array_and_linkedlist/array.rs index 1184dcfff..33e6118af 100644 --- a/zh-hant/codes/rust/chapter_array_and_linkedlist/array.rs +++ b/zh-hant/codes/rust/chapter_array_and_linkedlist/array.rs @@ -21,9 +21,8 @@ fn extend(nums: &[i32], enlarge: usize) -> Vec { // 初始化一個擴展長度後的陣列 let mut res: Vec = vec![0; nums.len() + enlarge]; // 將原陣列中的所有元素複製到新 - for i in 0..nums.len() { - res[i] = nums[i]; - } + res[0..nums.len()].copy_from_slice(nums); + // 返回擴展後的新陣列 res } @@ -54,7 +53,8 @@ fn traverse(nums: &[i32]) { _count += nums[i]; } // 直接走訪陣列元素 - for num in nums { + _count = 0; + for &num in nums { _count += num; } } diff --git a/zh-hant/codes/rust/chapter_array_and_linkedlist/linked_list.rs b/zh-hant/codes/rust/chapter_array_and_linkedlist/linked_list.rs index 916cb5121..9db771e8f 100644 --- a/zh-hant/codes/rust/chapter_array_and_linkedlist/linked_list.rs +++ b/zh-hant/codes/rust/chapter_array_and_linkedlist/linked_list.rs @@ -19,9 +19,6 @@ pub fn insert(n0: &Rc>>, P: Rc>>) { /* 刪除鏈結串列的節點 n0 之後的首個節點 */ #[allow(non_snake_case)] pub fn remove(n0: &Rc>>) { - if n0.borrow().next.is_none() { - return; - }; // n0 -> P -> n1 let P = n0.borrow_mut().next.take(); if let Some(node) = P { @@ -31,26 +28,39 @@ pub fn remove(n0: &Rc>>) { } /* 訪問鏈結串列中索引為 index 的節點 */ -pub fn access(head: Rc>>, index: i32) -> Rc>> { - if index <= 0 { - return head; - }; - if let Some(node) = &head.borrow().next { - return access(node.clone(), index - 1); +pub fn access(head: Rc>>, index: i32) -> Option>>> { + fn dfs( + head: Option<&Rc>>>, + index: i32, + ) -> Option>>> { + if index <= 0 { + return head.cloned(); + } + + if let Some(node) = head { + dfs(node.borrow().next.as_ref(), index - 1) + } else { + None + } } - return head; + dfs(Some(head).as_ref(), index) } /* 在鏈結串列中查詢值為 target 的首個節點 */ -pub fn find(head: Rc>>, target: T, index: i32) -> i32 { - if head.borrow().val == target { - return index; - }; - if let Some(node) = &head.borrow_mut().next { - return find(node.clone(), target, index + 1); +pub fn find(head: Rc>>, target: T) -> i32 { + fn find(head: Option<&Rc>>>, target: T, idx: i32) -> i32 { + if let Some(node) = head { + if node.borrow().val == target { + return idx; + } + return find(node.borrow().next.as_ref(), target, idx + 1); + } else { + -1 + } } - return -1; + + find(Some(head).as_ref(), target, 0) } /* Driver Code */ @@ -82,9 +92,9 @@ fn main() { /* 訪問節點 */ let node = access(n0.clone(), 3); - println!("鏈結串列中索引 3 處的節點的值 = {}", node.borrow().val); + println!("鏈結串列中索引 3 處的節點的值 = {}", node.unwrap().borrow().val); /* 查詢節點 */ - let index = find(n0.clone(), 2, 0); + let index = find(n0.clone(), 2); println!("鏈結串列中值為 2 的節點的索引 = {}", index); } diff --git a/zh-hant/codes/rust/src/include/vertex.rs b/zh-hant/codes/rust/src/include/vertex.rs index 6d9b5e550..3a1730dc5 100644 --- a/zh-hant/codes/rust/src/include/vertex.rs +++ b/zh-hant/codes/rust/src/include/vertex.rs @@ -10,9 +10,15 @@ pub struct Vertex { pub val: i32, } +impl From for Vertex { + fn from(value: i32) -> Self { + Self { val: value } + } +} + /* 輸入值串列 vals ,返回頂點串列 vets */ pub fn vals_to_vets(vals: Vec) -> Vec { - vals.into_iter().map(|val| Vertex { val }).collect() + vals.into_iter().map(|val| val.into()).collect() } /* 輸入頂點串列 vets ,返回值串列 vals */ diff --git a/zh-hant/docs/chapter_computational_complexity/performance_evaluation.md b/zh-hant/docs/chapter_computational_complexity/performance_evaluation.md index 9f101dfa4..b97c7a325 100644 --- a/zh-hant/docs/chapter_computational_complexity/performance_evaluation.md +++ b/zh-hant/docs/chapter_computational_complexity/performance_evaluation.md @@ -24,7 +24,7 @@ ## 理論估算 -由於實際測試具有較大的侷限性,因此我們可以考慮僅透過一些計算來評估演算法的效率。這種估算方法被稱為漸近複雜度分析(asymptotic complexity analysis),簡稱複雜度分析。 +由於實際測試具有較大的侷限性,我們可以考慮僅透過一些計算來評估演算法的效率。這種估算方法被稱為漸近複雜度分析(asymptotic complexity analysis),簡稱複雜度分析。 複雜度分析能夠體現演算法執行所需的時間和空間資源與輸入資料大小之間的關係。**它描述了隨著輸入資料大小的增加,演算法執行所需時間和空間的增長趨勢**。這個定義有些拗口,我們可以將其分為三個重點來理解。 diff --git a/zh-hant/docs/chapter_dynamic_programming/dp_solution_pipeline.md b/zh-hant/docs/chapter_dynamic_programming/dp_solution_pipeline.md index 7750266f9..777a8b751 100644 --- a/zh-hant/docs/chapter_dynamic_programming/dp_solution_pipeline.md +++ b/zh-hant/docs/chapter_dynamic_programming/dp_solution_pipeline.md @@ -110,7 +110,7 @@ $$ ![暴力搜尋遞迴樹](dp_solution_pipeline.assets/min_path_sum_dfs.png) -每個狀態都有向下和向右兩種選擇,從左上角走到右下角總共需要 $m + n - 2$ 步,所以最差時間複雜度為 $O(2^{m + n})$ 。請注意,這種計算方式未考慮臨近網格邊界的情況,當到達網路邊界時只剩下一種選擇,因此實際的路徑數量會少一些。 +每個狀態都有向下和向右兩種選擇,從左上角走到右下角總共需要 $m + n - 2$ 步,所以最差時間複雜度為 $O(2^{m + n})$ ,其中 $n$ 和 $m$ 分別為網格的行數和列數。請注意,這種計算方式未考慮臨近網格邊界的情況,當到達網路邊界時只剩下一種選擇,因此實際的路徑數量會少一些。 ### 方法二:記憶化搜尋 diff --git a/zh-hant/docs/chapter_hashing/hash_algorithm.md b/zh-hant/docs/chapter_hashing/hash_algorithm.md index 55c9ac225..50c6f7369 100644 --- a/zh-hant/docs/chapter_hashing/hash_algorithm.md +++ b/zh-hant/docs/chapter_hashing/hash_algorithm.md @@ -52,7 +52,7 @@ index = hash(key) % capacity 觀察發現,每種雜湊演算法的最後一步都是對大質數 $1000000007$ 取模,以確保雜湊值在合適的範圍內。值得思考的是,為什麼要強調對質數取模,或者說對合數取模的弊端是什麼?這是一個有趣的問題。 -先說結論:**使用大質數作為模數,可以最大化地保證雜湊值的均勻分佈**。因為質數不與其他數字存在公約數,可以減少因取模操作而產生的週期性模式,從而避免雜湊衝突。 +先給出結論:**使用大質數作為模數,可以最大化地保證雜湊值的均勻分佈**。因為質數不與其他數字存在公約數,可以減少因取模操作而產生的週期性模式,從而避免雜湊衝突。 舉個例子,假設我們選擇合數 $9$ 作為模數,它可以被 $3$ 整除,那麼所有可以被 $3$ 整除的 `key` 都會被對映到 $0$、$3$、$6$ 這三個雜湊值。 diff --git a/zh-hant/docs/chapter_sorting/heap_sort.md b/zh-hant/docs/chapter_sorting/heap_sort.md index 81ca4452b..638c7d3fb 100644 --- a/zh-hant/docs/chapter_sorting/heap_sort.md +++ b/zh-hant/docs/chapter_sorting/heap_sort.md @@ -2,7 +2,7 @@ !!! tip - 閱讀本節前,請確保已學完“堆積“章節。 + 閱讀本節前,請確保已學完“堆積”章節。 堆積排序(heap sort)是一種基於堆積資料結構實現的高效排序演算法。我們可以利用已經學過的“建堆積操作”和“元素出堆積操作”實現堆積排序。 diff --git a/zh-hant/docs/chapter_tree/binary_tree.md b/zh-hant/docs/chapter_tree/binary_tree.md index 69c2820a6..dbbb9f270 100644 --- a/zh-hant/docs/chapter_tree/binary_tree.md +++ b/zh-hant/docs/chapter_tree/binary_tree.md @@ -493,6 +493,8 @@ P->left = n2; // 刪除節點 P n1->left = n2; + // 釋放記憶體 + delete P; ``` === "Java" @@ -598,6 +600,8 @@ P->left = n2; // 刪除節點 P n1->left = n2; + // 釋放記憶體 + free(P); ``` === "Kotlin" diff --git a/zh-hant/docs/index.html b/zh-hant/docs/index.html index 4c20abb9e..4628e7070 100644 --- a/zh-hant/docs/index.html +++ b/zh-hant/docs/index.html @@ -131,7 +131,7 @@
Cover
- 紙質書(簡中) + 紙質書 @@ -368,7 +368,7 @@

貢獻者

本書在開源社群一百多位貢獻者的共同努力下不斷完善,感謝他們付出的時間與精力!

- Contributors + Contributors