啊哈!去中科院玩單片機
  呦吼!在微軟亞洲研究院寫爬蟲
  噠噠!寫一本開開心心的算法書
  你一定能看懂的算法書!
  作為本書的策劃編輯,我很榮幸。
  《啊哈!算法》是我讀過的有趣且是我能看懂的一本算法書。
  我當初是因為啊哈磊寫的另外一本書《啊哈!C》而認識啊哈磊的。啊哈磊還有個網站,也叫啊哈磊,這個啊哈磊網站中有個論壇,叫啊哈論壇。論壇建立短短一年半時間,就聚集瞭15000多個啊哈小夥伴,都是萌物。我對他的寫作風格很欣賞,那是一種因熱愛和探究而産生的純粹的快樂,因此,當啊哈磊率領著他的一大波萌物開開心心地攻城略地,浩浩蕩蕩地兵臨城下,跟我說他想寫一本通俗易懂的算法書,不知是否能齣版時,我的迴答是:“必須齣版!”
  這本書齣版意嚮的達成就是這麼簡單。
  但創作的過程一點不輕鬆。因為任何一本拿得齣手的書的創作都是作者大量時間和精力付齣的結果。是毅力的纍積。
  幾個月之後,我拿到瞭這本書的初稿。我高高興興地開始讀。這部分寫得通俗易懂,我看得津津有味。但讀瞭一些之後,我發現我高興不起來瞭,我遇到瞭睏難,有些篇章寫得太簡略瞭,隻是把算法的基本思路說瞭一下,然後就直接給齣瞭以該算法實現的某個示例的完整代碼。
  這樣不行,看不懂啊。原理很簡單,但實現起來時,看代碼就感覺對應不起來瞭。或許比我聰明的人能看懂,但我希望像我這種在算法方麵毫無造詣的普通選手讀起來也不吃力,於是我讓啊哈磊完善它。我是這麼交代的——你得寫得讓我能看懂纔行。這要求非常的簡單,但也非常的暗黑。
  經過比我想象的要長的時間,啊哈磊給瞭我第二版。
  我繼續閱讀,很多之前看不懂的地方現在能看懂瞭,或者至少我認為我看懂瞭(請允許我使用這種讓人生氣的措辭),但還有少部分欠點勁兒。啊哈磊嚮我投來睏惑又略帶鄙視的目光,我用堅定又癡癡呆呆的目光把他的目光給頂瞭迴去。
  於是啊哈磊繼續埋頭苦乾。
  終於,我完全可以看懂的版本誕生瞭。
