描述
內容簡介
「What I cannot create, I do not understand.」 - Richard Feynman 最實用演算法指南,讓你在隨機森林裡也不迷航。 本書挑選出最實用、出現頻率最高的演算法及相關例題,並以C++實作,透過實作來了解每一種演算法的流程,同時每章節後皆附上 LeetCode 或 APCS考古題與線上批改系統連結供讀者練習。
本書適合… ✪修習資料結構與演算法之學生 ✪準備APCS或程式競試的學生 ✪準備面試或轉職成為軟體工程師的你
本書特色 ✪挑選出最實用且出現頻率最高的演算法,並附上每個演算法的步驟圖解與實作程式碼 ✪每章節後皆附上LeetCode 或 APCS考古題與線上批改系統連結供讀者練習 ✪仿照大學教材與進度編排,可做為大學課程的輔助或先修教材 ✪講解常見的C++ STL 用法及操作原理,熟悉 C++ STL的使用能夠使你在程式競賽或面試中脫穎而出 ✪程式競賽中常見的技巧或相關注意事項
電子資源 |
作者簡介
作者介紹
李耕銘 電機所畢業後目前不務正業地在台大資工訓練班擔任講師,平時喜歡教學、寫文章、研究基礎科學,現在養了五隻貓,努力過每一天掙罐頭錢。 本書也是作者在資工訓練班開設演算法課程的參考教材。 bit.ly/3L2xOqI Email:lkm543@gmail.com
編者介紹 張凱鈞 本來是商業顧問,因為覺得每天都在說一樣的話所以轉而研究自然語言處理。 願望是做一個很棒的系統陪大家聊天、幫助大家工作、守護世界和平。 |
目錄
01 資料結構與演算法入門
1-1 資料結構與演算法簡介 1-2 效能還與哪些因素有關 1-3 Take Home Message
02 複雜度估算 Complexity 2-1 複雜度簡介 2-2 複雜度的估計法 2-3 Big-O 的運算證明 2-4 極限的表達方式 2-5 複雜度的其他符號 2-6 遞迴的複雜度計算 習題
03 P 與 NP 問題 3-1 演算法問題的分類 3-2 問題的難度 3-3 歸約與NP-hard 3-4 NP-complete(NPC) 習題
04 排序 Sort 4-1 排序簡介 4-2 插入排序法 Insertion Sort 4-3 謝爾排序法 Shell Sort 4-4 選擇排序法 Selection Sort 4-5 冒泡排序法 Bubble Sort 4-6 合併排序法 Merge Sort 4-7 堆積排序法 Heap Sor 4-8 快速排序法 Quick Sort 4-9 C++ STL 中的排序 4-10 實戰練習 4-11 (補充) C++ STL 的內觀排序法 習題
05 搜尋 Search 5-1 搜尋簡介 5-2 循序搜尋 5-3 二分搜尋法 5-4 插補搜尋 5-5 黃金切割搜尋 5-6 費氏搜尋 5-7 雜湊搜尋 5-8 搜尋總結 5-9 實戰練習 習題
06 分治法Divide and Conquer 6-1 分治法 Divide and Conquer 簡介 6-2 河內塔 6-3 合併排序與快速排序 6-4 最大子數列問題 6-5 矩陣相乘 6-6 選擇問題 6-7 支配理論 6-8 實戰練習 習題
07 貪婪演算法 Greedy Algorithm 7-1 貪婪演算法簡介 7-2 找錢問題 7-3 中途休息 7-4 活動選擇問題 7-5 背包問題 Knapsack Problem 7-6 工作排程 7-7 實戰練習 習題
08 動態規劃 Dynamic Programming 8-1 動態規劃簡介 8-2 動態規劃解析 8-3 找錢問題 8-4 最大子數列 8-5 活動選擇問題 8-6 郵票問題 8-7 木頭切割問題 8-8 背包問題 8-9 矩陣鏈乘 8-10 最長遞增子序列 (Longest Increasing Subsequence, LIS) 8-11 最長共同子序列( Longest Common Subsequence, LCS) 8-12 實戰練習 8-13 小結 習題
09 圖論 Graph 9-1 「圖」的定義 9-2 圖的表示方式 9-3 圖的分類 9-4 AOV 網路、AOE 網路與拓樸 排序 9-5 實戰練習 習題
10 廣度優先搜尋Breadth-First Search 10-1 圖的搜尋 10-2 廣度優先搜尋的實作 10-3 計算連通元件個數 10-4 窮舉所有情形 10-5 最短路徑 10-6 環的判別 10-7 實戰練習 習題
11 深度優先搜尋Depth-First Search 11-1 深度優先搜尋簡介與實作 11-2 拓樸排序 11-3 強連通元件 11-4 N 皇后問題 11-5 實戰練習 習題
12 最小生成樹 Minimal Spanning Tree 12-1 最小生成樹定義與原理 12-2 集合的搜尋與合併 12-3 Kruskal 演算法 12-4 Prim 演算法 習題
13 網路流 Flow Network 13-1 網路流問題簡介 13-2 網路流問題的演算法 13-3 Ford-Fulkerson 方法 13-4 Edmonds-Karp Algorithm 13-5 二分圖最大匹配 習題
14 最短路徑Shortest Path 14-1 最短路徑問題簡介 14-2 Bellman-Ford Algorithm 14-3 SPFA (Shortest Path Faster Algorithm) 14-4 DAG Algorithm 14-5 Dijkstra's Algorithm 14-6 Floyd-Warshall Algorithm 14-7 最短路徑問題總結 習題 |
序
開始教課後意識到出題比寫題難這件事,而要出有鑑別力的題目更難。正因如此許多演算法題目其實都是修改自教科書上的例題,但對於大部份人而言需要掌握的方法與例題仍然太多,於是參考「八二法則」:80%的題目出自20%的知識點上,本書挑選出這80%最常出現的知識點並彙集相關的題目,讓你可以先讀完基本的例題後,再看看這些演算法的變體。
我也很喜歡前諾貝爾物理獎得主Richard Phillips Feynman曾說過的一句話: 「What I cannot create, I do not understand.」 在資訊科學的領域裡,要測驗自己是不是真的理解一個領域,最簡單粗暴的方式便是看自己能不能從頭把它打造出來,所以這本書有很大的篇幅便是強調手做,會帶你一步步打造這些常見的演算法。
雖然我過去學習演算法時就跟大多數人一樣有點懵懂又不知為何要學,但隨著求學與工作的時間長,才慢慢了解到基礎理論的重要,日常的應用工程就像是外功一樣招式甚多也千變萬化,而基礎理論像是內功一樣需要長時間穩紮穩打卻不知何時能夠真正用上。 比方說,過去在寫虛擬貨幣的自動套利程式時,我並沒有體認或使用到任何演算法,而是單純使用暴力解,直到因為授課需要重讀了Introduction to Algorithms 這本演算法大學教科書,看到書上的例題後發現其實套利問題是可以用演算法中的最短路徑、檢查負環來解答的,這時候才體會到「經典之所以是經典,在於每次閱讀都能夠有不同的體悟」這件事,至於相關的套利演算法細節我寫在「14-7-3 外匯套利的應用」之中。 或是在研究時需要計算三維立體空間中的血管鈣化體積時,也是用到廣度優先搜尋來解決,因此演算法的學習只是過程,目的是讓自己擁有解決問題的能力,或許多數人跟我一樣並不是那麼享受寫題目的過程,我也認為所謂的「快樂學習」在多數時候並不存在,學習的過程往往是苦澀的,但學習的成果卻是甜美的。 |