如何抓住重點,系統高效地學習資料結構與演算法?

weixin_33807284發表於2019-01-25

你是否曾跟我一樣,因為看不懂資料結構和演算法,而一度懷疑是自己太笨?實際上,很多人在第一次接觸這門課時,都會有這種感覺,覺得資料結構和演算法很抽象,晦澀難懂,宛如天書。正是這個原因,讓很多初學者對這門課望而卻步。

我個人覺得,其實真正的原因是你沒有找到好的學習方法,沒有抓住學習的重點。實際上,資料結構和演算法的東西並不多,常用的、基礎的知識點更是屈指可數。只要掌握了正確的學習方法,學起來並沒有看上去那麼難,更不需要什麼高智商、厚底子。

還記得大學裡每次考前老師都要劃重點嗎?今天,我就給你劃劃我們這門課的重點,再告訴你一些我總結的學習小竅門。相信有了這些之後,你學起來就會有的放矢、事半功倍了。
戳此試讀,42000+程式設計師加入\u0026gt;\u0026gt;\u0026gt;

什麼是資料結構?什麼是演算法?

大部分資料結構和演算法教材,在開篇都會給這兩個概念下一個明確的定義。但是,這些定義都很抽象,對理解這兩個概念並沒有實質性的幫助,反倒會讓你陷入死摳定義的誤區。畢竟,我們現在學習,並不是為了考試,所以,概念背得再牢,不會用也就沒什麼用。

雖然我們說沒必要深挖嚴格的定義,但是這並不等於不需要理解概念。下面我就從廣義和狹義兩個層面,來幫你理解資料結構與演算法這兩個概念。

從廣義上講,資料結構就是指一組資料的儲存結構。演算法就是運算元據的一組方法。

圖書館儲藏書籍你肯定見過吧?為了方便查詢,圖書管理員一般會將書籍分門別類進行“儲存”。按照一定規律編號,就是書籍這種“資料”的儲存結構。

那我們如何來查詢一本書呢?有很多種辦法,你當然可以一本一本地找,也可以先根據書籍類別的編號,是人文,還是科學、計算機,來定位書架,然後再依次查詢。籠統地說,這些查詢方法都是演算法。

從狹義上講,也就是我們專欄要講的,是指某些著名的資料結構和演算法,比如佇列、棧、堆、二分查詢、動態規劃等。這些都是前人智慧的結晶,我們可以直接拿來用。我們要講的這些經典資料結構和演算法,都是前人從很多實際操作場景中抽象出來的,經過非常多的求證和檢驗,可以高效地幫助我們解決很多實際的開發問題。

那資料結構和演算法有什麼關係呢?為什麼大部分書都把這兩個東西放到一塊兒來講呢?

這是因為,資料結構和演算法是相輔相成的。資料結構是為演算法服務的,演算法要作用在特定的資料結構之上。因此,我們無法孤立資料結構來講演算法,也無法孤立演算法來講資料結構。

比如,因為陣列具有隨機訪問的特點,常用的二分查詢演算法需要用陣列來儲存資料。但如果我們選擇連結串列這種資料結構,二分查詢演算法就無法工作了,因為連結串列並不支援隨機訪問。

資料結構是靜態的,它只是組織資料的一種方式。如果不在它的基礎上操作、構建演算法,孤立存在的資料結構就是沒用的。

現在你對資料結構與演算法是不是有了比較清晰的理解了呢?有了這些儲備,下面我們來看看,究竟該怎麼學資料結構與演算法。

學習這個專欄需要什麼基礎?

看到資料結構和演算法裡的“演算法”兩個字,很多人就會聯想到“數學”,覺得演算法會涉及到很多深奧的數學知識。那我數學基礎不是很好,學起來會不會很吃力啊?

資料結構和演算法課程確實會涉及一些數學方面的推理、證明,尤其是在分析某個演算法的時間、空間複雜度的時候,但是這個你完全不需要擔心。

這個專欄不會像《演算法導論》那樣,裡面有非常複雜的數學證明和推理。我會由淺入深,從概念到應用,一點一點給你解釋清楚。你只要有高中數學水平,就完全可以學習。

當然,我希望你最好有些程式設計基礎,如果有專案經驗就更好了。這樣我給你講資料結構和演算法如何提高效率、如何節省儲存空間,你就會有很直觀的感受。因為,對於每個概念和實現過程,我都會從實際場景出發,不僅教你“是什麼”,還會教你“為什麼”,並且告訴你遇到同型別問題應該“怎麼做”。

學習的重點在什麼地方?

提到資料結構和演算法,很多人就很頭疼,因為這裡面的內容實在是太多了。這裡,我就幫你梳理一下,應該先學什麼,後學什麼。你可以對照看看,你屬於哪個階段,然後有針對地進行學習。

想要學習資料結構與演算法,首先要掌握一個資料結構與演算法中最重要的概念——複雜度分析。

這個概念究竟有多重要呢?可以這麼說,它幾乎佔了資料結構和演算法這門課的半壁江山,是資料結構和演算法學習的精髓。

資料結構和演算法解決的是如何更省、更快地儲存和處理資料的問題,因此,我們就需要一個考量效率和資源消耗的方法,這就是複雜度分析方法。所以,如果你只掌握了資料結構和演算法的特點、用法,但是沒有學會複雜度分析,那就相當於只知道操作口訣,而沒掌握心法。只有把心法瞭然於胸,才能做到無招勝有招!

所以,複雜度分析這個內容,我會用很大篇幅給你講透。你也一定要花大力氣來啃,必須要拿下,並且要搞得非常熟練。否則,後面的資料結構和演算法也很難學好。

搞定複雜度分析,下面就要進入資料結構與演算法的正文內容了。

為了讓你對資料結構和演算法能有個全面的認識,我畫了一張圖,裡面幾乎涵蓋了所有資料結構和演算法書籍中都會講到的知識點。
\"\"

但是,作為初學者,或者一個非演算法工程師來說,你並不需要掌握圖裡面的所有知識點。很多高階的資料結構與演算法,比如二分圖、最大流等,這些在我們平常的開發中很少會用到。所以,你暫時可以不用看。我還是那句話,我們們學習要學會找重點。如果不分重點地學習,眉毛鬍子一把抓,學起來肯定會比較吃力。

所以,結合我自己的學習心得,還有這些年的面試、開發經驗,我總結了20個最常用的、最基礎資料結構與演算法,不管是應付面試還是工作需要,只要集中精力逐一攻克這20個知識點就足夠了。

這裡面有10個資料結構:陣列、連結串列、棧、佇列、雜湊表、二叉樹、堆、跳錶、圖、Trie樹;10個演算法:遞迴、排序、二分查詢、搜尋、雜湊演算法、貪心演算法、分治演算法、回溯演算法、動態規劃、字串匹配演算法。

掌握了這些基礎的資料結構和演算法,再學更加複雜的資料結構和演算法,就會非常容易、非常快。

在學習資料結構和演算法的過程中,你也要注意,不要只是死記硬背,不要為了學習而學習,而是要學習它的“來歷”“自身的特點”“適合解決的問題”以及“實際的應用場景”。對於每一種資料結構或演算法,我都會從這幾個方面進行詳細講解。只要你掌握了我每節課裡講的內容,就能在開發中靈活應用。

學習資料結構和演算法的過程,是非常好的思維訓練的過程,所以,千萬不要被動地記憶,要多辯證地思考,多問為什麼。如果你一直這麼堅持做,你會發現,等你學完之後,寫程式碼的時候就會不由自主地考慮到很多效能方面的事情,時間複雜度、空間複雜度非常高的垃圾程式碼出現的次數就會越來越少。你的程式設計內功就真正得到了修煉。

一些可以讓你事半功倍的學習技巧

前面我給你劃了學習的重點,也講了學習這門課需要具備的基礎。作為一個過來人,現在我就給你分享一下,專欄學習的一些技巧。掌握了這些技巧,可以讓你化被動為主動,學起來更加輕鬆,更加有動力!

1.邊學邊練,適度刷題

“邊學邊練”這一招非常有用。建議你每週花1~2個小時的時間,集中把這周的三節內容涉及的資料結構和演算法,全都自己寫出來,用程式碼實現一遍。這樣一定會比單純地看或者聽的效果要好很多!

有面試需求的同學,可能會問了,那我還要不要去刷題呢?

我個人的觀點是可以“適度”刷題,但一定不要浪費太多時間在刷題上。我們學習的目的還是掌握,然後應用。除非你要面試Google、Facebook這樣的公司,它們的演算法題目非常非常難,必須大量刷題,才能在短期內提升應試正確率。如果是應對國內公司的技術面試,即便是BAT這樣的公司,你只要徹底掌握這個專欄的內容,就足以應對。

2.多問、多思考、多互動

學習最好的方法是,找到幾個人一起學習,一塊兒討論切磋,有問題及時尋求老師答疑。但是,離開大學之後,既沒有同學也沒有老師,這個條件就比較難具備了。

不過,這也就是我們們專欄學習的優勢。專欄裡有很多跟你一樣的學習者。你可以多在留言區寫下自己的疑問、思考和總結,也可以經常看看別人的留言,和他們進行互動。

除此之外,如果你有疑問,你可以隨時在留言區給我留言,我只要有空就會及時回覆你。你不要擔心問的問題太小白。因為我初學的時候,也常常會被一些小白問題困擾。不懂一點都不丟人,只要你勇敢提出來,我們一起解決了就可以了。

我也會力爭每節課都最大限度地給你講透,幫你掃除知識盲點,而你要做的就是,避免一知半解,要想盡一切辦法去搞懂我講的所有內容。

3.打怪升級學習法

學習的過程中,我們碰到最大的問題就是,堅持不下來。是的,很多基礎課程學起來都非常枯燥。為此,我自己總結了一套“打怪升級學習法”。

遊戲你肯定玩過吧?為什麼很多看起來非常簡單又沒有樂趣的遊戲,你會玩得不亦樂乎呢?這是因為,當你努力打到一定級別之後,每天看著自己的經驗值、戰鬥力在慢慢提高,那種每天都在一點一點成長的成就感就不由自主地產生了。

所以,我們在枯燥的學習過程中,也可以給自己設立一個切實可行的目標,就像打怪升級一樣。

比如,針對這個專欄,你就可以設立這樣一個目標:每節課後的思考題都認真思考,並且回覆到留言區。當你看到很多人給你點贊之後,你就會為了每次都能發一個漂亮的留言,而更加認真地學習。

當然,還有很多其他的目標,比如,每節課後都寫一篇學習筆記或者學習心得;或者你還可以每節課都找一下我講得不對、不合理的地方……諸如此類,你可以總結一個適合你的“打怪升級攻略”。

如果你能這樣學習一段時間,不僅能收穫到知識,你還會有意想不到的成就感。因為,這其實幫你改掉了一點學習的壞習慣。這個習慣一旦改掉了,你的人生也會變得不一樣。

4.知識需要沉澱,不要想試圖一下子掌握所有

在學習的過程中,一定會碰到“攔路虎”。如果哪個知識點沒有怎麼學懂,不要著急,這是正常的。因為,想聽一遍、看一遍就把所有知識掌握,這肯定是不可能的。學習知識的過程是反覆迭代、不斷沉澱的過程。

如果碰到“攔路虎”,你可以盡情地在留言區問我,也可以先沉澱一下,過幾天再重新學一遍。所謂,書讀百遍其義自見,我覺得是很有道理的!

我講的這些學習方法,不僅僅針對我們們這一個課程的學習,其實完全適用任何知識的學習過程。你可以通過這個專欄的學習,實踐一下這些方法。如果效果不錯,再推廣到之後的學習過程中。

內容小結

今天,我帶你劃了劃資料結構和演算法的學習重點,複雜度分析,以及10個資料結構和10個演算法。

這些內容是我根據平時的學習和工作、面試經驗積累,精心篩選出來的。只要掌握這些內容,應付日常的面試、工作,基本不會有問題。

除此之外,我還給你分享了我總結的一些學習技巧,比如邊學邊練、多問、多思考,還有兩個比較通用的學習方法,打怪升級法和沉澱法。掌握了這些學習技巧,可以讓你學習過程中事半功倍。所以,你一定要好好實踐哦!

戳此立即訂閱,42000+程式設計師已經加入\u0026gt;\u0026gt;\u0026gt;

相關文章