進入品牌店請點擊:
目錄
第1章 一大波數正在靠近——排序 1
第1節 最快最簡單的排序——桶排序 2
第2節 鄰居好說話——冒泡排序 7
第3節 最常用的排序——快速排序 12
第4節 小哼買書 20
第2章 棧、隊列、鏈錶 25
第1節 解密QQ號——隊列 26
第2節 解密迴文——棧 32
第3節 紙牌遊戲——小貓釣魚 35
第4節 鏈錶 44
第5節 模擬鏈錶 54
第3章 枚舉!很暴力 57
第1節 坑爹的奧數 58
第2節 炸彈人 61
第3節 火柴棍等式 67
第4節 數的全排列 70
第4章 萬能的搜索 72
第1節 不撞南牆不迴頭——深度優先搜索 73
第2節 解救小哈 81
第3節 層層遞進——廣度優先搜索 88
第4節 再解炸彈人 95
第5節 寶島探險 106
第6節 水管工遊戲 117
第5章 圖的遍曆 128
第1節 深度和廣度優先究竟是指啥 129
第2節 城市地圖——圖的深度優先遍曆 136
第3節 最少轉機——圖的廣度優先遍曆 142
第6章 最短路徑 147
第1節 隻有五行的算法——Floyd-Warshall 148
第2節 Dijkstra算法——通過邊實現鬆弛 155
第3節 Bellman-Ford——解決負權邊 163
第4節 Bellman-Ford的隊列優化 171
第5節 最短路徑算法對比分析 177
第7章 神奇的樹 178
第1節 開啓“樹”之旅 179
第2節 二叉樹 183
第3節 堆——神奇的優先隊列 185
第4節 擒賊先擒王——並查集 200
第8章 更多精彩算法 211
第1節 鏢局運鏢——圖的最小生成樹 212
第2節 再談最小生成樹 219
第3節 重要城市——圖的割點 229
第4節 關鍵道路——圖的割邊 234
第5節 我要做月老——二分圖最大匹配 237
第9章 還能更好嗎——微軟亞洲研究院麵試 243
  第1節 最快最簡單的排序——桶排序
  在我們生活的這個世界中到處都是被排序過的東東。站隊的時候會按照身高排序,考試的名次需要按照分數排序,網上購物的時候會按照價格排序,電子郵箱中的郵件按照時間排序……總之很多東東都需要排序,可以說排序是無處不在。現在我們舉個具體的例子來介紹一下排序算法。
  首先齣場的是我們的主人公小哼,上麵這個可愛的娃就是啦。期末考試完瞭老師要將同學們的分數按照從高到低排序。小哼的班上隻有5個同學,這5個同學分彆考瞭5分、3分、5分、2分和8分,哎,考得真是慘不忍睹(滿分是10分)。接下來將分數進行從大到小排序,排序後是8 5 5 3 2。你有沒有什麼好方法編寫一段程序,讓計算機隨機讀入5個數然後將這5個數從大到小輸齣?請先想一想,至少想15分鍾再往下看吧(*^__^*)。
  我們這裏隻需藉助一個一維數組就可以解決這個問題。請確定你真的仔細想過再往下看哦。
  首先我們需要申請一個大小為11的數組int a[11]。OK,現在你已經有瞭11個變量,編號從a[0]~a[10]。剛開始的時候,我們將a[0]~a[10]都初始化為0,錶示這些分數還都沒有人得過。例如a[0]等於0就錶示目前還沒有人得過0分,同理a[1]等於0就錶示目前還沒有人得過1分……a[10]等於0就錶示目前還沒有人得過10分。
  下麵開始處理每一個人的分數,第一個人的分數是5分,我們就將相對應的a[5]的值在原來的基礎增加1,即將a[5]的值從0改為1,錶示5分齣現過瞭一次。
  第二個人的分數是3分,我們就把相對應的a[3]的值在原來的基礎上增加1,即將a[3]的值從0改為1,錶示3分齣現過瞭一次。
  注意啦!第三個人的分數也是5分,所以a[5]的值需要在此基礎上再增加1,即將a[5]的值從1改為2,錶示5分齣現過瞭兩次。
  按照剛纔的方法處理第四個和第五個人的分數。最終結果就是下麵這個圖啦。
  你發現沒有,a[0]~a[10]中的數值其實就是0分到10分每個分數齣現的次數。接下來,我們隻需要將齣現過的分數打印齣來就可以瞭,齣現幾次就打印幾次,具體如下。
  a[0]為0,錶示“0”沒有齣現過,不打印。
  a[1]為0,錶示“1”沒有齣現過,不打印。
  a[2]為1,錶示“2”齣現過1次,打印2。
  a[3]為1,錶示“3”齣現過1次,打印3。
  a[4]為0,錶示“4”沒有齣現過,不打印。
  a[5]為2,錶示“5”齣現過2次,打印5 5。
  a[6]為0,錶示“6”沒有齣現過,不打印。
  a[7]為0,錶示“7”沒有齣現過,不打印。
  a[8]為1,錶示“8”齣現過1次,打印8。
  a[9]為0,錶示“9”沒有齣現過,不打印。
  a[10]為0,錶示“10”沒有齣現過,不打印。
  最終屏幕輸齣“2 3 5 5 8”,完整的代碼如下。
  #include 
  int main()
  {
  int a[11],i,j,t;
  for(i=0;i<=10;i++)
  a[i]=0; //初始化為0
  for(i=1;i<=5;i++) //循環讀入5個數
  {
  scanf("%d",&t;); //把每一個數讀到變量t中
  a[t]++; //進行計數
  }
  for(i=0;i<=10;i++) //依次判斷a[0]~a[10]
  for(j=1;j<=a[i];j++) //齣現瞭幾次就打印幾次
  printf("%d ",i);
  getchar();getchar();
  //這裏的getchar();用來暫停程序,以便查看程序輸齣的內容
  //也可以用system("pause");等來代替
  return 0;
  }
  輸入數據為:
  5 3 5 2 8
  仔細觀察的同學會發現,剛纔實現的是從小到大排序。但是我們要求是從大到小排序,這該怎麼辦呢?還是先自己想一想再往下看哦。
  其實很簡單。隻需要將for(i=0;i<=10;i++)改為for(i=10;i>=0;i--)就OK啦,快去試一試吧。
  這種排序方法我們暫且叫它“桶排序”。因為其實真正的桶排序要比這個復雜一些,以後再詳細討論,目前此算法已經能夠滿足我們的需求瞭。
  這個算法就好比有11個桶,編號從0~10。每齣現一個數,就在對應編號的桶中放一個小旗子,最後隻要數數每個桶中有幾個小旗子就OK瞭。例如2號桶中有1個小旗子,錶示2齣現瞭一次;3號桶中有1個小旗子,錶示3齣現瞭一次;5號桶中有2個小旗子,錶示5齣現瞭兩次;8號桶中有1個小旗子,錶示8齣現瞭一次。
  現在你可以嘗試一下輸入n個0~1000之間的整數,將它們從大到小排序。提醒一下,如果需要對數據範圍在0~1000的整數進行排序,我們需要1001個桶,來錶示0~1000之間每一個數齣現的次數,這一點一定要注意。另外,此處的每一個桶的作用其實就是“標記”每個數齣現的次數,因此我喜歡將之前的數組a換個更貼切的名字book(book這個單詞有記錄、標記的意思),代碼實現如下。
  #include 
  int main()
  {
  int book[1001],i,j,t,n;
  for(i=0;i<=1000;i++)
  book[i]=0;
  scanf("%d",&n;);//輸入一個數n,錶示接下來有n個數
  for(i=1;i<=n;i++)//循環讀入n個數,並進行桶排序
  {
  scanf("%d",&t;); //把每一個數讀到變量t中
  book[t]++; //進行計數,對編號為t的桶放一個小旗子
  }
  for(i=1000;i>=0;i--) //依次判斷編號1000~0的桶
  for(j=1;j<=book[i];j++) //齣現瞭幾次就將桶的編號打印幾次
  printf("%d ",i);
  getchar();getchar();
  return 0;
  }
  可以輸入以下數據進行驗證。
  10
  8 100 50 22 15 6 1 1000 999 0
  運行結果是:
  1000 999 100 50 22 15 8 6 1 0
  最後來說下時間復雜度的問題。代碼中第6行的循環一共循環瞭m次(m為桶的個數),第9行的代碼循環瞭n次(n為待排序數的個數),第14行和第15行一共循環瞭m+n次。所以整個排序算法一共執行瞭m+n+m+n次。我們用大寫字母O來錶示時間復雜度,因此該算法的時間復雜度是O(m+n+m+n)即O(2*(m+n))。我們在說時間復雜度的時候可以忽略較小的常數,最終桶排序的時間復雜度為O(m+n)。還有一點,在錶示時間復雜度的時候,n和m通常用大寫字母即O(M+N)。
  這是一個非常快的排序算法。桶排序從1956年就開始被使用,該算法的基本思想是由E.J. Issac和R.C. Singleton提齣來的。之前我說過,其實這並不是真正的桶排序算法,真正的桶排序算法要比這個更加復雜。但是考慮到此處是算法講解的第一篇,我想還是越簡單易懂越好,真正的桶排序留在以後再聊吧。需要說明一點的是:我們目前學習的簡化版桶排序算法,其本質上還不能算是一個真正意義上的排序算法。為什麼呢?例如遇到下麵這個例子就沒轍瞭。
  現在分彆有5個人的名字和分數:huhu 5分、haha 3分、xixi 5分、hengheng 2分和gaoshou 8分。請按照分數從高到低,輸齣他們的名字。即應該輸齣gaoshou、huhu、xixi、haha、hengheng。發現問題瞭沒有?如果使用我們剛纔簡化版的桶排序算法僅僅是把分數進行瞭排序。最終輸齣的也僅僅是分數,但沒有對人本身進行排序。也就是說,我們現在並不知道排序後的分數原本對應著哪一個人!這該怎麼辦呢?不要著急,請看下節——冒泡排序。
……
  我想寫一本通俗易懂的算法書很久瞭,因為對於多數人而言,“算法”給他的第一印象就是很難懂,其實我也是這樣。還記得我第一次學習圖論的“割點割邊”算法時,看過不下於四五本書,其中不乏一些算法經典書籍,還百度瞭一堆材料,纔勉強將其看懂並實現成代碼。其實這個算法並不難,核心代碼不超過20行,但是很多算法書都是草草敘述,不同的書籍給齣的參考代碼也是五花八門,有的甚至都不稀罕給你代碼,這大大增加瞭學習的難度。我是花瞭整整一個晚上纔搞定的,當然這其中不排除智商因素。第二印象就是算法是枯燥無趣的,並且好像沒什麼作用。其實在我們的日常生活之中到處都可見到算法的影子,隻不過它通常隱匿在事物的背後,不太容易被發現。但是它每天都在默默地為我們服務著。在本書中我將帶你一步步揭開算法的奧秘,帶它走近你的身邊。
  由於算法的內容確實是太多瞭,要想全部寫清楚恐怕幾本書都不夠,本書將介紹一些最常用的算法。此外算法的實現通常需要依附一些數據結構,因此在必要的時候對於需要用到的數據結構我也會進行講解。本書中涉及的數據結構有棧、隊列、樹、並查集、堆和圖等;算法有各種排序、枚舉、深度和廣度優先搜索、圖上的遍曆,當然還有圖論中不可以缺少的四種最短路徑算法、兩種最小生成樹算法、割點與割邊算法、二分圖的最大匹配算法等。
  盡管我不敢保證我寫的算法你一定可以看懂(但憑著一股強大的自信,我認為初中以上文化程度的應該沒問題^_^),但我會以一個故事或者一個你在生活中可能遇到的問題開始對一個算法進行講解,並盡量用通俗易懂的語言配閤有趣的插圖讓你在閱讀本書的時候更像是在品讀一篇篇輕鬆的短篇小說或是在玩一把趣味解謎遊戲,在輕鬆愉悅中掌握算法精髓,感受算法之美。
  緻謝
  本書能得以麵世,首先要感謝圖靈的陳冰先生。感謝你主動聯係我,給予我信心去完成本書的全部,並且提齣瞭很多寶貴的建議。更加令我吃驚的是你竟然能讀懂本書的全部算法(包括每一行代碼),還發現瞭很多隱藏得很深的錯誤,真是一位非常棒的圖書齣版人。
  在書稿創作的過程中,有幸和很多優秀的學生共同學習和探討,是他們為本書的創作提供瞭靈感,感謝他們的傾聽、交流和建議。他們是武漢二中的呂凱風同學、武漢外國語學校的李嘉浩、熊子健、陳雨禾、郭明達和李丁等同學。
  本書之所以變得這麼有趣,還必須要感謝我的美女插畫師鄭佳茜,你靈感湧現的插圖功不可沒。
  感謝我的好友張知嚴,無私地幫助我搭建瞭“添柴”編程在綫學習係統(tianchai。org),為本書讀者提供瞭更好的學習交流平颱。
  感謝我的學生鬍夢清,感謝你排除萬難來參加你人生中的最後一場NOIP競賽。是你用行動、青春路上追求夢想的精神,告訴我們18歲就應該可愛、執著、不畏懼,敢於朝著夢想前行。
  特彆感謝我的未婚妻Snowin,是你放棄瞭近一年來所有的周末和節假日,陪我在書桌旁、咖啡廳裏、旅途中……共同完成瞭本書的每一個字、每一幅圖、每一段代碼。
  最後要感謝我的父母,你們把我拉扯大太不容易瞭,我愛你們!
  啊哈磊
  2014年5月6日
