天天看點

程式員如何高效學好資料結構與算法?

  主題:

  1. 為什麼要學資料結構

  2. 資料結構學習秘籍

  3. 算法為什麼那麼難

  4. 算法學習秘籍

  5. 如何打開資料結構與算法這兩扇門

  随着科學技術的發展,人工智能已滲透到各個行業,算法工程師非常火 爆,急缺大量人才,年薪也越來越高。剛畢業30-40萬很常見。很多人想入手 學習算法,那麼多算法,究竟該如何下手呢?

  很多人看到招聘要求,算法工程師有很多具體分支:

  音/視訊算法工程師 圖像處理算法工程師 信号算法工程師 自然語言算法工程師 資料挖掘算法工程師 搜尋算法工程師 例如有的招聘要求:

  1 ?至少熟悉一門程式設計語言C/C++/java/python/R

  2.熟練掌握資料結構,具有良好的算法基礎和程式設計功底;

  /熟練運用各種常用算法和資料結構,有獨立的實作能力;

  3 ?熟悉資料挖掘算法

  4 ?熟悉機器學習相關知識理論

  加分項:具有較為豐富的項目實踐經驗 那麼是不是要直接學習這些算法呢?

  其實不然,萬丈高樓平地起,任何高深的算法都要從基礎算法學起,不可 能一口吃個胖子,是以入門算法還是要從基礎開始:

  ?首先學習一門語言,例如C/C++/Java/python,初學者學C++比較普 遍。

  ?學資料結構,資料結構書有很多,但是有些教材晦澀難懂,建議看圖 解多,通俗易懂的書,推薦《趣學資料結構》。

  ?學算法,不要直接看《算法導論》,大量證明會讓你崩潰。推薦《趣 學算法》,有問題分析,完美圖解,僞碼詳解,實戰演練,适合初學 者快速掌握經典算法。

  1. 為什麼要學資料結構?

  招聘搞笑事

  如果你關注招聘試題,越是大的公司,問的問題越基礎,有的甚至問你什 麼是棧和隊列,反而一些小公司會關心你做過什麼系統,關注點不同,大公司 更注重基礎紮實,發展潛力,而小公司希望你立刻、馬上為他幹活,通常是沒 什麼技術含量的活。小公司喜歡細而長的竹子,大公司更喜歡碗口粗的竹筍。

  我曾經推薦一個學生到某知名公司,沒多久,學生給我說了應聘的事情: “我介紹我開發了企業管理系統、線上商城系統等等,沒想到他問我使用了什 麼資料結構和算法,我懂很多技術,那麼多功能我都實作了,他不問,卻問我 使用了什麼資料結構和算法,你說搞笑不?資料結構、算法我早就忘了,我會 開發軟體還不行嗎?”人力資源總監也回報過來意見:“很搞笑,這個學生做 了不少系統,卻說根本沒用到資料結構和算法。”

  既然雙方都覺得這是一個件搞笑事,我們就攤開來看,資料結構到底是什 麼東西。

  撥雲見日,看清資料結構

  遇到一個實際問題,需要解決兩個事情:

  (1) 如何将資料存儲在計算機中;

  (2) 用什麼方法政策解決問題。

  前者是資料結構,後者是算法。隻有資料結構沒有算法,相當于隻把資料 存儲到計算機中而沒有有效的方法去處理,就像一幢隻有架構的爛尾樓;若隻 有算法,沒有資料結構,就像沙漠裡的海市蜃樓,隻不過是空中樓閣罷了。

  資料是一切能輸入到計算機的資訊總和,結構是指資料之間的關系,資料 結構就是将資料及其之間的關系有效地存儲在計算機中。算法是指對特定問題 求解步驟的一種描述,說白了就是解決問題的方法政策。資料結構和算法不依 賴于語言,什麼語言無所謂。但是如果上機實作的話,就要使用計算機語言。

  遇到一個實際問題,充分利用所學的資料結構,将資料及其之間的關系有 效地存儲在計算機中,然後選擇合适的算法政策,并用程式高效實作,這就是 N.Wirth教授所說的:資料結構+算法=程式。

  為什麼要學習資料結構?

  計算機專業大學生都開設資料結構課程,它是計算機學科知識結構的核心 和技術體系的基石。研究所學生考試也是必考科目,随着科學技術的飛速發展,數

  據結構的基礎性地位不僅沒有動搖,反而由于近年來算法工程師的高薪火爆, 而得到了業内空前的重視。很多人覺得基本的資料結構及操作己經在進階語言 (如C++、JAVA語言中)中封裝,棧、隊列、排序、優先隊列等都可以直接 調用庫函數,學會怎麼調用就好了,幹嘛要重複造輪子?那麼到底有沒有必要 好好學習資料結構?

  先看學習資料結構有什麼用處:

  (1) 學習資料有效存儲的方法

  很多學生在學習資料結構時,問我要不要把單連結清單插入删除代碼背下來?

  要不合上書就不會寫了。我非常詫異,為什麼要背?理工科技術知識很少需要 記憶的,是用的,用的!學習知識不是死記硬背,更重要的是學習處理問題的 方法。同一個問題,如何有效地存儲資料,不同的資料結構産生什麼樣的算法 複雜性,有沒有更好的存儲方法提高算法的效率?例如,用順序表查找需要 〇(?)的時間複雜度,用平衡樹查找需要〇(l〇g?)的時間複雜度。這是什麼概念 呢?就像你有10個億,一覺醒來,兜裡隻剩下30塊!

  (2) 處理具有複雜關系的資料

  現實中很多具有複雜關系的資料,無法通過簡單的庫函數調用實作。專業 認證中特别強調培養學生解決複雜工程問題的能力,什麼是複雜工程問題?就 是需要綜合運用多個知識技術解決的問題。如同現在很多晶片高度內建,完全 不需要晶片内部如何,直接使用就行了。但是,如果在現實中遇到一個複雜問 題,一個晶片隻能完成其中一個功能,難道要連接配接十幾塊晶片來解決這一個問 題?你在搞聖誕樹嘛? 一個樹枝挂個小禮物,叮叮當當的亂響。這顯然是不合 适的,我們需要的是完成該複雜問題的一個晶片,是以需要運用所學的資料結 構知識,高效處理具有複雜關系的資料。

  通過學習資料結構,更加準确、深刻地了解不同資料結構之間的共性和聯 系,學會選擇和改進資料結構,高效地設計并實作各種算法,這才是資料結構 的精髓。

  資料結構為什麼那麼難?

  網絡上太多的同學吐槽被虐,如滔滔江水連綿不絕,資料結構太難了!真 的很難嗎?其實資料結構隻是講了三種:線性結構、樹、圖。到底難在哪裡 呢?通過調查了解大概有四個原因:

  (1)無法接受的描述方式

  資料結構的描述大多是抽象的形式,我們使用自然語言表達習慣了,不容 易接受資料結構的抽象表示。不止一個學生問我,書上的“ElemType”到底是 什麼類型?運作時怎麼提示錯誤。它的意思就是“元素類型”,隻是這樣的描 述,你需要什麼類型就寫什麼類型,例如int。這樣的表達方式讓不少人崩潰。

  (2) 不知道什麼用處

  盡管很多人學習資料結構,有的人是應付考試,有的人考研需要,有的人 參加算法競賽需要,而很多人不太清楚學習資料結構有什麼用處,迷迷糊糊看 書、做題、考試。

  (3) 體會不到其中的妙處

  由于教材、教師等等各種因素影響,很多學生沒有體會到資料結構處理數 據的妙處,經常為學不會而焦頭爛額,無法體會其中樂趣,有趣是才有意思, 興趣是最大的驅動力。一旦體會到其中的奧妙,就會有停不下來的感覺。有讀 者給我留言,老師看了你的書根本停不下來。其實,我寫書的時候也停不下 來,神同步。

  (4) 語言基礎不好

  我一直強調先看圖解,理清思路,再上機。還是有很多同學己經了解了思 路後,因為缺少main函數,輸入輸出格式不對,缺少括号等等各種語言問題卡 殼,而這一切統統戴給了“資料結構太難了”這個大帽子。

  資料結構學習秘籍

  在講學習秘籍之前,首先了解一下資料結構學習的三種境界:

  (1) 會資料結構的基本操作

  這是最基礎的要求,學會各種資料結構的基本操作,取值、查找、插入、 删除等。先看圖解,了解各種資料結構的定義,操作方法,然後看代碼,嘗試 自己動手上機運作,逐漸掌握基本操作。初學時,要想了解資料結構,一定要 學會畫圖,通過畫圖形象表達,更能體會其中的資料結構關系。是以,初學階 段學習利器:畫圖,了解,畫圖。

  (2) 會利用資料結構,解決實際問題

  在掌握了書上的基本操作之後,就可以嘗試利用資料結構解決一些實際問 題了,先學經典應用問題的解決方法,體會資料結構的使用方法,然後再做 題,獨立設計資料結構解決問題。要想熟練應用就必須做大量的題,從做題中 體會其中的方法。最好進行專項練習,比如線性表問題,二叉樹問題,圖問 題,該階段學習利器:做題,反思,做題。

  (3) 熟練使用和改進資料結構,優化算法

  這是最高境界了,也是學習資料結構的精髓所在,單獨學習資料結構是無 法達到這種境界的。它需要在學習算法的過程中慢慢修煉。在學習算法的同 時,逐漸熟練應用、改進,慢慢體會不同資料結構和算法政策的算法複雜性, 最終學會利用資料結構改進和優化算法。該階段已經在資料結構之上,通過在 測試系統上刷各種算法題,體會利用資料結構改進優化算法。該階段學習利 器:刷題,總結,刷題。

  刷題網站:打比賽 HDU、POJ、Vjudge、Code Forces,找工作 LeetCode

  很多人感歎:算法為什麼那麼難!

  首先,算法本身具有一定的複雜性,還有一個原因:講的太爛!

  算法的教與學有兩個困難:

  (1) 我們學習了那些經典的算法,在驚歎它們奇思妙想的同時,難免疑慮 重重:這麼牛,怎麼想到的?對學生來說,這可能是最費解、也最讓人窩火的 地方。高手講,學算法要學它的來龍去脈,包括種種證明。但這對菜鳥來說,

  簡直比登天還難,很可能花費很多時間也無法搞清楚。這條路對大多數人來

  說,是行不通的,那怎麼辦呢?下功夫去記憶書上的算法?記住這些算法的效 率?看似學會了,其實兩手空空。遇到一個新問題,仍然無從下手。可這偏偏 又是極重要的,無論作研究還是實際工作,一個計算機專業人士最重要的能 力,就是解決問題一解決那些不斷從實際應用中冒出來的新問題。

  (2) 算法作為一門學問,有兩條幾乎平行的線索。一個是資料結構(資料 對象):數、矩陣、集合、串、排列、圖、表達式、分布等等。另一個是算法策 略:貪心、分治、動态規劃、線性規劃、搜尋等等。這兩條線索是互相獨立 的:同一個資料對象(例如圖)上有不同的問題,例如單源最短路徑和最優二 叉樹,就可以用到不同的算法政策,如貪心和動态規劃;而同一個算法政策, 例如排序和整數乘法,也會用到不同的資料結構。它們之間是多對多的關系。

  兩條線索交織在一起,該如何表述?

  我們早己習慣《資料結構》中講資料結構,《算法設計與分析》裡面講算 法政策。各說各的,講算法設計時就假設你己經對資料結構了如指掌,還沒有 哪一本算法書很好的解決這兩個困難,傳統的算法書,大多注重内容的收錄, 但卻忽視思維過程的展示,是以我們學習了經典的算法,卻費解于算法設計的 過程。遇到一個實際問題,通過問題分析,選擇使用什麼樣的算法政策,基于 這種

