Compare commits

...

9 commits

Author SHA1 Message Date
砖吐筷筷
ebda62c385
Merge bc0e32af57 into 356cc35e8a 2024-12-08 14:32:41 +08:00
Yudong Jin
356cc35e8a
Update the links to the zh-hant version of the PDF. (#1588) 2024-12-07 23:01:46 +08:00
Yudong Jin
dad0a3fd95
Prepare 1.2.0 release (#1585)
* Sync zh and zh-hant versions

* Update the list of contributors.

* Update time_complexity_simple_example.png

* Reduce size of the RGBA images for zh-hant version.

* Sync the zh-hant version of terminology.md

* Prepare 1.2.0 release

* Update the contributors list.
2024-12-06 09:03:43 +08:00
pzpz
e41b0a3156
Fix the function for printing the queue (#1573)
Some checks failed
C / build (Release, clang, clang++, ubuntu-latest) (push) Failing after 17s
C / build (Release, gcc, g++, ubuntu-latest) (push) Failing after 13s
C / build (Release, cl, cl, windows-latest) (push) Has been cancelled
* renfined!

* Add toArray() function to array_queue.c and array_deque.c

---------

Co-authored-by: Xi-Row <astruggle123@putlook.com>
Co-authored-by: krahets <krahets@163.com>
2024-12-04 19:38:30 +08:00
K3v123
b6939da46c
translation: Update replace_linear_by_hashing.md (#1551)
* translation: Update replace_linear_by_hashing.md

refined some parts of it.

* Update replace_linear_by_hashing.md

* Update replace_linear_by_hashing.md

---------

Co-authored-by: Yudong Jin <krahets@163.com>
2024-12-04 18:05:03 +08:00
Yudong Jin
abf1f115bf
Bug fixes and improvements (#1581)
* A bug fixes

* Sync zh and zh-hant versions.

* Fix a question in chapter_array_and_linkedlist/summary.md

* Optimize a definition in what_is_dsa.md

* Fix the Contributing guidelines for Chinese-to-English.

* Add a q&a in chapter_array_and_linkedlist/summary.md

* Sync zh and zh-hant versions.

* Update .gitignore

* Sync zh and zh-hant versions.
2024-12-04 17:58:28 +08:00
Thomas
6348dbe18d
translation: binary search updates (#1569)
* translation: binary search updates

* fix minor gramma and expression issues
2024-12-04 17:48:48 +08:00
YuZou
ca774eefbf
Update time_complexity.md (#1578)
* Bug fixes and improvements (#1577)
 * correct the implement of exp_recur function and remove +1 operation from the function to simulate the cell division process

* Update time_complexity.rs

* Update time_complexity.md

---------

Co-authored-by: zouy26 <zouy26@chinaunicom.cn>
Co-authored-by: Yudong Jin <krahets@163.com>
2024-12-04 17:36:11 +08:00
ztkuaikuai
bc0e32af57 fix(graph): enhance the judgment of boundary conditions for removeEdge functions 2024-07-07 18:40:23 +08:00
40 changed files with 163 additions and 87 deletions

5
.gitignore vendored
View file

@ -1,7 +1,7 @@
# macOS
.DS_Store
# Editor
# editors
.vscode/
**/.idea
@ -12,6 +12,3 @@
/build
/site
/utils
# test script
test.sh

View file

@ -111,16 +111,29 @@ int popLast(ArrayDeque *deque) {
return num;
}
/* 返回数组用于打印 */
int *toArray(ArrayDeque *deque, int *queSize) {
*queSize = deque->queSize;
int *res = (int *)calloc(deque->queSize, sizeof(int));
int j = deque->front;
for (int i = 0; i < deque->queSize; i++) {
res[i] = deque->nums[j % deque->queCapacity];
j++;
}
return res;
}
/* Driver Code */
int main() {
/* 初始化队列 */
int capacity = 10;
int queSize;
ArrayDeque *deque = newArrayDeque(capacity);
pushLast(deque, 3);
pushLast(deque, 2);
pushLast(deque, 5);
printf("双向队列 deque = ");
printArray(deque->nums, deque->queSize);
printArray(toArray(deque, &queSize), queSize);
/* 访问元素 */
int peekFirstNum = peekFirst(deque);
@ -131,18 +144,18 @@ int main() {
/* 元素入队 */
pushLast(deque, 4);
printf("元素 4 队尾入队后 deque = ");
printArray(deque->nums, deque->queSize);
printArray(toArray(deque, &queSize), queSize);
pushFirst(deque, 1);
printf("元素 1 队首入队后 deque = ");
printArray(deque->nums, deque->queSize);
printArray(toArray(deque, &queSize), queSize);
/* 元素出队 */
int popLastNum = popLast(deque);
printf("队尾出队元素 = %d ,队尾出队后 deque= ", popLastNum);
printArray(deque->nums, deque->queSize);
printArray(toArray(deque, &queSize), queSize);
int popFirstNum = popFirst(deque);
printf("队首出队元素 = %d ,队首出队后 deque= ", popFirstNum);
printArray(deque->nums, deque->queSize);
printArray(toArray(deque, &queSize), queSize);
/* 获取队列的长度 */
int dequeSize = size(deque);
@ -156,4 +169,4 @@ int main() {
delArrayDeque(deque);
return 0;
}
}

View file

@ -74,10 +74,23 @@ int pop(ArrayQueue *queue) {
return num;
}
/* 返回数组用于打印 */
int *toArray(ArrayQueue *queue, int *queSize) {
*queSize = queue->queSize;
int *res = (int *)calloc(queue->queSize, sizeof(int));
int j = queue->front;
for (int i = 0; i < queue->queSize; i++) {
res[i] = queue->nums[j % queue->queCapacity];
j++;
}
return res;
}
/* Driver Code */
int main() {
/* 初始化队列 */
int capacity = 10;
int queSize;
ArrayQueue *queue = newArrayQueue(capacity);
/* 元素入队 */
@ -87,7 +100,7 @@ int main() {
push(queue, 5);
push(queue, 4);
printf("队列 queue = ");
printArray(queue->nums, queue->queSize);
printArray(toArray(queue, &queSize), queSize);
/* 访问队首元素 */
int peekNum = peek(queue);
@ -96,7 +109,7 @@ int main() {
/* 元素出队 */
peekNum = pop(queue);
printf("出队元素 pop = %d ,出队后 queue = ", peekNum);
printArray(queue->nums, queue->queSize);
printArray(toArray(queue, &queSize), queSize);
/* 获取队列的长度 */
int queueSize = size(queue);
@ -111,11 +124,11 @@ int main() {
push(queue, i);
pop(queue);
printf("第 %d 轮入队 + 出队后 queue = ", i);
printArray(queue->nums, queue->queSize);
printArray(toArray(queue, &queSize), queSize);
}
// 释放内存
delArrayQueue(queue);
return 0;
}
}

View file

@ -46,7 +46,8 @@ class GraphAdjList {
if (
!this.adjList.has(vet1) ||
!this.adjList.has(vet2) ||
vet1 === vet2
vet1 === vet2 ||
this.adjList.get(vet1).indexOf(vet2) === -1
) {
throw new Error('Illegal Argument Exception');
}

View file

@ -46,7 +46,8 @@ class GraphAdjList {
if (
!this.adjList.has(vet1) ||
!this.adjList.has(vet2) ||
vet1 === vet2
vet1 === vet2 ||
this.adjList.get(vet1).indexOf(vet2) === -1
) {
throw new Error('Illegal Argument Exception');
}

View file

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View file

@ -71,6 +71,16 @@
另一方面,必要使用链表的情况主要是二叉树和图。栈和队列往往会使用编程语言提供的 `stack``queue` ,而非链表。
**Q**初始化列表 `res = [0] * self.size()` 操作,会导致 `res` 的每个元素引用相同的地址吗?
**Q**操作 `res = [[0]] * n` 生成了一个二维列表,其中每一个 `[0]` 都是独立的吗?
不会。但二维数组会有这个问题,例如初始化二维列表 `res = [[0]] * self.size()` ,则多次引用了同一个列表 `[0]`
不是独立的。此二维列表中,所有的 `[0]` 实际上是同一个对象的引用。如果我们修改其中一个元素,会发现所有的对应元素都会随之改变。
如果希望二维列表中的每个 `[0]` 都是独立的,可以使用 `res = [[0] for _ in range(n)]` 来实现。这种方式的原理是初始化了 $n$ 个独立的 `[0]` 列表对象。
**Q**:操作 `res = [0] * n` 生成了一个列表,其中每一个整数 0 都是独立的吗?
在该列表中,所有整数 0 都是同一个对象的引用。这是因为 Python 对小整数(通常是 -5 到 256采用了缓存池机制以便最大化对象复用从而提升性能。
虽然它们指向同一个对象,但我们仍然可以独立修改列表中的每个元素,这是因为 Python 的整数是“不可变对象”。当我们修改某个元素时,实际上是切换为另一个对象的引用,而不是改变原有对象本身。
然而,当列表元素是“可变对象”时(例如列表、字典或类实例等),修改某个元素会直接改变该对象本身,所有引用该对象的元素都会产生相同变化。

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View file

@ -1120,7 +1120,7 @@ $$
生物学的“细胞分裂”是指数阶增长的典型例子:初始状态为 $1$ 个细胞,分裂一轮后变为 $2$ 个,分裂两轮后变为 $4$ 个,以此类推,分裂 $n$ 轮后有 $2^n$ 个细胞。
下图和以下代码模拟了细胞分裂的过程,时间复杂度为 $O(2^n)$
下图和以下代码模拟了细胞分裂的过程,时间复杂度为 $O(2^n)$ 。请注意,输入 $n$ 表示分裂轮数,返回值 `count` 表示总分裂次数。
```src
[file]{time_complexity}-[class]{}-[func]{exponential}

View file

@ -5,7 +5,7 @@
- 整理扑克的过程与插入排序算法非常类似。插入排序算法适合排序小型数据集。
- 货币找零的步骤本质上是贪心算法,每一步都采取当前看来最好的选择。
- 算法是在有限时间内解决特定问题的一组指令或操作步骤,而数据结构是计算机中组织和存储数据的方式。
- 数据结构与算法紧密相连。数据结构是算法的基石,而算法是数据结构发挥作用的舞台
- 数据结构与算法紧密相连。数据结构是算法的基石,而算法为数据结构注入生命力
- 我们可以将数据结构与算法类比为拼装积木,积木代表数据,积木的形状和连接方式等代表数据结构,拼装积木的步骤则对应算法。
### Q & A

View file

@ -26,7 +26,7 @@
如下图所示,数据结构与算法高度相关、紧密结合,具体表现在以下三个方面。
- 数据结构是算法的基石。数据结构为算法提供了结构化存储的数据,以及操作数据的方法。
- 算法是数据结构发挥作用的舞台。数据结构本身仅存储数据信息,结合算法才能解决特定问题。
- 算法为数据结构注入生命力。数据结构本身仅存储数据信息,结合算法才能解决特定问题。
- 算法通常可以基于不同的数据结构实现,但执行效率可能相差很大,选择合适的数据结构是关键。
![数据结构与算法的关系](what_is_dsa.assets/relationship_between_data_structure_and_algorithm.png)

View file

@ -30,9 +30,9 @@
## 致谢
本书在开源社区众多贡献者的共同努力下不断完善。感谢每一位投入时间与精力的撰稿人,他们是(按照 GitHub 自动生成的顺序krahets、Gonglja、nuomi1、codingonion、Reanon、justin-tse、hpstory、danielsss、curtishd、night-cruise、S-N-O-R-L-A-X、msk397、gvenusleo、RiverTwilight、gyt95、zhuoqinyue、Zuoxun、mingXta、hello-ikun、khoaxuantu、FangYuan33、GN-Yu、longsizhuo、mgisr、Cathay-Chen、guowei-gong、xBLACKICEx、K3v123、IsChristina、JoseHung、qualifier1024、pengchzn、Guanngxu、QiLOL、L-Super、WSL0809、Slone123c、lhxsm、yuan0221、what-is-me、rongyi、JeffersonHuang、longranger2、theNefelibatas、yuelinxin、xiongsp、nanlei、a16su、cy-by-side、gaofer、malone6、Wonderdch、hongyun-robot、XiaChuerwu、yd-j、bluebean-cloud、iron-irax、he-weilai、Nigh、MolDuM、Phoenix0415、XC-Zero、SamJin98、reeswell、NI-SW、Horbin-Magician、xjr7670、YangXuanyi、DullSword、iStig、qq909244296、jiaxianhua、wenjianmin、keshida、kilikilikid、lclc6、lwbaptx、luluxia、boloboloda、hts0000、gledfish、fbigm、echo1937、szu17dmy、dshlstarr、coderlef、czruby、beintentional、KeiichiKasai、xb534、ElaBosak233、baagod、zhouLion、yishangzhang、yi427、yabo083、weibk、wangwang105、th1nk3r-ing、tao363、4yDX3906、syd168、siqyka、selear、sdshaoda、noobcodemaker、chadyi、lyl625760、lucaswangdev、liuxjerry、0130w、shanghai-Jerry、JackYang-hellobobo、Javesun99、lipusheng、ShiMaRing、FreddieLi、FloranceYeh、Transmigration-zhou、fanchenggang、gltianwen、Dr-XYZ、curly210102、CuB3y0nd、youshaoXG、bubble9um、fanenr、52coder、foursevenlove、KorsChen、ZongYangL、hezhizhen、linzeyan、ZJKung、GaochaoZhu、yang-le、Evilrabbit520、Turing-1024-Lee、Suremotoo、Allen-Scai、Richard-Zhang1019、qingpeng9802、primexiao、nidhoggfgg、1ch0、MwumLi、ZnYang2018、hugtyftg、logan-qiu、psychelzh 和 Keynman
本书在开源社区众多贡献者的共同努力下不断完善。感谢每一位投入时间与精力的撰稿人,他们是(按照 GitHub 自动生成的顺序krahets、coderonion、Gonglja、nuomi1、Reanon、justin-tse、hpstory、danielsss、curtishd、night-cruise、S-N-O-R-L-A-X、msk397、gvenusleo、khoaxuantu、RiverTwilight、rongyi、gyt95、zhuoqinyue、K3v123、Zuoxun、mingXta、hello-ikun、FangYuan33、GN-Yu、yuelinxin、longsizhuo、Cathay-Chen、guowei-gong、xBLACKICEx、IsChristina、JoseHung、qualifier1024、QiLOL、pengchzn、Guanngxu、L-Super、WSL0809、Slone123c、lhxsm、yuan0221、what-is-me、theNefelibatas、longranger2、cy-by-side、xiongsp、JeffersonHuang、Transmigration-zhou、magentaqin、Wonderdch、malone6、xiaomiusa87、gaofer、bluebean-cloud、a16su、Shyam-Chen、nanlei、hongyun-robot、Phoenix0415、MolDuM、Nigh、he-weilai、junminhong、mgisr、iron-irax、yd-j、XiaChuerwu、XC-Zero、seven1240、SamJin98、wodray、reeswell、NI-SW、Horbin-Magician、Enlightenus、xjr7670、YangXuanyi、DullSword、boloboloda、iStig、qq909244296、jiaxianhua、wenjianmin、keshida、kilikilikid、lclc6、lwbaptx、liuxjerry、lucaswangdev、lyl625760、hts0000、gledfish、fbigm、echo1937、szu17dmy、dshlstarr、Yucao-cy、coderlef、czruby、bongbongbakudan、beintentional、ZongYangL、ZhongYuuu、luluxia、xb534、bitsmi、ElaBosak233、baagod、zhouLion、yishangzhang、yi427、yabo083、weibk、wangwang105、th1nk3r-ing、tao363、4yDX3906、syd168、steventimes、sslmj2020、smilelsb、siqyka、selear、sdshaoda、Xi-Row、popozhu、nuquist19、noobcodemaker、XiaoK29、chadyi、ZhongGuanbin、shanghai-Jerry、JackYang-hellobobo、Javesun99、lipusheng、BlindTerran、ShiMaRing、FreddieLi、FloranceYeh、iFleey、fanchenggang、gltianwen、goerll、Dr-XYZ、nedchu、curly210102、CuB3y0nd、KraHsu、CarrotDLaw、youshaoXG、bubble9um、fanenr、eagleanurag、LifeGoesOnionOnionOnion、52coder、foursevenlove、KorsChen、hezhizhen、linzeyan、ZJKung、GaochaoZhu、hopkings2008、yang-le、Evilrabbit520、Turing-1024-Lee、thomasq0、Suremotoo、Allen-Scai、Risuntsy、Richard-Zhang1019、qingpeng9802、primexiao、nidhoggfgg、1ch0、MwumLi、martinx、ZnYang2018、hugtyftg、logan-qiu、psychelzh、Keynman、KeiichiKasai 和 0130w
本书的代码审阅工作由 codingonion、curtishd、Gonglja、gvenusleo、hpstory、justin-tse、khoaxuantu、krahets、night-cruise、nuomi1 和 Reanon 完成(按照首字母顺序排列)。感谢他们付出的时间与精力,正是他们确保了各语言代码的规范与统一。
本书的代码审阅工作由 coderonion、curtishd、Gonglja、gvenusleo、hpstory、justin-tse、khoaxuantu、krahets、night-cruise、nuomi1、Reanon 和 rongyi 完成(按照首字母顺序排列)。感谢他们付出的时间与精力,正是他们确保了各语言代码的规范与统一。
在本书的创作过程中,我得到了许多人的帮助。

View file

@ -258,9 +258,9 @@
<h3>代码审阅者</h3>
<div class="profile-div">
<div class="profile-cell">
<a href="https://github.com/codingonion">
<img class="profile-img" src="assets/avatar/avatar_codingonion.jpg" alt="Reviewer: codingonion" />
<br><b>codingonion</b>
<a href="https://github.com/coderonion">
<img class="profile-img" src="assets/avatar/avatar_coderonion.jpg" alt="Reviewer: coderonion" />
<br><b>coderonion</b>
<br><sub>Zig, Rust</sub>
</a>
</div>

View file

@ -32,14 +32,14 @@ That is, our contributors are computer scientists, engineers, and students from
> [!important]
> Before diving in, ensure you're comfortable with the GitHub pull request workflow and have read the "Translation standards" and "Pseudo-code for translation" below.
1. **Self-assignment**: Visit [GitHub projects](https://github.com/users/krahets/projects/2/views/4) to select an unclaimed task and mark it as `In Progress`.
2. **Translation**: We encourage preserving the original meaning while ensuring the translation is natural and fluent.
3. **Peer review**: Please carefully check your changes before submitting a Pull Request (PR). After approval by two reviewers, it will be merged into the project.
1. **Task assignment**: Self-assign a task in the Notion workspace.
2. **Translation**: Optimize the translation on your local PC, referring to the “Translation Pseudo-Code” section below for more details.
3. **Peer review**: Carefully review your changes before submitting a Pull Request (PR). The PR will be merged into the main branch after approval from two reviewers.
## Translation standards
> [!tip]
> The "Accuracy" and "Authenticity" are primarily handled by native Chinese speakers and native English speakers, respectively.
> **The "Accuracy" and "Authenticity" are primarily handled by native Chinese speakers and native English speakers, respectively.**
>
> In some instances, "Accuracy (consistency)" and "Authenticity" represent a trade-off, where optimizing one aspect could significantly affect the other. In such cases, please leave a comment in the pull request for discussion.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View file

@ -30,9 +30,9 @@ The main content of the book is shown in the figure below.
## Acknowledgements
This book is continuously improved with the joint efforts of many contributors from the open-source community. Thanks to each writer who invested their time and energy, listed in the order generated by GitHub: krahets, codingonion, nuomi1, Gonglja, Reanon, justin-tse, danielsss, hpstory, S-N-O-R-L-A-X, night-cruise, msk397, gvenusleo, RiverTwilight, gyt95, zhuoqinyue, Zuoxun, Xia-Sang, mingXta, FangYuan33, GN-Yu, IsChristina, xBLACKICEx, guowei-gong, Cathay-Chen, mgisr, JoseHung, qualifier1024, pengchzn, Guanngxu, longsizhuo, L-Super, what-is-me, yuan0221, lhxsm, Slone123c, WSL0809, longranger2, theNefelibatas, xiongsp, JeffersonHuang, hongyun-robot, K3v123, yuelinxin, a16su, gaofer, malone6, Wonderdch, xjr7670, DullSword, Horbin-Magician, NI-SW, reeswell, XC-Zero, XiaChuerwu, yd-j, iron-irax, huawuque404, MolDuM, Nigh, KorsChen, foursevenlove, 52coder, bubble9um, youshaoXG, curly210102, gltianwen, fanchenggang, Transmigration-zhou, FloranceYeh, FreddieLi, ShiMaRing, lipusheng, Javesun99, JackYang-hellobobo, shanghai-Jerry, 0130w, Keynman, psychelzh, logan-qiu, ZnYang2018, MwumLi, 1ch0, Phoenix0415, qingpeng9802, Richard-Zhang1019, QiLOL, Suremotoo, Turing-1024-Lee, Evilrabbit520, GaochaoZhu, ZJKung, linzeyan, hezhizhen, ZongYangL, beintentional, czruby, coderlef, dshlstarr, szu17dmy, fbigm, gledfish, hts0000, boloboloda, iStig, jiaxianhua, wenjianmin, keshida, kilikilikid, lclc6, lwbaptx, liuxjerry, lucaswangdev, lyl625760, chadyi, noobcodemaker, selear, siqyka, syd168, 4yDX3906, tao363, wangwang105, weibk, yabo083, yi427, yishangzhang, zhouLion, baagod, ElaBosak233, xb534, luluxia, yanedie, thomasq0, YangXuanyi and th1nk3r-ing.
This book is continuously improved with the joint efforts of many contributors from the open-source community. Thanks to each writer who invested their time and energy, listed in the order generated by GitHub: krahets, coderonion, Gonglja, nuomi1, Reanon, justin-tse, hpstory, danielsss, curtishd, night-cruise, S-N-O-R-L-A-X, msk397, gvenusleo, khoaxuantu, RiverTwilight, rongyi, gyt95, zhuoqinyue, K3v123, Zuoxun, mingXta, hello-ikun, FangYuan33, GN-Yu, yuelinxin, longsizhuo, Cathay-Chen, guowei-gong, xBLACKICEx, IsChristina, JoseHung, qualifier1024, QiLOL, pengchzn, Guanngxu, L-Super, WSL0809, Slone123c, lhxsm, yuan0221, what-is-me, theNefelibatas, longranger2, cy-by-side, xiongsp, JeffersonHuang, Transmigration-zhou, magentaqin, Wonderdch, malone6, xiaomiusa87, gaofer, bluebean-cloud, a16su, Shyam-Chen, nanlei, hongyun-robot, Phoenix0415, MolDuM, Nigh, he-weilai, junminhong, mgisr, iron-irax, yd-j, XiaChuerwu, XC-Zero, seven1240, SamJin98, wodray, reeswell, NI-SW, Horbin-Magician, Enlightenus, xjr7670, YangXuanyi, DullSword, boloboloda, iStig, qq909244296, jiaxianhua, wenjianmin, keshida, kilikilikid, lclc6, lwbaptx, liuxjerry, lucaswangdev, lyl625760, hts0000, gledfish, fbigm, echo1937, szu17dmy, dshlstarr, Yucao-cy, coderlef, czruby, bongbongbakudan, beintentional, ZongYangL, ZhongYuuu, luluxia, xb534, bitsmi, ElaBosak233, baagod, zhouLion, yishangzhang, yi427, yabo083, weibk, wangwang105, th1nk3r-ing, tao363, 4yDX3906, syd168, steventimes, sslmj2020, smilelsb, siqyka, selear, sdshaoda, Xi-Row, popozhu, nuquist19, noobcodemaker, XiaoK29, chadyi, ZhongGuanbin, shanghai-Jerry, JackYang-hellobobo, Javesun99, lipusheng, BlindTerran, ShiMaRing, FreddieLi, FloranceYeh, iFleey, fanchenggang, gltianwen, goerll, Dr-XYZ, nedchu, curly210102, CuB3y0nd, KraHsu, CarrotDLaw, youshaoXG, bubble9um, fanenr, eagleanurag, LifeGoesOnionOnionOnion, 52coder, foursevenlove, KorsChen, hezhizhen, linzeyan, ZJKung, GaochaoZhu, hopkings2008, yang-le, Evilrabbit520, Turing-1024-Lee, thomasq0, Suremotoo, Allen-Scai, Risuntsy, Richard-Zhang1019, qingpeng9802, primexiao, nidhoggfgg, 1ch0, MwumLi, martinx, ZnYang2018, hugtyftg, logan-qiu, psychelzh, Keynman, KeiichiKasai and 0130w.
The code review work for this book was completed by codingonion, Gonglja, gvenusleo, hpstory, justintse, khoaxuantu, krahets, night-cruise, nuomi1, and Reanon (listed in alphabetical order). Thanks to them for their time and effort, ensuring the standardization and uniformity of the code in various languages.
The code review work for this book was completed by coderonion, Gonglja, gvenusleo, hpstory, justintse, khoaxuantu, krahets, night-cruise, nuomi1, Reanon and rongyi (listed in alphabetical order). Thanks to them for their time and effort, ensuring the standardization and uniformity of the code in various languages.
Throughout the creation of this book, numerous individuals provided invaluable assistance, including but not limited to:

View file

@ -1,24 +1,24 @@
# Binary search
<u>Binary search</u> is an efficient search algorithm based on the divide-and-conquer strategy. It utilizes the orderliness of data, reducing the search range by half each round until the target element is found or the search interval is empty.
<u>Binary search</u> is an efficient search algorithm that uses a divide-and-conquer strategy. It takes advantage of the sorted order of elements in an array by reducing the search interval by half in each iteration, continuing until either the target element is found or the search interval becomes empty.
!!! question
Given an array `nums` of length $n$, with elements arranged in ascending order and non-repeating. Please find and return the index of element `target` in this array. If the array does not contain the element, return $-1$. An example is shown in the figure below.
Given an array `nums` of length $n$, where elements are arranged in ascending order without duplicates. Please find and return the index of element `target` in this array. If the array does not contain the element, return $-1$. An example is shown in the figure below.
![Binary search example data](binary_search.assets/binary_search_example.png)
As shown in the figure below, we first initialize pointers $i = 0$ and $j = n - 1$, pointing to the first and last elements of the array, representing the search interval $[0, n - 1]$. Please note that square brackets indicate a closed interval, which includes the boundary values themselves.
As shown in the figure below, we firstly initialize pointers with $i = 0$ and $j = n - 1$, pointing to the first and last element of the array respectively. They also represent the whole search interval $[0, n - 1]$. Please note that square brackets indicate a closed interval, which includes the boundary values themselves.
Next, perform the following two steps in a loop.
And then the following two steps may be performed in a loop.
1. Calculate the midpoint index $m = \lfloor {(i + j) / 2} \rfloor$, where $\lfloor \: \rfloor$ denotes the floor operation.
2. Compare the size of `nums[m]` and `target`, divided into the following three scenarios.
2. Based on the comparison between the value of `nums[m]` and `target`, one of the following three cases will be chosen to execute.
1. If `nums[m] < target`, it indicates that `target` is in the interval $[m + 1, j]$, thus set $i = m + 1$.
2. If `nums[m] > target`, it indicates that `target` is in the interval $[i, m - 1]$, thus set $j = m - 1$.
3. If `nums[m] = target`, it indicates that `target` is found, thus return index $m$.
If the array does not contain the target element, the search interval will eventually reduce to empty. In this case, return $-1$.
If the array does not contain the target element, the search interval will eventually reduce to empty, ending up returning $-1$.
=== "<1>"
![Binary search process](binary_search.assets/binary_search_step1.png)
@ -41,7 +41,7 @@ If the array does not contain the target element, the search interval will event
=== "<7>"
![binary_search_step7](binary_search.assets/binary_search_step7.png)
It's worth noting that since $i$ and $j$ are both of type `int`, **$i + j$ might exceed the range of `int` type**. To avoid large number overflow, we usually use the formula $m = \lfloor {i + (j - i) / 2} \rfloor$ to calculate the midpoint.
It's worth noting that as $i$ and $j$ are both of type `int`, **$i + j$ might exceed the range of `int` type**. To avoid large number overflow, we usually use the formula $m = \lfloor {i + (j - i) / 2} \rfloor$ to calculate the midpoint.
The code is as follows:
@ -49,13 +49,13 @@ The code is as follows:
[file]{binary_search}-[class]{}-[func]{binary_search}
```
**Time complexity is $O(\log n)$** : In the binary loop, the interval reduces by half each round, hence the number of iterations is $\log_2 n$.
**Time complexity is $O(\log n)$** : In the binary loop, the interval decreases by half each round, hence the number of iterations is $\log_2 n$.
**Space complexity is $O(1)$** : Pointers $i$ and $j$ use constant size space.
**Space complexity is $O(1)$** : Pointers $i$ and $j$ occupies constant size of space.
## Interval representation methods
Besides the aforementioned closed interval, a common interval representation is the "left-closed right-open" interval, defined as $[0, n)$, where the left boundary includes itself, and the right boundary does not include itself. In this representation, the interval $[i, j)$ is empty when $i = j$.
Besides the above closed interval, another common interval representation is the "left-closed right-open" interval, defined as $[0, n)$, where the left boundary includes itself, and the right boundary does not. In this representation, the interval $[i, j)$ is empty when $i = j$.
We can implement a binary search algorithm with the same functionality based on this representation:
@ -63,9 +63,9 @@ We can implement a binary search algorithm with the same functionality based on
[file]{binary_search}-[class]{}-[func]{binary_search_lcro}
```
As shown in the figure below, in the two types of interval representations, the initialization of the binary search algorithm, the loop condition, and the narrowing interval operation are different.
As shown in the figure below, under the two types of interval representations, the initialization, loop condition, and narrowing interval operation of the binary search algorithm differ.
Since both boundaries in the "closed interval" representation are defined as closed, the operations to narrow the interval through pointers $i$ and $j$ are also symmetrical. This makes it less prone to errors, **therefore, it is generally recommended to use the "closed interval" approach**.
Since both boundaries in the "closed interval" representation are inclusive, the operations to narrow the interval through pointers $i$ and $j$ are also symmetrical. This makes it less prone to errors, **therefore, it is generally recommended to use the "closed interval" approach**.
![Two types of interval definitions](binary_search.assets/binary_search_ranges.png)
@ -73,11 +73,11 @@ Since both boundaries in the "closed interval" representation are defined as clo
Binary search performs well in both time and space aspects.
- Binary search is time-efficient. With large data volumes, the logarithmic time complexity has a significant advantage. For instance, when the data size $n = 2^{20}$, linear search requires $2^{20} = 1048576$ iterations, while binary search only requires $\log_2 2^{20} = 20$ iterations.
- Binary search does not require extra space. Compared to search algorithms that rely on additional space (like hash search), binary search is more space-efficient.
- Binary search is time-efficient. With large dataset, the logarithmic time complexity offers a major advantage. For instance, given a dataset with size $n = 2^{20}$, linear search requires $2^{20} = 1048576$ iterations, while binary search only demands $\log_2 2^{20} = 20$ loops.
- Binary search does not need extra space. Compared to search algorithms that rely on additional space (like hash search), binary search is more space-efficient.
However, binary search is not suitable for all situations, mainly for the following reasons.
However, binary search may not be suitable for all scenarios due to the following concerns.
- Binary search is only applicable to ordered data. If the input data is unordered, it is not worth sorting it just to use binary search, as sorting algorithms typically have a time complexity of $O(n \log n)$, which is higher than both linear and binary search. For scenarios with frequent element insertion to maintain array order, inserting elements into specific positions has a time complexity of $O(n)$, which is also quite costly.
- Binary search is only applicable to arrays. Binary search requires non-continuous (jumping) element access, which is inefficient in linked lists, thus not suitable for use in linked lists or data structures based on linked lists.
- With small data volumes, linear search performs better. In linear search, each round only requires 1 decision operation; whereas in binary search, it involves 1 addition, 1 division, 1 to 3 decision operations, 1 addition (subtraction), totaling 4 to 6 operations; therefore, when data volume $n$ is small, linear search can be faster than binary search.
- Binary search can only be applied to sorted data. Unsorted data must be sorted before applying binary search, which may not be worthwhile as sorting algorithm typically has a time complexity of $O(n \log n)$. Such cost is even higher than linear search, not to mention binary search itself. For scenarios with frequent insertion, the cost of remaining the array in order is pretty high as the time complexity of inserting new elements into specific positions is $O(n)$.
- Binary search may use array only. Binary search requires non-continuous (jumping) element access, which is inefficient in linked list. As a result, linked list or data structures based on linked list may not be suitable for this algorithm.
- Linear search performs better on small dataset. In linear search, only 1 decision operation is required for each iteration; whereas in binary search, it involves 1 addition, 1 division, 1 to 3 decision operations, 1 addition (subtraction), totaling 4 to 6 operations. Therefore, if data size $n$ is small, linear search is faster than binary search.

View file

@ -1,6 +1,6 @@
# Hash optimization strategies
In algorithm problems, **we often reduce the time complexity of algorithms by replacing linear search with hash search**. Let's use an algorithm problem to deepen understanding.
In algorithm problems, **we often reduce the time complexity of an algorithm by replacing a linear search with a hash-based search**. Let's use an algorithm problem to deepen the understanding.
!!! question
@ -8,7 +8,7 @@ In algorithm problems, **we often reduce the time complexity of algorithms by re
## Linear search: trading time for space
Consider traversing all possible combinations directly. As shown in the figure below, we initiate a two-layer loop, and in each round, we determine whether the sum of the two integers equals `target`. If so, we return their indices.
Consider traversing through all possible combinations directly. As shown in the figure below, we initiate a nested loop, and in each iteration, we determine whether the sum of the two integers equals `target`. If so, we return their indices.
![Linear search solution for two-sum problem](replace_linear_by_hashing.assets/two_sum_brute_force.png)
@ -18,11 +18,11 @@ The code is shown below:
[file]{two_sum}-[class]{}-[func]{two_sum_brute_force}
```
This method has a time complexity of $O(n^2)$ and a space complexity of $O(1)$, which is very time-consuming with large data volumes.
This method has a time complexity of $O(n^2)$ and a space complexity of $O(1)$, which can be very time-consuming with large data volumes.
## Hash search: trading space for time
Consider using a hash table, with key-value pairs being the array elements and their indices, respectively. Loop through the array, performing the steps shown in the figure below each round.
Consider using a hash table, where the key-value pairs are the array elements and their indices, respectively. Loop through the array, performing the steps shown in the figure below during each iteration.
1. Check if the number `target - nums[i]` is in the hash table. If so, directly return the indices of these two elements.
2. Add the key-value pair `nums[i]` and index `i` to the hash table.
@ -42,6 +42,6 @@ The implementation code is shown below, requiring only a single loop:
[file]{two_sum}-[class]{}-[func]{two_sum_hash_table}
```
This method reduces the time complexity from $O(n^2)$ to $O(n)$ by using hash search, greatly improving the running efficiency.
This method reduces the time complexity from $O(n^2)$ to $O(n)$ by using hash search, significantly enhancing runtime efficiency.
As it requires maintaining an additional hash table, the space complexity is $O(n)$. **Nevertheless, this method has a more balanced time-space efficiency overall, making it the optimal solution for this problem**.

View file

@ -258,9 +258,9 @@
<h3>Code reviewers</h3>
<div class="profile-div">
<div class="profile-cell">
<a href="https://github.com/codingonion">
<img class="profile-img" src="../assets/avatar/avatar_codingonion.jpg" alt="Reviewer: codingonion" />
<br><b>codingonion</b>
<a href="https://github.com/coderonion">
<img class="profile-img" src="../assets/avatar/avatar_coderonion.jpg" alt="Reviewer: coderonion" />
<br><b>coderonion</b>
<br><sub>Zig, Rust</sub>
</a>
</div>
@ -414,7 +414,7 @@
<!-- contributors -->
<div style="margin: 2em auto;">
<h3>Contributors</h3>
<p>This book has been optimized by the efforts of over 180 contributors. We sincerely thank them for their invaluable time and contributions!</p>
<p>This book has been refined by the efforts of over 180 contributors. We sincerely thank them for their invaluable time and contributions!</p>
<a href="https://github.com/krahets/hello-algo/graphs/contributors">
<img src="https://contrib.rocks/image?repo=krahets/hello-algo&max=300&columns=16" alt="Contributors" style="width: 100%; max-width: 38.5em;">
</a>

View file

@ -9,7 +9,7 @@ site_dir: site
repo_name: krahets/hello-algo
repo_url: https://github.com/krahets/hello-algo
edit_uri: tree/main/docs
version: 1.1.0
version: 1.2.0
# Copyright
copyright: Copyright &copy; 2024 krahets<br>The website content is licensed under <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">CC BY-NC-SA 4.0</a>

View file

@ -12,6 +12,8 @@
<p align="center">
<a href="https://www.hello-algo.com/zh-hant/">
<img src="https://www.hello-algo.com/zh-hant/index.assets/btn_read_online_dark.svg" width="145"></a>
<a href="https://github.com/krahets/hello-algo/releases">
<img src="https://www.hello-algo.com/zh-hant/index.assets/btn_download_pdf_dark.svg" width="145"></a>
</p>
<p align="center">

View file

@ -111,16 +111,29 @@ int popLast(ArrayDeque *deque) {
return num;
}
/* 返回陣列用於列印 */
int *toArray(ArrayDeque *deque, int *queSize) {
*queSize = deque->queSize;
int *res = (int *)calloc(deque->queSize, sizeof(int));
int j = deque->front;
for (int i = 0; i < deque->queSize; i++) {
res[i] = deque->nums[j % deque->queCapacity];
j++;
}
return res;
}
/* Driver Code */
int main() {
/* 初始化佇列 */
int capacity = 10;
int queSize;
ArrayDeque *deque = newArrayDeque(capacity);
pushLast(deque, 3);
pushLast(deque, 2);
pushLast(deque, 5);
printf("雙向佇列 deque = ");
printArray(deque->nums, deque->queSize);
printArray(toArray(deque, &queSize), queSize);
/* 訪問元素 */
int peekFirstNum = peekFirst(deque);
@ -131,18 +144,18 @@ int main() {
/* 元素入列 */
pushLast(deque, 4);
printf("元素 4 佇列尾入列後 deque = ");
printArray(deque->nums, deque->queSize);
printArray(toArray(deque, &queSize), queSize);
pushFirst(deque, 1);
printf("元素 1 佇列首入列後 deque = ");
printArray(deque->nums, deque->queSize);
printArray(toArray(deque, &queSize), queSize);
/* 元素出列 */
int popLastNum = popLast(deque);
printf("佇列尾出列元素 = %d ,佇列尾出列後 deque= ", popLastNum);
printArray(deque->nums, deque->queSize);
printArray(toArray(deque, &queSize), queSize);
int popFirstNum = popFirst(deque);
printf("佇列首出列元素 = %d ,佇列首出列後 deque= ", popFirstNum);
printArray(deque->nums, deque->queSize);
printArray(toArray(deque, &queSize), queSize);
/* 獲取佇列的長度 */
int dequeSize = size(deque);
@ -156,4 +169,4 @@ int main() {
delArrayDeque(deque);
return 0;
}
}

View file

@ -74,10 +74,23 @@ int pop(ArrayQueue *queue) {
return num;
}
/* 返回陣列用於列印 */
int *toArray(ArrayQueue *queue, int *queSize) {
*queSize = queue->queSize;
int *res = (int *)calloc(queue->queSize, sizeof(int));
int j = queue->front;
for (int i = 0; i < queue->queSize; i++) {
res[i] = queue->nums[j % queue->queCapacity];
j++;
}
return res;
}
/* Driver Code */
int main() {
/* 初始化佇列 */
int capacity = 10;
int queSize;
ArrayQueue *queue = newArrayQueue(capacity);
/* 元素入列 */
@ -87,7 +100,7 @@ int main() {
push(queue, 5);
push(queue, 4);
printf("佇列 queue = ");
printArray(queue->nums, queue->queSize);
printArray(toArray(queue, &queSize), queSize);
/* 訪問佇列首元素 */
int peekNum = peek(queue);
@ -96,7 +109,7 @@ int main() {
/* 元素出列 */
peekNum = pop(queue);
printf("出列元素 pop = %d ,出列後 queue = ", peekNum);
printArray(queue->nums, queue->queSize);
printArray(toArray(queue, &queSize), queSize);
/* 獲取佇列的長度 */
int queueSize = size(queue);
@ -111,11 +124,11 @@ int main() {
push(queue, i);
pop(queue);
printf("第 %d 輪入列 + 出列後 queue = ", i);
printArray(queue->nums, queue->queSize);
printArray(toArray(queue, &queSize), queSize);
}
// 釋放記憶體
delArrayQueue(queue);
return 0;
}
}

View file

@ -115,9 +115,9 @@ int main() {
int i = 1;
int l = abt.left(i), r = abt.right(i), p = abt.parent(i);
cout << "\n當前節點的索引為 " << i << ",值為 " << abt.val(i) << "\n";
cout << "其左子節點的索引為 " << l << ",值為 " << (l != INT_MAX ? to_string(abt.val(l)) : "nullptr") << "\n";
cout << "其右子節點的索引為 " << r << ",值為 " << (r != INT_MAX ? to_string(abt.val(r)) : "nullptr") << "\n";
cout << "其父節點的索引為 " << p << ",值為 " << (p != INT_MAX ? to_string(abt.val(p)) : "nullptr") << "\n";
cout << "其左子節點的索引為 " << l << ",值為 " << (abt.val(l) != INT_MAX ? to_string(abt.val(l)) : "nullptr") << "\n";
cout << "其右子節點的索引為 " << r << ",值為 " << (abt.val(r) != INT_MAX ? to_string(abt.val(r)) : "nullptr") << "\n";
cout << "其父節點的索引為 " << p << ",值為 " << (abt.val(p) != INT_MAX ? to_string(abt.val(p)) : "nullptr") << "\n";
// 走訪樹
vector<int> res = abt.levelOrder();

View file

@ -46,7 +46,8 @@ class GraphAdjList {
if (
!this.adjList.has(vet1) ||
!this.adjList.has(vet2) ||
vet1 === vet2
vet1 === vet2 ||
this.adjList.get(vet1).indexOf(vet2) === -1
) {
throw new Error('Illegal Argument Exception');
}

View file

@ -46,7 +46,8 @@ class GraphAdjList {
if (
!this.adjList.has(vet1) ||
!this.adjList.has(vet2) ||
vet1 === vet2
vet1 === vet2 ||
this.adjList.get(vet1).indexOf(vet2) === -1
) {
throw new Error('Illegal Argument Exception');
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 434 KiB

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 465 KiB

After

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 477 KiB

After

Width:  |  Height:  |  Size: 122 KiB

View file

@ -50,6 +50,7 @@
| front of the queue | 队首 | 佇列首 |
| rear of the queue | 队尾 | 佇列尾 |
| hash table | 哈希表 | 雜湊表 |
| hash set | 哈希集合 | 雜湊集合 |
| bucket | 桶 | 桶 |
| hash function | 哈希函数 | 雜湊函式 |
| hash collision | 哈希冲突 | 雜湊衝突 |

View file

@ -71,6 +71,16 @@
另一方面,必要使用鏈結串列的情況主要是二元樹和圖。堆疊和佇列往往會使用程式語言提供的 `stack``queue` ,而非鏈結串列。
**Q**初始化串列 `res = [0] * self.size()` 操作,會導致 `res` 的每個元素引用相同的位址嗎?
**Q**操作 `res = [[0]] * n` 生成了一個二維串列,其中每一個 `[0]` 都是獨立的嗎?
不會。但二維陣列會有這個問題,例如初始化二維串列 `res = [[0]] * self.size()` ,則多次引用了同一個串列 `[0]`
不是獨立的。此二維串列中,所有的 `[0]` 實際上是同一個物件的引用。如果我們修改其中一個元素,會發現所有的對應元素都會隨之改變。
如果希望二維串列中的每個 `[0]` 都是獨立的,可以使用 `res = [[0] for _ in range(n)]` 來實現。這種方式的原理是初始化了 $n$ 個獨立的 `[0]` 串列物件。
**Q**:操作 `res = [0] * n` 生成了一個串列,其中每一個整數 0 都是獨立的嗎?
在該串列中,所有整數 0 都是同一個物件的引用。這是因為 Python 對小整數(通常是 -5 到 256採用了快取池機制以便最大化物件複用從而提升效能。
雖然它們指向同一個物件,但我們仍然可以獨立修改串列中的每個元素,這是因為 Python 的整數是“不可變物件”。當我們修改某個元素時,實際上是切換為另一個物件的引用,而不是改變原有物件本身。
然而,當串列元素是“可變物件”時(例如串列、字典或類別例項等),修改某個元素會直接改變該物件本身,所有引用該物件的元素都會產生相同變化。

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View file

@ -1120,7 +1120,7 @@ $$
生物學的“細胞分裂”是指數階增長的典型例子:初始狀態為 $1$ 個細胞,分裂一輪後變為 $2$ 個,分裂兩輪後變為 $4$ 個,以此類推,分裂 $n$ 輪後有 $2^n$ 個細胞。
下圖和以下程式碼模擬了細胞分裂的過程,時間複雜度為 $O(2^n)$
下圖和以下程式碼模擬了細胞分裂的過程,時間複雜度為 $O(2^n)$ 。請注意,輸入 $n$ 表示分裂輪數,返回值 `count` 表示總分裂次數。
```src
[file]{time_complexity}-[class]{}-[func]{exponential}

View file

@ -5,7 +5,7 @@
- 整理撲克的過程與插入排序演算法非常類似。插入排序演算法適合排序小型資料集。
- 貨幣找零的步驟本質上是貪婪演算法,每一步都採取當前看來最好的選擇。
- 演算法是在有限時間內解決特定問題的一組指令或操作步驟,而資料結構是計算機中組織和儲存資料的方式。
- 資料結構與演算法緊密相連。資料結構是演算法的基石,而演算法是資料結構發揮作用的舞臺
- 資料結構與演算法緊密相連。資料結構是演算法的基石,而演算法為資料結構注入生命力
- 我們可以將資料結構與演算法類比為拼裝積木,積木代表資料,積木的形狀和連線方式等代表資料結構,拼裝積木的步驟則對應演算法。
### Q & A

View file

@ -26,7 +26,7 @@
如下圖所示,資料結構與演算法高度相關、緊密結合,具體表現在以下三個方面。
- 資料結構是演算法的基石。資料結構為演算法提供了結構化儲存的資料,以及操作資料的方法。
- 演算法是資料結構發揮作用的舞臺。資料結構本身僅儲存資料資訊,結合演算法才能解決特定問題。
- 演算法為資料結構注入生命力。資料結構本身僅儲存資料資訊,結合演算法才能解決特定問題。
- 演算法通常可以基於不同的資料結構實現,但執行效率可能相差很大,選擇合適的資料結構是關鍵。
![資料結構與演算法的關係](what_is_dsa.assets/relationship_between_data_structure_and_algorithm.png)

View file

@ -30,9 +30,9 @@
## 致謝
本書在開源社群眾多貢獻者的共同努力下不斷完善。感謝每一位投入時間與精力的撰稿人,他們是(按照 GitHub 自動生成的順序krahets、Gonglja、nuomi1、codingonion、Reanon、justin-tse、hpstory、danielsss、curtishd、night-cruise、S-N-O-R-L-A-X、msk397、gvenusleo、RiverTwilight、gyt95、zhuoqinyue、Zuoxun、mingXta、hello-ikun、khoaxuantu、FangYuan33、GN-Yu、longsizhuo、mgisr、Cathay-Chen、guowei-gong、xBLACKICEx、K3v123、IsChristina、JoseHung、qualifier1024、pengchzn、Guanngxu、QiLOL、L-Super、WSL0809、Slone123c、lhxsm、yuan0221、what-is-me、rongyi、JeffersonHuang、longranger2、theNefelibatas、yuelinxin、xiongsp、nanlei、a16su、cy-by-side、gaofer、malone6、Wonderdch、hongyun-robot、XiaChuerwu、yd-j、bluebean-cloud、iron-irax、he-weilai、Nigh、MolDuM、Phoenix0415、XC-Zero、SamJin98、reeswell、NI-SW、Horbin-Magician、xjr7670、YangXuanyi、DullSword、iStig、qq909244296、jiaxianhua、wenjianmin、keshida、kilikilikid、lclc6、lwbaptx、luluxia、boloboloda、hts0000、gledfish、fbigm、echo1937、szu17dmy、dshlstarr、coderlef、czruby、beintentional、KeiichiKasai、xb534、ElaBosak233、baagod、zhouLion、yishangzhang、yi427、yabo083、weibk、wangwang105、th1nk3r-ing、tao363、4yDX3906、syd168、siqyka、selear、sdshaoda、noobcodemaker、chadyi、lyl625760、lucaswangdev、liuxjerry、0130w、shanghai-Jerry、JackYang-hellobobo、Javesun99、lipusheng、ShiMaRing、FreddieLi、FloranceYeh、Transmigration-zhou、fanchenggang、gltianwen、Dr-XYZ、curly210102、CuB3y0nd、youshaoXG、bubble9um、fanenr、52coder、foursevenlove、KorsChen、ZongYangL、hezhizhen、linzeyan、ZJKung、GaochaoZhu、yang-le、Evilrabbit520、Turing-1024-Lee、Suremotoo、Allen-Scai、Richard-Zhang1019、qingpeng9802、primexiao、nidhoggfgg、1ch0、MwumLi、ZnYang2018、hugtyftg、logan-qiu、psychelzh 和 Keynman
本書在開源社群眾多貢獻者的共同努力下不斷完善。感謝每一位投入時間與精力的撰稿人,他們是(按照 GitHub 自動生成的順序krahets、coderonion、Gonglja、nuomi1、Reanon、justin-tse、hpstory、danielsss、curtishd、night-cruise、S-N-O-R-L-A-X、msk397、gvenusleo、khoaxuantu、RiverTwilight、rongyi、gyt95、zhuoqinyue、K3v123、Zuoxun、mingXta、hello-ikun、FangYuan33、GN-Yu、yuelinxin、longsizhuo、Cathay-Chen、guowei-gong、xBLACKICEx、IsChristina、JoseHung、qualifier1024、QiLOL、pengchzn、Guanngxu、L-Super、WSL0809、Slone123c、lhxsm、yuan0221、what-is-me、theNefelibatas、longranger2、cy-by-side、xiongsp、JeffersonHuang、Transmigration-zhou、magentaqin、Wonderdch、malone6、xiaomiusa87、gaofer、bluebean-cloud、a16su、Shyam-Chen、nanlei、hongyun-robot、Phoenix0415、MolDuM、Nigh、he-weilai、junminhong、mgisr、iron-irax、yd-j、XiaChuerwu、XC-Zero、seven1240、SamJin98、wodray、reeswell、NI-SW、Horbin-Magician、Enlightenus、xjr7670、YangXuanyi、DullSword、boloboloda、iStig、qq909244296、jiaxianhua、wenjianmin、keshida、kilikilikid、lclc6、lwbaptx、liuxjerry、lucaswangdev、lyl625760、hts0000、gledfish、fbigm、echo1937、szu17dmy、dshlstarr、Yucao-cy、coderlef、czruby、bongbongbakudan、beintentional、ZongYangL、ZhongYuuu、luluxia、xb534、bitsmi、ElaBosak233、baagod、zhouLion、yishangzhang、yi427、yabo083、weibk、wangwang105、th1nk3r-ing、tao363、4yDX3906、syd168、steventimes、sslmj2020、smilelsb、siqyka、selear、sdshaoda、Xi-Row、popozhu、nuquist19、noobcodemaker、XiaoK29、chadyi、ZhongGuanbin、shanghai-Jerry、JackYang-hellobobo、Javesun99、lipusheng、BlindTerran、ShiMaRing、FreddieLi、FloranceYeh、iFleey、fanchenggang、gltianwen、goerll、Dr-XYZ、nedchu、curly210102、CuB3y0nd、KraHsu、CarrotDLaw、youshaoXG、bubble9um、fanenr、eagleanurag、LifeGoesOnionOnionOnion、52coder、foursevenlove、KorsChen、hezhizhen、linzeyan、ZJKung、GaochaoZhu、hopkings2008、yang-le、Evilrabbit520、Turing-1024-Lee、thomasq0、Suremotoo、Allen-Scai、Risuntsy、Richard-Zhang1019、qingpeng9802、primexiao、nidhoggfgg、1ch0、MwumLi、martinx、ZnYang2018、hugtyftg、logan-qiu、psychelzh、Keynman、KeiichiKasai 和 0130w
本書的程式碼審閱工作由 codingonion、curtishd、Gonglja、gvenusleo、hpstory、justin-tse、khoaxuantu、krahets、night-cruise、nuomi1 和 Reanon 完成(按照首字母順序排列)。感謝他們付出的時間與精力,正是他們確保了各語言程式碼的規範與統一。
本書的程式碼審閱工作由 coderonion、curtishd、Gonglja、gvenusleo、hpstory、justin-tse、khoaxuantu、krahets、night-cruise、nuomi1、Reanon 和 rongyi 完成(按照首字母順序排列)。感謝他們付出的時間與精力,正是他們確保了各語言程式碼的規範與統一。
在本書的創作過程中,我得到了許多人的幫助。

Binary file not shown.

Before

Width:  |  Height:  |  Size: 386 KiB

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 386 KiB

After

Width:  |  Height:  |  Size: 74 KiB

View file

@ -155,7 +155,7 @@
<a href="https://github.com/krahets/hello-algo/releases">
<img class="device-on-hover" style="height: 75%;" src="../assets/hero/pdf_ipad.png" alt="">
<div class="text-button">
<span>PDF(簡中)</span>
<span>下載 PDF</span>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
<path d="M278.6 233.4c12.5 12.5 12.5 32.8 0 45.3l-160 160c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L210.7 256 73.4 118.6c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l160 160z" />
</svg>
@ -258,9 +258,9 @@
<h3>程式碼審閱者</h3>
<div class="profile-div">
<div class="profile-cell">
<a href="https://github.com/codingonion">
<img class="profile-img" src="../assets/avatar/avatar_codingonion.jpg" alt="Reviewer: codingonion" />
<br><b>codingonion</b>
<a href="https://github.com/coderonion">
<img class="profile-img" src="../assets/avatar/avatar_coderonion.jpg" alt="Reviewer: coderonion" />
<br><b>coderonion</b>
<br><sub>Zig, Rust</sub>
</a>
</div>

View file

@ -9,7 +9,7 @@ docs_dir: ../build/zh-hant/docs
site_dir: ../site/zh-hant
# Repository
edit_uri: tree/main/zh-hant/docs
version: 1.1.0
version: 1.2.0
# Configuration
theme: