這是一本關(guān)于數(shù)據(jù)結(jié)構(gòu)和算法的書,以Java為描述語言,介紹了計算機編程中常用的數(shù)據(jù)結(jié)構(gòu)和算法。全書共13章,講述了常見的數(shù)據(jù)結(jié)構(gòu)、排序算法、位運算、樹、遞歸、回溯算法、貪心算法、雙指針和滑動窗口、BFS和DFS、前綴和、動態(tài)規(guī)劃、并查集、其他經(jīng)典算法等知識。本書內(nèi)容豐富,實用性強,通過示例練習(xí)和問題分析等方式,詳細講解了與算法有關(guān)的知識點。本書附贈視頻講解二維碼,以及源代碼。
本書適合程序員、計算機專業(yè)相關(guān)師生,以及對算法感興趣的讀者閱讀。
算法是編程的基石,開發(fā)的核心。本書包含55個二維碼,300多分鐘視頻,100多個知識點,50多個示例,適合程序員、計算機專業(yè)相關(guān)師生,以及對算法感興趣的讀者。
數(shù)據(jù)結(jié)構(gòu)和算法是計算機科學(xué)的基石,是計算機的靈魂,要想成為計算機專業(yè)人員,學(xué)習(xí)和掌握算法是十分必要的。不懂?dāng)?shù)據(jù)結(jié)構(gòu)和算法的人不可能寫出效率更高的代碼。計算機科學(xué)的很多新行業(yè)都離不開數(shù)據(jù)結(jié)構(gòu)和算法作為基石,比如大數(shù)據(jù)、人工智能等。底層開發(fā)中也需要使用非常多的數(shù)據(jù)結(jié)構(gòu)和算法知識,以保證底層系統(tǒng)的穩(wěn)定性和高效性。
計算機科學(xué)家尼古拉斯·沃斯在計算機領(lǐng)域有一句人盡皆知的名言算法 數(shù)據(jù)結(jié)構(gòu)=程序(Algorithms Data Structures=Programs),所以數(shù)據(jù)結(jié)構(gòu)和算法是程序員必須掌握的技能。尤其是到一些大公司面試的時候,算法更是一個少不了的環(huán)節(jié),熟練掌握數(shù)據(jù)結(jié)構(gòu)和算法,可以開拓我們的視野,提高我們的邏輯思維能力,在寫代碼和分析官方源碼的時候也非常有幫助。學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)和算法的一個好處就是:學(xué)完之后知識基本不會過時,可以永遠為我們所用。大家都知道程序員需要不停地學(xué)習(xí),因為知識更新太快,記得在筆者上大學(xué)和后來開始工作的時候,非常喜歡研究官方源碼和框架,如癡如醉,但很遺憾,現(xiàn)在很多框架都已被淘汰了,沒被淘汰的也被更新得面目全非,然后還要不停地學(xué)習(xí)其他新的框架。筆者一直在思考,能不能學(xué)習(xí)一種永不過時的知識。后來就接觸了數(shù)據(jù)結(jié)構(gòu)和算法,這一接觸就是好多年,學(xué)的那么多知識依然沒有過時。比如KMP算法是在1977年被聯(lián)合發(fā)表的,那么多年過去了,這種算法依然沒有被淘汰,如果是一個框架,基本上很難保證那么多年還能存在,就算存在也會有大量的更新,還是需要不停地學(xué)習(xí)。
本書以Java為描述語言,介紹了計算機編程中常用的數(shù)據(jù)結(jié)構(gòu)和算法,主要內(nèi)容如下。
第1章:主要介紹了8種數(shù)據(jù)結(jié)構(gòu),包括數(shù)組、鏈表、隊列、棧、散列表、樹、堆、圖,然后每種數(shù)據(jù)結(jié)構(gòu)又有細分,比如介紹樹的時候有完全二叉樹、滿二叉樹、二叉搜索樹、AVL樹、紅黑樹、字典樹、哈夫曼樹、線段樹、笛卡兒樹等。圖的介紹中也有一些經(jīng)典的算法,比如迪杰斯特拉算法、弗洛伊德算法、普里姆算法和克魯斯卡爾算法等。
第2章:介紹了幾種經(jīng)典排序算法,以及它們的穩(wěn)定性分析。
第3章:主要介紹了一些位運算和常見操作符,還有一些簡單的操作和使用技巧,如有限狀態(tài)機和相關(guān)示例講解。
第4章:介紹了和樹有關(guān)的知識,比如樹的遍歷方式,包括DFS遍歷、Morris遍歷,以及BFS遍歷等。
第5章:分析了遞歸的原理和示例練習(xí),可以把它看作是對一棵樹的DFS遍歷。
第6章:主要介紹了回溯算法的使用,然后得出回溯算法的使用模板,以及一些經(jīng)典示例,還有一些重復(fù)問題和不符合條件的修剪分支。
第7章:主要介紹貪心算法的使用和存在的不足。
第8章:分別介紹了相向雙指針、同向雙指針和快慢雙指針的使用技巧,還有滑動窗口的介紹和使用模板,以及大小可變窗口、固定窗口、只增不減窗口等。
第9章:主要介紹了BFS和DFS的使用模板和示例練習(xí)。
第10章:主要介紹了一維前綴和與二維前綴和的使用。
第11章:介紹動態(tài)規(guī)劃和一些經(jīng)典問題的講解,如背包問題、組合與排列問題等。
第12章:通過三國人物的故事,生動形象地介紹了并查集的使用、并查集優(yōu)化、并查集路徑壓縮以及合并優(yōu)化等。
算 法 秘 籍第13章:介紹了其他一些經(jīng)典算法,比如KMP算法、馬拉車算法、算術(shù)表達式的運算、牛頓迭代法求平方根、Base64編碼等。
本書的撰寫與出版得益于機械工業(yè)出版社的鼎力支持,在此深表感謝,同時也感謝支持筆者的讀者和朋友,還要感謝筆者的愛人楊蘭一直以來的理解和支持。由于筆者水平有限,書中難免有不妥和疏漏之處,誠摯期盼讀者朋友給予批評和斧正,筆者會把問題整理出來分享到我們的算法學(xué)習(xí)網(wǎng)站wansuanfa.com(玩算法的拼音),關(guān)于算法的知識非常多,書中不可能全部介紹,大家還可以繼續(xù)在網(wǎng)站免費學(xué)習(xí),本書的提高和改進離不開讀者的幫助和時間的考驗。大家也可以關(guān)注筆者,如果書中有不明白的地方可以隨時溝通,如果有想了解的知識點也可以告訴筆者,筆者會通過視頻直播和錄播的方式為大家進行講解。
王一博,網(wǎng)名博哥,各大專業(yè)網(wǎng)站知名博主,具有10多年的開發(fā)經(jīng)驗,2017年開始做算法試題并在公眾號發(fā)布試題講解,經(jīng)常游走在全球30多個算法網(wǎng)站之間,累計做題2000多道,對算法試題有自己獨特的解題思路和技巧。
前言
第1章 常見的數(shù)據(jù)結(jié)構(gòu)/
1.1數(shù)組/
1.1.1滾動數(shù)組/
1.1.2差分?jǐn)?shù)組/
1.1.3二維差分?jǐn)?shù)組/
1.1.4樹狀數(shù)組/
1.2鏈表/
1.3隊列/
1.4棧/
1.5散列表/
1.6樹/
1.6.1二叉搜索樹/
1.6.2AVL樹/
1.6.3紅黑樹/
1.6.4字典樹/
1.6.5哈夫曼樹/
1.6.6線段樹/
1.6.7笛卡兒樹/
1.6.8其他樹/
1.7堆/
1.8圖/
1.8.1圖的分類/
1.8.2圖的表示方式/
1.8.3圖的遍歷/
1.8.4迪杰斯特拉(Dijkstra)算法/
1.8.5貝爾曼-福特(Bellman-Ford)算法/
1.8.6SPFA算法/
1.8.7弗洛伊德(Floyd)算法/
1.8.8普里姆(Prim)算法/
1.8.9克魯斯卡爾(Kruskal)算法/
1.8.10博魯夫卡(Boruvka)算法/
1.8.11拓撲排序/
1.9數(shù)據(jù)結(jié)構(gòu)總結(jié)/
第2章 排序算法/
2.1冒泡排序/
2.2選擇排序/
2.3插入排序/
2.4快速排序/
2.5歸并排序/
2.6堆排序/
2.7桶排序/
2.8基數(shù)排序/
2.9希爾排序/
2.10計數(shù)排序/
2.11其他排序/
第3章 位運算/
3.1位運算的常見操作符/
3.2位運算的一些簡單操作/
3.3示例練習(xí)/
3.3.1交換兩個數(shù)字的值/
3.3.2只出現(xiàn)一次的數(shù)字/
3.3.3有限狀態(tài)機/
3.3.4二進制中1的個數(shù)/
3.3.5總的比特位數(shù)/
3.3.6反轉(zhuǎn)二進制/
3.3.72的冪/
3.3.84的冪/
3.3.9交替二進制數(shù)/
3.3.10數(shù)字范圍的按位與/
3.3.11字符串長度的最大乘積/
3.3.12兩整數(shù)之和/
3.3.13集合的所有子集/
第4章 算法秘籍樹/
4.1二叉樹的遍歷方式/
4.1.1二叉樹的DFS遍歷/
4.1.2二叉樹的Morris遍歷/
4.1.3二叉樹的BFS遍歷/
4.1.4N叉樹的遍歷/
4.2二叉樹層次遍歷習(xí)題/
4.3二叉樹的特性習(xí)題/
4.4二叉樹的深度優(yōu)先搜索習(xí)題/
4.5二叉樹的構(gòu)造/
4.6二叉樹的公共祖先問題/
第5章 遞歸/
5.1遞歸的理解/
5.2示例練習(xí)/
5.2.1反轉(zhuǎn)鏈表/
5.2.2檢查是否是回文鏈表/
5.2.3刪除鏈表的倒數(shù)第n個節(jié)點/
5.2.4生成括號/
5.2.5二叉樹展開為鏈表/
5.2.6將二叉搜索樹改為累加樹/
第6章 回溯算法/
6.1回溯算法的使用/
6.2示例練習(xí)/
6.2.1解數(shù)獨/
6.2.2n皇后/
6.2.3目標(biāo)值的組合/
6.2.4組合/
6.2.5單詞搜索/
6.3回溯算法的剪枝/
6.3.1有重復(fù)項數(shù)字的全排列/
6.3.2劃分為k個相等的子集/
第7章 貪心算法/
7.1貪心算法存在的不足/
7.2示例練習(xí)/
7.2.1檸檬找零/
7.2.2分發(fā)餅干/
7.2.3分糖果問題/
7.2.4最小跳躍次數(shù)/
7.2.5無重疊區(qū)域/
第8章 雙指針和滑動窗口/
8.1相向雙指針/
8.1.1回文串/
8.1.2盛最多水的容器/
8.2同向雙指針/
8.2.1移動所有的0到數(shù)組末尾/
8.2.2兩個鏈表的第一個公共節(jié)點/
8.3快慢雙指針/
8.3.1判斷鏈表中是否有環(huán)/
8.3.2找出鏈表的中間節(jié)點/
8.4滑動窗口/
8.5大小可變窗口/
8.5.1最長沒有重復(fù)字符的子串/
8.5.2最小覆蓋子串/
8.5.3長度最小的連續(xù)子數(shù)組/
8.6固定窗口/
8.6.1平均值最大的子數(shù)組/
8.6.2找到字符串中的異位詞/
8.6.3子數(shù)組中的最大值/
8.7只增不減窗口/
8.7.1最大連續(xù)1的個數(shù)/
8.7.2替換后的最長重復(fù)字符/
8.7.3籃子里的水果/
第9章 BFS和DFS/
9.1BFS的使用模板/
9.2DFS的使用模板/
9.3示例練習(xí)/
9.3.1島嶼數(shù)量/
9.3.2被圍繞的區(qū)域/
9.3.3島嶼的最大面積/
9.3.4腐爛的蘋果/
9.3.5刪除無效的括號/
9.3.6省份數(shù)量/
第10章 前綴和/
10.1一維前綴和/
10.2二維前綴和/
10.3示例練習(xí)/
10.3.1和為k的子數(shù)組/
10.3.2k個奇數(shù)的子數(shù)組/
10.3.3連續(xù)數(shù)組的長度/
10.3.4總和可被k整除的子數(shù)組/
10.3.5和為k的路徑/
第11章 動態(tài)規(guī)劃/
11.1動態(tài)規(guī)劃講解/
11.1.1兌換零錢(一)/
11.1.2國王與金礦/
11.1.3解題思路/
11.2背包問題/
11.2.101背包問題/
11.2.2完全背包問題/
11.2.3多重背包問題/
11.2.4狀態(tài)壓縮/
11.3組合與排列/
11.3.1兌換零錢(二)/
11.3.2加起來和為目標(biāo)值的組合/
11.3.3單詞拆分/
11.4背包練習(xí)/
11.4.1目標(biāo)和(01背包)/
11.4.2平分子集(01背包)/
11.4.3最少的完全平方數(shù)(完全
背包)/
11.5其他練習(xí)/
11.5.1最長公共子串/
11.5.2最長公共子序列/
11.5.3網(wǎng)格中的不同路徑/
11.5.4最大正方形/
11.5.5最長上升子序列/
第12章 并查集/
12.1并查集的使用/
12.2并查集優(yōu)化/
12.3并查集路徑壓縮/
12.4按大小合并優(yōu)化/
12.5按秩合并優(yōu)化/
12.6示例練習(xí)/
12.6.1島嶼數(shù)量/
12.6.2被圍繞的區(qū)域/
12.6.3省份數(shù)量/
12.6.4飛地的數(shù)量/
第13章 其他經(jīng)典算法/
13.1KMP算法/
13.2馬拉車算法/
13.3摩爾投票算法/
13.4埃氏篩法/
13.5兩個數(shù)的最大公約數(shù)/
13.6算術(shù)表達式的運算/
13.6.1中綴表達式轉(zhuǎn)換的括號法/
13.6.2中綴表達式轉(zhuǎn)換的二叉樹法/
13.6.3中綴表達式轉(zhuǎn)前綴表達式/
13.6.4中綴表達式轉(zhuǎn)后綴表達式/
13.6.5后綴表達式求值/
13.6.6前綴表達式求值/
13.7牛頓迭代法求平方根/
13.8Base64編碼/