這本《啊哈!算法》真是讓人愛不釋手,從第一頁翻開就深深地吸引瞭我。作者的筆觸非常生動,將那些原本枯燥乏味的算法知識,描繪得如同一個個引人入勝的故事。我一直覺得算法是計算機科學中最核心也最神秘的部分,但又常常因為那些抽象的數學公式和復雜的邏輯而望而卻步。這本書卻不一樣,它完全打破瞭我對算法的刻闆印象。它沒有直接堆砌理論,而是通過一係列精心設計的、貼近生活的例子,引導讀者一步步走進算法的世界。比如,書中關於“跳躍錶”的講解,用到瞭現實生活中查找電話號碼的類比,我一下子就理解瞭它的原理和優勢。再比如,講解“哈希錶”時,作者巧妙地將它比作一個高效的“萬能鑰匙”,能讓你迅速找到想要的東西。這種“啊哈!”時刻的頓悟感,貫穿瞭整本書,讓人在輕鬆愉悅的氛圍中,不知不覺地掌握瞭算法的精髓。我尤其喜歡作者在講解每個算法時,都會先介紹它要解決的問題,再引齣算法的思想,最後再詳細解析實現細節,這種結構非常清晰,邏輯性很強,讓我能更好地理解算法誕生的背景和價值。即便是我之前接觸過的算法,在這本書裏也仿佛獲得瞭新生,有瞭更深刻的理解。這本書不僅適閤初學者,我覺得對於有一定算法基礎的讀者來說,也能從中獲得不少啓發,重新審視和鞏固自己的知識體係。
評分《啊哈!算法》這本書,與其說是一本算法入門書,不如說是一本“思維方式啓濛”的讀物。我一直以來都對“效率”這個概念很感興趣,也一直在思考如何纔能讓生活和工作變得更有效率。這本書恰恰提供瞭一個非常好的視角。它沒有直接教你怎麼寫代碼,而是從“是什麼”、“為什麼”和“怎麼做”這三個層麵,深入淺齣地剖析瞭各種經典算法的核心思想。我印象最深刻的是關於“搜索算法”的講解,作者用“大海撈針”的比喻,讓我們直觀地理解瞭二分查找的高效性,以及它對數據有序性的要求。這讓我意識到,很多時候我們低效的原因,並不是能力不行,而是沒有找到正確的方法。書中對於“排序算法”的講解也同樣精彩,各種排序方法的比較,讓我明白瞭在不同的場景下,選擇不同的排序算法,其效率差異是巨大的。這本書讓我開始重新審視我日常工作中遇到的各種“瓶頸”,並且嘗試用算法的思維去分析和解決它們。它教會瞭我如何更係統地思考問題,如何從根源上找到最優解。這本書的價值,遠遠超齣瞭算法本身,它為我打開瞭一扇新的大門。
評分我是一個對計算機原理充滿好奇的普通讀者,但往往因為過於專業和晦澀的術語而感到力不從心。《啊哈!算法》這本書,就像是一盞明燈,照亮瞭我探索算法世界的道路。它摒棄瞭枯燥的理論堆砌,而是用一種非常親民、生動的方式,將算法的精髓展現在讀者麵前。書中的案例豐富多樣,從簡單的查找、排序,到復雜的圖論、動態規劃,每一個算法都經過瞭作者的精心打磨,以最易於理解的方式呈現。我尤其欣賞作者在講解時,總會預設一個讀者可能遇到的問題,然後逐步引導讀者去思考,去發現,最終“啊哈!”一聲,豁然開朗。這種體驗,遠比直接灌輸知識要深刻得多。這本書讓我明白,算法並非高不可攀,它其實是我們解決問題、優化效率的強大工具。通過閱讀這本書,我不僅對各種算法有瞭初步的瞭解,更重要的是,它激發瞭我對計算機科學更深層次的興趣,讓我對未來的學習充滿瞭期待。
評分老實說,我本來對算法沒什麼太大的興趣,總覺得那是程序員纔需要關注的東西,離我這個普通讀者有點遠。但朋友強烈推薦瞭《啊哈!算法》,抱著試試看的心態翻開,沒想到徹底改變瞭我的看法。這本書的語言風格非常獨特,不是那種冷冰冰的技術手冊,而是充滿瞭幽默感和人情味。作者好像真的在和你聊天一樣,用一種非常接地氣的方式來講解那些聽起來很“高大上”的算法。他會用生活中的小場景來解釋復雜的概念,比如用扔硬幣來比喻隨機算法,用排隊買票來闡述貪心算法。這些生動形象的比喻,讓原本難以理解的抽象概念變得異常清晰。我感覺自己就像在玩一個智力遊戲,每攻剋一個算法,都有一種小小的成就感。而且,這本書的設計也很貼心,每個章節都相對獨立,即使跳著看,也不會覺得太吃力。我已經迫不及待地想把書裏的例子和方法用到我的實際工作中去,雖然我不是程序員,但很多解決問題的思路和優化流程的方法,都能從算法中學到。這本書讓我看到瞭算法的魅力,它不僅僅是代碼,更是一種解決問題的智慧。
評分這是一本非常“有趣”的書!我一直以來都覺得算法是很枯燥的,但《啊哈!算法》徹底顛覆瞭我的認知。作者的文筆非常幽默,而且充滿瞭智慧。他在講解算法的時候,總是能用一些非常意想不到的比喻,讓你忍不住會心一笑,然後就恍然大悟。比如,關於“圖論”的講解,他用“旅行商問題”來引入,把復雜的圖遍曆問題變得生動有趣。我一直以為圖論是非常抽象和難以理解的,但在他的筆下,我竟然能夠感受到其中的邏輯和美感。這本書的亮點在於,它不僅僅是告訴你“這個算法是什麼”,更是告訴你“這個算法為什麼是這樣的”,以及“這個算法在解決什麼問題”。這種深入的探討,讓我對算法有瞭更全麵的認識。我尤其喜歡書中穿插的那些曆史故事和趣聞軼事,它們讓算法不再是冰冷的公式,而是有瞭人情味,有瞭發展的脈絡。這本書讓我覺得,學習算法,其實也是在學習一種解決問題的智慧,一種優化思維的藝術。
評分經典書,基本的數據結構和算法都有涉及
評分很好的一本算法書,寫的有趣,通俗易懂,難的地方圖解就簡單瞭,希望看過以後能提高不少。有源碼下載和優化算法不錯,可以拓展思維。
評分東西很好用,京東的每一次購物都很滿意,配送員很熱情,希望京東越做越好。
評分一直很期待買的書,很喜歡,物流很快呦!
評分講解挺詳細,入門很不錯。
評分這本書是在圖靈社區經推薦來的,和算法圖解一起買的,不過現在還沒有開始看,先從算法圖解入門。
評分經典算法書,打摺收一本
評分書價偏貴,還好有活動可以減價。書內容不算深,配圖較多,可以看。記得加作者的球球答疑群,哈哈。
評分很不錯的寶貝,物美價廉,值得迴購,還會推薦給朋友的
本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度,google,bing,sogou 等
© 2025 book.tinynews.org All Rights Reserved. 静思书屋 版权所有