二手賣号平台

算法政策選擇什麼樣的資料結構,有時算法政策和資料結構的選擇并不是 唯一的,不同的算法政策和資料結構設計的算法,其複雜性是不同的。而很多 書就是灌輸式的講一個執行個體,一下子就選擇了一個認定是最優的算法政策,告 訴你就這樣幹,不談資料結構,然後分析算法複雜性,就結束了。原則上講算 法政策就講算法政策,不依賴任何程式設計語言和資料結構,但對很多學生來 講,尤其是語言沒學好,資料結構也不熟練的同學,隻講算法政策,如同空中 樓閣。自己用算法解決實際問題,一頭霧水。

  《趣學算法》,從問題出發,根據實際問題進行分析,選擇合适的算法策 略,并分析為什麼采用這種算法政策,然後選擇什麼資料結構,不同的資料結 構複雜性會有什麼差別,巧妙地将資料結構和算法政策擰成了一條線。通過大 量執行個體,充分展現算法設計的思維過程,讓學生充分體會遇到一個問題,如何

  分析,使用什麼算法政策,采用什麼資料結構,算法的複雜性如何?是否有優 化的可能?

  西方教育旨在激發學生對世界的好奇心,而在這裡,我們培養的是讓學生 懷着一顆好奇心,思考問題、解決問題的能力。更重要的是一一體會學習的樂 趣,發現算法的美!

  知識在于積累,學習需要耐力。學習就像挖金礦,或許一開始毫無頭緒, 一頭霧水,但轉個角度,換換工具,時間久了總會找到一個縫隙。成功就是你 比别人多走了一段路,或許恰恰是那麼一小步。

  第一個建議:多角度,對比學習

  學習算法,可以先閱讀一本簡單的入門書,然後綜合幾本書橫向多角度 看,例如學習動态規劃,拿幾本算法書,把動态規劃這章找出來,比較學習, 多角度對比分析更清晰,或許你會恍然大悟,噢,原來如此簡單。或許有同學 說我哪有那麼多錢買那麼多書,隻要你想學習,沒有什麼可以阻擋!你可以圖 書館借,也可以聯系你的老師,每學期上課前,我都會告訴學生,如果你想學 習卻沒錢買書,我可以提供幫助。想一想,你真的沒有辦法?

  第二個建議:大視野,不求甚解

  經常有學生為了一個公式推導,或幾句代碼抛錨,甚至停滞數日,然後淹 沒在無盡的挫敗感中,把自己弄得垂頭喪氣。公式可以不懂,代碼可以不會。 你不必投入大量精力試圖推導書上的每一個公式,也不必探究文法或技術細 節。學算法就是學算法本身,首先是算法思想,解題思路,然後是算法實作, 算法思想的背後可能有高深的數學模型,複雜的公式推導,你了解了當然玄 妙,不懂就拉倒。算法實作可以用任何語言,是以不必糾結是C,C++,Java, Python,更不必管嚴格的文法規則,除非你要上機調試。建議還是先領會算 法,寫僞代碼,在大腦中調試吧,如果沒有良好的程式設計經驗,一開始就上機或 許更讓你崩潰。遇到不懂的部分,浏覽一下或跳過去,讀完了還不明白再翻翻 别的書,總有一天,你會發現,“暮然回首,那人卻在燈火闌珊處”。

  第三個建議:多交流,見賢思齊

  與同學,朋友,教師或其他程式設計愛好者們一起學習和讨論問題,是取得進 步最有效的辦法,也是分享知識和快樂的途徑。加入論壇,加入交流群,會了 解其它人在做什麼,怎麼做,遇到問題可以請教高手,帶來醍醐灌頂的喜悅; 也可以應助菜鳥,使你暗自得意,信心倍增。論壇和群也會分享大量的學習資 料和視訊,還有不定期的教育訓練講座,讀書交流會,你會發現,不是你一個人在 戰鬥!

  第四個建議:勤實戰,越挫越勇

  實踐是檢驗一切真理的标準。古人雲:“學以緻用”,“師夷長技以制 夷”。請不要急切期盼“實際的”例子,更不要看不起小執行個體,“不積跬步, 無以至千裡”。大規模的成功商業案例所采用的算法,人工情感,無人駕駛, 不是我們目前要解決的問題。看清楚腳下的路,比仰望天空更實際,多做一些 實戰練習,更好地體會算法的本質,在錯誤中不斷成長,越挫越勇,終究會成 參天大樹。

  第五個建議:看電影,洞察未來

  不管是講《人工智能》,還是《算法分析》,我都會建議同學們去看一看 科幻電影,如《人工智能》、《記憶裂痕》、《絕密飛行》、《未來戰士》、 《她》等等。奇妙的是,這些科幻的東西,正在一步步的實作,靠的是什麼? 人工智能。計算機的終極是人工智能,人工智能的核心