mirror of
https://github.com/krahets/hello-algo.git
synced 2026-08-29 19:37:14 +00:00
build
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
---
|
||||
comments: true
|
||||
---
|
||||
|
||||
# 0.1 關於本書
|
||||
|
||||
本專案旨在建立一本開源、免費、對新手友好的資料結構與演算法入門教程。
|
||||
|
||||
- 全書採用動畫圖解,內容清晰易懂、學習曲線平滑,引導初學者探索資料結構與演算法的知識地圖。
|
||||
- 源程式碼可一鍵執行,幫助讀者在練習中提升程式設計技能,瞭解演算法工作原理和資料結構底層實現。
|
||||
- 提倡讀者互助學習,歡迎大家在評論區提出問題與分享見解,在交流討論中共同進步。
|
||||
|
||||
## 0.1.1 目標讀者
|
||||
|
||||
若你是演算法初學者,從未接觸過演算法,或者已經有一些刷題經驗,對資料結構與演算法有模糊的認識,在會與不會之間反覆橫跳,那麼本書正是為你量身定製的!
|
||||
|
||||
如果你已經積累一定的刷題量,熟悉大部分題型,那麼本書可助你回顧與梳理演算法知識體系,倉庫源程式碼可以當作“刷題工具庫”或“演算法字典”來使用。
|
||||
|
||||
若你是演算法“大神”,我們期待收到你的寶貴建議,或者[一起參與創作](https://www.hello-algo.com/chapter_appendix/contribution/)。
|
||||
|
||||
!!! success "前置條件"
|
||||
|
||||
你需要至少具備任一語言的程式設計基礎,能夠閱讀和編寫簡單程式碼。
|
||||
|
||||
## 0.1.2 內容結構
|
||||
|
||||
本書的主要內容如圖 0-1 所示。
|
||||
|
||||
- **複雜度分析**:資料結構和演算法的評價維度與方法。時間複雜度和空間複雜度的推算方法、常見型別、示例等。
|
||||
- **資料結構**:基本資料型別和資料結構的分類方法。陣列、鏈結串列、堆疊、佇列、雜湊表、樹、堆積、圖等資料結構的定義、優缺點、常用操作、常見型別、典型應用、實現方法等。
|
||||
- **演算法**:搜尋、排序、分治、回溯、動態規劃、貪婪等演算法的定義、優缺點、效率、應用場景、解題步驟和示例問題等。
|
||||
|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 圖 0-1 本書主要內容 </p>
|
||||
|
||||
## 0.1.3 致謝
|
||||
|
||||
本書在開源社群眾多貢獻者的共同努力下不斷完善。感謝每一位投入時間與精力的撰稿人,他們是(按照 GitHub 自動生成的順序):krahets、coderonion、Gonglja、nuomi1、Reanon、justin-tse、hpstory、danielsss、curtishd、night-cruise、S-N-O-R-L-A-X、rongyi、msk397、gvenusleo、khoaxuantu、rivertwilight、K3v123、gyt95、zhuoqinyue、yuelinxin、Zuoxun、mingXta、Phoenix0415、FangYuan33、GN-Yu、longsizhuo、pengchzn、QiLOL、Cathay-Chen、guowei-gong、xBLACKICEx、IsChristina、JoseHung、qualifier1024、hello-ikun、magentaqin、Guanngxu、thomasq0、sunshinesDL、L-Super、Transmigration-zhou、WSL0809、Slone123c、lhxsm、yuan0221、what-is-me、theNefelibatas、Shyam-Chen、sangxiaai、longranger2、codeberg-user、xiongsp、JeffersonHuang、prinpal、seven1240、Wonderdch、malone6、xiaomiusa87、gaofer、bluebean-cloud、a16su、SamJin98、hongyun-robot、nanlei、XiaChuerwu、yd-j、iron-irax、mgisr、steventimes、junminhong、heshuyue、danny900714、Nigh、Dr-XYZ、MolDuM、XC-Zero、reeswell、PXG-XPG、NI-SW、Horbin-Magician、Enlightenus、YangXuanyi、xjr7670、beatrix-chan、DullSword、qq909244296、iStig、boloboloda、hts0000、gledfish、fbigm、echo1937、jiaxianhua、wenjianmin、keshida、kilikilikid、lclc6、lwbaptx、linyejoe2、liuxjerry、szu17dmy、dshlstarr、Yucao-cy、coderlef、czruby、bongbongbakudan、beintentional、ZongYangL、ZhongYuuu、ZhongGuanbin、hezhizhen、linzeyan、ZJKung、JTCPOWI、KawaiiAsh、luluxia、xb534、ztkuaikuai、yw-1021、ElaBosak233、baagod、zhouLion、yishangzhang、yi427、yanedie、yabo083、weibk、wangwang105、th1nk3r-ing、tao363、4yDX3906、syd168、sslmj2020、smilelsb、siqyka、selear、sdshaoda、Xi-Row、popozhu、nuquist19、noobcodemaker、XiaoK29、chadyi、lyl625760、lucaswangdev、llql1211、0130w、shanghai-Jerry、EJackYang、Javesun99、eltociear、lipusheng、KNChiu、BlindTerran、ShiMaRing、lovelock、FreddieLi、FloranceYeh、fanchenggang、gltianwen、goerll、nedchu、curly210102、CuB3y0nd、KraHsu、CarrotDLaw、youshaoXG、bubble9um、Asashishi、Asa0oo0o0o、fanenr、eagleanurag、akshiterate、52coder、foursevenlove、KorsChen、hopkings2008、yang-le、realwujing、Evilrabbit520、Umer-Jahangir、Turing-1024-Lee、Suremotoo、paoxiaomooo、Chieko-Seren、Senrian、Allen-Scai、19santosh99、ymmmas、Risuntsy、Richard-Zhang1019、RafaelCaso、qingpeng9802、primexiao、Urbaner3、codetypess、nidhoggfgg、MwumLi、CreatorMetaSky、martinx、ZnYang2018、hugtyftg、logan-qiu、psychelzh、Kunchen-Luo、Keynman 和 KeiichiKasai。
|
||||
|
||||
本書的程式碼審閱工作由 coderonion、curtishd、Gonglja、gvenusleo、hpstory、justin-tse、khoaxuantu、krahets、night-cruise、nuomi1、Reanon 和 rongyi 完成(按照首字母順序排列)。感謝他們付出的時間與精力,正是他們確保了各語言程式碼的規範與統一。
|
||||
|
||||
本書的英文版由 yuelinxin、K3v123、magentaqin、QiLOL、Phoenix0415、SamJin98、yanedie、RafaelCaso、pengchzn 和 thomasq0 審閱;日文版由 eltociear 審閱;俄文版由 И. А. Шевкун 和 Yuyan Huang 審閱;繁體中文版由 Shyam-Chen 和 Dr-XYZ 審閱。正是因為他們的貢獻,這本書才能夠服務於更廣泛的讀者群體,感謝他們。
|
||||
|
||||
本書的 ePub 電子書生成工具由 zhongfq 開發。感謝他的貢獻,為讀者提供了更靈活的閱讀方式。
|
||||
|
||||
在本書的創作過程中,我得到了許多人的幫助。
|
||||
|
||||
- 感謝我在公司的導師李汐博士,在一次暢談中你鼓勵我“快行動起來”,堅定了我寫這本書的決心;
|
||||
- 感謝我的女朋友泡泡作為本書的首位讀者,從演算法小白的角度提出許多寶貴建議,使得本書更適合新手閱讀;
|
||||
- 感謝騰寶、琦寶、飛寶為本書起了一個富有創意的名字,喚起大家寫下第一行程式碼“Hello World!”的美好回憶;
|
||||
- 感謝校銓在智慧財產權方面提供的專業幫助,這對本開源書的完善起到了重要作用;
|
||||
- 感謝蘇潼為本書設計了精美的封面和 logo ,並在我的強迫症的驅使下多次耐心修改;
|
||||
- 感謝 @squidfunk 提供的排版建議,以及他開發的開源文件主題 [Material-for-MkDocs](https://github.com/squidfunk/mkdocs-material) 。
|
||||
|
||||
在寫作過程中,我閱讀了許多關於資料結構與演算法的教材和文章。這些作品為本書提供了優秀的範本,確保了本書內容的準確性與品質。在此感謝所有老師和前輩的傑出貢獻!
|
||||
|
||||
本書倡導手腦並用的學習方式,在這一點上我深受[《動手學深度學習》](https://github.com/d2l-ai/d2l-zh)的啟發。在此向各位讀者強烈推薦這本優秀的著作。
|
||||
|
||||
**衷心感謝我的父母,正是你們一直以來的支持與鼓勵,讓我有機會做這件富有趣味的事**。
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
comments: true
|
||||
icon: material/book-open-outline
|
||||
---
|
||||
|
||||
# 第 0 章 前言
|
||||
|
||||
{ class="cover-image" }
|
||||
|
||||
!!! abstract
|
||||
|
||||
演算法猶如美妙的交響樂,每一行程式碼都像韻律般流淌。
|
||||
|
||||
願這本書在你的腦海中輕輕響起,留下獨特而深刻的旋律。
|
||||
|
||||
## 本章內容
|
||||
|
||||
- [0.1 關於本書](about_the_book.md)
|
||||
- [0.2 如何使用本書](suggestions.md)
|
||||
- [0.3 小結](summary.md)
|
||||
@@ -0,0 +1,257 @@
|
||||
---
|
||||
comments: true
|
||||
---
|
||||
|
||||
# 0.2 如何使用本書
|
||||
|
||||
!!! tip
|
||||
|
||||
為了獲得最佳的閱讀體驗,建議你通讀本節內容。
|
||||
|
||||
## 0.2.1 行文風格約定
|
||||
|
||||
- 標題後標註 `*` 的是選讀章節,內容相對困難。如果你的時間有限,可以先跳過。
|
||||
- 專業術語會使用黑體(紙質版和 PDF 版)或新增下劃線(網頁版),例如<u>陣列(array)</u>。建議記住它們,以便閱讀文獻。
|
||||
- 重點內容和總結性語句會 **加粗**,這類文字值得特別關注。
|
||||
- 有特指含義的詞句會使用“引號”標註,以避免歧義。
|
||||
- 當涉及程式語言之間不一致的名詞時,本書均以 Python 為準,例如使用 `None` 來表示“空”。
|
||||
- 本書部分放棄了程式語言的註釋規範,以換取更加緊湊的內容排版。註釋主要分為三種類型:標題註釋、內容註釋、多行註釋。
|
||||
|
||||
=== "Python"
|
||||
|
||||
```python title=""
|
||||
"""標題註釋,用於標註函式、類別、測試樣例等"""
|
||||
|
||||
# 內容註釋,用於詳解程式碼
|
||||
|
||||
"""
|
||||
多行
|
||||
註釋
|
||||
"""
|
||||
```
|
||||
|
||||
=== "C++"
|
||||
|
||||
```cpp title=""
|
||||
/* 標題註釋,用於標註函式、類別、測試樣例等 */
|
||||
|
||||
// 內容註釋,用於詳解程式碼
|
||||
|
||||
/**
|
||||
* 多行
|
||||
* 註釋
|
||||
*/
|
||||
```
|
||||
|
||||
=== "Java"
|
||||
|
||||
```java title=""
|
||||
/* 標題註釋,用於標註函式、類別、測試樣例等 */
|
||||
|
||||
// 內容註釋,用於詳解程式碼
|
||||
|
||||
/**
|
||||
* 多行
|
||||
* 註釋
|
||||
*/
|
||||
```
|
||||
|
||||
=== "C#"
|
||||
|
||||
```csharp title=""
|
||||
/* 標題註釋,用於標註函式、類別、測試樣例等 */
|
||||
|
||||
// 內容註釋,用於詳解程式碼
|
||||
|
||||
/**
|
||||
* 多行
|
||||
* 註釋
|
||||
*/
|
||||
```
|
||||
|
||||
=== "Go"
|
||||
|
||||
```go title=""
|
||||
/* 標題註釋,用於標註函式、類別、測試樣例等 */
|
||||
|
||||
// 內容註釋,用於詳解程式碼
|
||||
|
||||
/**
|
||||
* 多行
|
||||
* 註釋
|
||||
*/
|
||||
```
|
||||
|
||||
=== "Swift"
|
||||
|
||||
```swift title=""
|
||||
/* 標題註釋,用於標註函式、類別、測試樣例等 */
|
||||
|
||||
// 內容註釋,用於詳解程式碼
|
||||
|
||||
/**
|
||||
* 多行
|
||||
* 註釋
|
||||
*/
|
||||
```
|
||||
|
||||
=== "JS"
|
||||
|
||||
```javascript title=""
|
||||
/* 標題註釋,用於標註函式、類別、測試樣例等 */
|
||||
|
||||
// 內容註釋,用於詳解程式碼
|
||||
|
||||
/**
|
||||
* 多行
|
||||
* 註釋
|
||||
*/
|
||||
```
|
||||
|
||||
=== "TS"
|
||||
|
||||
```typescript title=""
|
||||
/* 標題註釋,用於標註函式、類別、測試樣例等 */
|
||||
|
||||
// 內容註釋,用於詳解程式碼
|
||||
|
||||
/**
|
||||
* 多行
|
||||
* 註釋
|
||||
*/
|
||||
```
|
||||
|
||||
=== "Dart"
|
||||
|
||||
```dart title=""
|
||||
/* 標題註釋,用於標註函式、類別、測試樣例等 */
|
||||
|
||||
// 內容註釋,用於詳解程式碼
|
||||
|
||||
/**
|
||||
* 多行
|
||||
* 註釋
|
||||
*/
|
||||
```
|
||||
|
||||
=== "Rust"
|
||||
|
||||
```rust title=""
|
||||
/* 標題註釋,用於標註函式、類別、測試樣例等 */
|
||||
|
||||
// 內容註釋,用於詳解程式碼
|
||||
|
||||
// 多行
|
||||
// 註釋
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
||||
```c title=""
|
||||
/* 標題註釋,用於標註函式、類別、測試樣例等 */
|
||||
|
||||
// 內容註釋,用於詳解程式碼
|
||||
|
||||
/**
|
||||
* 多行
|
||||
* 註釋
|
||||
*/
|
||||
```
|
||||
|
||||
=== "Kotlin"
|
||||
|
||||
```kotlin title=""
|
||||
/* 標題註釋,用於標註函式、類別、測試樣例等 */
|
||||
|
||||
// 內容註釋,用於詳解程式碼
|
||||
|
||||
/**
|
||||
* 多行
|
||||
* 註釋
|
||||
*/
|
||||
```
|
||||
|
||||
=== "Ruby"
|
||||
|
||||
```ruby title=""
|
||||
### 標題註釋,用於標註函式、類別、測試樣例等 ###
|
||||
|
||||
# 內容註釋,用於詳解程式碼
|
||||
|
||||
# 多行
|
||||
# 註釋
|
||||
```
|
||||
|
||||
## 0.2.2 在動畫圖解中高效學習
|
||||
|
||||
相較於文字,影片和圖片具有更高的資訊密度和結構化程度,更易於理解。在本書中,**重點和難點知識將主要透過動畫以圖解形式展示**,而文字則作為解釋與補充。
|
||||
|
||||
如果你在閱讀本書時,發現某段內容提供瞭如圖 0-2 所示的動畫圖解,**請以圖為主、以文字為輔**,綜合兩者來理解內容。
|
||||
|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 圖 0-2 動畫圖解示例 </p>
|
||||
|
||||
## 0.2.3 在程式碼實踐中加深理解
|
||||
|
||||
本書的配套程式碼託管在 [GitHub 倉庫](https://github.com/krahets/hello-algo)。如圖 0-3 所示,**源程式碼附有測試樣例,可一鍵執行**。
|
||||
|
||||
如果時間允許,**建議你參照程式碼自行敲一遍**。如果學習時間有限,請至少通讀並執行所有程式碼。
|
||||
|
||||
與閱讀程式碼相比,編寫程式碼的過程往往能帶來更多收穫。**動手學,才是真的學**。
|
||||
|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 圖 0-3 執行程式碼示例 </p>
|
||||
|
||||
執行程式碼的前置工作主要分為三步。
|
||||
|
||||
**第一步:安裝本地程式設計環境**。請參照附錄所示的[教程](https://www.hello-algo.com/chapter_appendix/installation/)進行安裝,如果已安裝,則可跳過此步驟。
|
||||
|
||||
**第二步:克隆或下載程式碼倉庫**。前往 [GitHub 倉庫](https://github.com/krahets/hello-algo)。如果已經安裝 [Git](https://git-scm.com/downloads) ,可以透過以下命令克隆本倉庫:
|
||||
|
||||
```shell
|
||||
git clone https://github.com/krahets/hello-algo.git
|
||||
```
|
||||
|
||||
當然,你也可以在圖 0-4 所示的位置,點選“Download ZIP”按鈕直接下載程式碼壓縮包,然後在本地解壓即可。
|
||||
|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 圖 0-4 克隆倉庫與下載程式碼 </p>
|
||||
|
||||
**第三步:執行源程式碼**。如圖 0-5 所示,對於頂部標有檔案名稱的程式碼塊,我們可以在倉庫的 `codes` 檔案夾內找到對應的源程式碼檔案。源程式碼檔案可一鍵執行,將幫助你節省不必要的除錯時間,讓你能夠專注於學習內容。
|
||||
|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 圖 0-5 程式碼塊與對應的源程式碼檔案 </p>
|
||||
|
||||
除了本地執行程式碼,**網頁版還支持 Python 程式碼的視覺化執行**(基於 [pythontutor](https://pythontutor.com/) 實現)。如圖 0-6 所示,你可以點選程式碼塊下方的“視覺化執行”來展開檢視,觀察演算法程式碼的執行過程;也可以點選“全屏觀看”,以獲得更好的閱覽體驗。
|
||||
|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 圖 0-6 Python 程式碼的視覺化執行 </p>
|
||||
|
||||
## 0.2.4 在提問討論中共同成長
|
||||
|
||||
在閱讀本書時,請不要輕易跳過那些沒學明白的知識點。**歡迎在評論區提出你的問題**,我和小夥伴們將竭誠為你解答,一般情況下可在兩天內回覆。
|
||||
|
||||
如圖 0-7 所示,網頁版每個章節的底部都配有評論區。希望你能多關注評論區的內容。一方面,你可以瞭解大家遇到的問題,從而查漏補缺,激發更深入的思考。另一方面,期待你能慷慨地回答其他小夥伴的問題,分享你的見解,幫助他人進步。
|
||||
|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 圖 0-7 評論區示例 </p>
|
||||
|
||||
## 0.2.5 演算法學習路線
|
||||
|
||||
從總體上看,我們可以將學習資料結構與演算法的過程劃分為三個階段。
|
||||
|
||||
1. **階段一:演算法入門**。我們需要熟悉各種資料結構的特點和用法,學習不同演算法的原理、流程、用途和效率等方面的內容。
|
||||
2. **階段二:刷演算法題**。建議從熱門題目開刷,先積累至少 100 道題目,熟悉主流的演算法問題。初次刷題時,“知識遺忘”可能是一個挑戰,但請放心,這是很正常的。我們可以按照“艾賓浩斯遺忘曲線”來複習題目,通常在進行 3~5 輪的重複後,就能將其牢記在心。推薦的題單和刷題計劃請見此 [GitHub 倉庫](https://github.com/krahets/LeetCode-Book)。
|
||||
3. **階段三:搭建知識體系**。在學習方面,我們可以閱讀演算法專欄文章、解題框架和演算法教材,以不斷豐富知識體系。在刷題方面,可以嘗試採用進階刷題策略,如按專題分類、一題多解、一解多題等,相關的刷題心得可以在各個社群找到。
|
||||
|
||||
如圖 0-8 所示,本書內容主要涵蓋“階段一”,旨在幫助你更高效地展開階段二和階段三的學習。
|
||||
|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 圖 0-8 演算法學習路線 </p>
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
comments: true
|
||||
---
|
||||
|
||||
# 0.3 小結
|
||||
|
||||
### 1. 重點回顧
|
||||
|
||||
- 本書的主要受眾是演算法初學者。如果你已有一定基礎,本書能幫助你系統回顧演算法知識,書中源程式碼也可作為“刷題工具庫”使用。
|
||||
- 書中內容主要包括複雜度分析、資料結構和演算法三部分,涵蓋了該領域的大部分主題。
|
||||
- 對於演算法新手,在初學階段閱讀一本入門書至關重要,可以少走許多彎路。
|
||||
- 書中的動畫圖解通常用於介紹重點和難點知識。閱讀本書時,應給予這些內容更多關注。
|
||||
- 實踐乃學習程式設計之最佳途徑。強烈建議執行源程式碼並親自敲程式碼。
|
||||
- 本書網頁版的每個章節都設有評論區,歡迎隨時分享你的疑惑與見解。
|
||||
Reference in New Issue
Block a user