如何抓住重点,系统高效地学习数据结构与算法?
你是否曾跟我一樣,因?yàn)榭床欢當(dāng)?shù)據(jù)結(jié)構(gòu)和算法,而一度懷疑是自己太笨?實(shí)際上,很多人在第一次接觸這門課時(shí),都會有這種感覺,覺得數(shù)據(jù)結(jié)構(gòu)和算法很抽象,晦澀難懂,宛如天書。正是這個(gè)原因,讓很多初學(xué)者對這門課望而卻步。
我個(gè)人覺得,其實(shí)真正的原因是你沒有找到好的學(xué)習(xí)方法,沒有抓住學(xué)習(xí)的重點(diǎn)。實(shí)際上,數(shù)據(jù)結(jié)構(gòu)和算法的東西并不多,常用的、基礎(chǔ)的知識點(diǎn)更是屈指可數(shù)。只要掌握了正確的學(xué)習(xí)方法,學(xué)起來并沒有看上去那么難,更不需要什么高智商、厚底子。
還記得大學(xué)里每次考前老師都要?jiǎng)澲攸c(diǎn)嗎?今天,我就給你劃劃我們這門課的重點(diǎn),再告訴你一些我總結(jié)的學(xué)習(xí)小竅門。相信有了這些之后,你學(xué)起來就會有的放矢、事半功倍了。
戳此試讀,42000+程序員加入\u0026gt;\u0026gt;\u0026gt;
什么是數(shù)據(jù)結(jié)構(gòu)?什么是算法?
大部分?jǐn)?shù)據(jù)結(jié)構(gòu)和算法教材,在開篇都會給這兩個(gè)概念下一個(gè)明確的定義。但是,這些定義都很抽象,對理解這兩個(gè)概念并沒有實(shí)質(zhì)性的幫助,反倒會讓你陷入死摳定義的誤區(qū)。畢竟,我們現(xiàn)在學(xué)習(xí),并不是為了考試,所以,概念背得再牢,不會用也就沒什么用。
雖然我們說沒必要深挖嚴(yán)格的定義,但是這并不等于不需要理解概念。下面我就從廣義和狹義兩個(gè)層面,來幫你理解數(shù)據(jù)結(jié)構(gòu)與算法這兩個(gè)概念。
從廣義上講,數(shù)據(jù)結(jié)構(gòu)就是指一組數(shù)據(jù)的存儲結(jié)構(gòu)。算法就是操作數(shù)據(jù)的一組方法。
圖書館儲藏書籍你肯定見過吧?為了方便查找,圖書管理員一般會將書籍分門別類進(jìn)行“存儲”。按照一定規(guī)律編號,就是書籍這種“數(shù)據(jù)”的存儲結(jié)構(gòu)。
那我們?nèi)绾蝸聿檎乙槐緯?#xff1f;有很多種辦法,你當(dāng)然可以一本一本地找,也可以先根據(jù)書籍類別的編號,是人文,還是科學(xué)、計(jì)算機(jī),來定位書架,然后再依次查找。籠統(tǒng)地說,這些查找方法都是算法。
從狹義上講,也就是我們專欄要講的,是指某些著名的數(shù)據(jù)結(jié)構(gòu)和算法,比如隊(duì)列、棧、堆、二分查找、動態(tài)規(guī)劃等。這些都是前人智慧的結(jié)晶,我們可以直接拿來用。我們要講的這些經(jīng)典數(shù)據(jù)結(jié)構(gòu)和算法,都是前人從很多實(shí)際操作場景中抽象出來的,經(jīng)過非常多的求證和檢驗(yàn),可以高效地幫助我們解決很多實(shí)際的開發(fā)問題。
那數(shù)據(jù)結(jié)構(gòu)和算法有什么關(guān)系呢?為什么大部分書都把這兩個(gè)東西放到一塊兒來講呢?
這是因?yàn)?#xff0c;數(shù)據(jù)結(jié)構(gòu)和算法是相輔相成的。數(shù)據(jù)結(jié)構(gòu)是為算法服務(wù)的,算法要作用在特定的數(shù)據(jù)結(jié)構(gòu)之上。因此,我們無法孤立數(shù)據(jù)結(jié)構(gòu)來講算法,也無法孤立算法來講數(shù)據(jù)結(jié)構(gòu)。
比如,因?yàn)閿?shù)組具有隨機(jī)訪問的特點(diǎn),常用的二分查找算法需要用數(shù)組來存儲數(shù)據(jù)。但如果我們選擇鏈表這種數(shù)據(jù)結(jié)構(gòu),二分查找算法就無法工作了,因?yàn)殒湵聿⒉恢С蛛S機(jī)訪問。
數(shù)據(jù)結(jié)構(gòu)是靜態(tài)的,它只是組織數(shù)據(jù)的一種方式。如果不在它的基礎(chǔ)上操作、構(gòu)建算法,孤立存在的數(shù)據(jù)結(jié)構(gòu)就是沒用的。
現(xiàn)在你對數(shù)據(jù)結(jié)構(gòu)與算法是不是有了比較清晰的理解了呢?有了這些儲備,下面我們來看看,究竟該怎么學(xué)數(shù)據(jù)結(jié)構(gòu)與算法。
學(xué)習(xí)這個(gè)專欄需要什么基礎(chǔ)?
看到數(shù)據(jù)結(jié)構(gòu)和算法里的“算法”兩個(gè)字,很多人就會聯(lián)想到“數(shù)學(xué)”,覺得算法會涉及到很多深奧的數(shù)學(xué)知識。那我數(shù)學(xué)基礎(chǔ)不是很好,學(xué)起來會不會很吃力啊?
數(shù)據(jù)結(jié)構(gòu)和算法課程確實(shí)會涉及一些數(shù)學(xué)方面的推理、證明,尤其是在分析某個(gè)算法的時(shí)間、空間復(fù)雜度的時(shí)候,但是這個(gè)你完全不需要擔(dān)心。
這個(gè)專欄不會像《算法導(dǎo)論》那樣,里面有非常復(fù)雜的數(shù)學(xué)證明和推理。我會由淺入深,從概念到應(yīng)用,一點(diǎn)一點(diǎn)給你解釋清楚。你只要有高中數(shù)學(xué)水平,就完全可以學(xué)習(xí)。
當(dāng)然,我希望你最好有些編程基礎(chǔ),如果有項(xiàng)目經(jīng)驗(yàn)就更好了。這樣我給你講數(shù)據(jù)結(jié)構(gòu)和算法如何提高效率、如何節(jié)省存儲空間,你就會有很直觀的感受。因?yàn)?#xff0c;對于每個(gè)概念和實(shí)現(xiàn)過程,我都會從實(shí)際場景出發(fā),不僅教你“是什么”,還會教你“為什么”,并且告訴你遇到同類型問題應(yīng)該“怎么做”。
學(xué)習(xí)的重點(diǎn)在什么地方?
提到數(shù)據(jù)結(jié)構(gòu)和算法,很多人就很頭疼,因?yàn)檫@里面的內(nèi)容實(shí)在是太多了。這里,我就幫你梳理一下,應(yīng)該先學(xué)什么,后學(xué)什么。你可以對照看看,你屬于哪個(gè)階段,然后有針對地進(jìn)行學(xué)習(xí)。
想要學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)與算法,首先要掌握一個(gè)數(shù)據(jù)結(jié)構(gòu)與算法中最重要的概念——復(fù)雜度分析。
這個(gè)概念究竟有多重要呢?可以這么說,它幾乎占了數(shù)據(jù)結(jié)構(gòu)和算法這門課的半壁江山,是數(shù)據(jù)結(jié)構(gòu)和算法學(xué)習(xí)的精髓。
數(shù)據(jù)結(jié)構(gòu)和算法解決的是如何更省、更快地存儲和處理數(shù)據(jù)的問題,因此,我們就需要一個(gè)考量效率和資源消耗的方法,這就是復(fù)雜度分析方法。所以,如果你只掌握了數(shù)據(jù)結(jié)構(gòu)和算法的特點(diǎn)、用法,但是沒有學(xué)會復(fù)雜度分析,那就相當(dāng)于只知道操作口訣,而沒掌握心法。只有把心法了然于胸,才能做到無招勝有招!
所以,復(fù)雜度分析這個(gè)內(nèi)容,我會用很大篇幅給你講透。你也一定要花大力氣來啃,必須要拿下,并且要搞得非常熟練。否則,后面的數(shù)據(jù)結(jié)構(gòu)和算法也很難學(xué)好。
搞定復(fù)雜度分析,下面就要進(jìn)入數(shù)據(jù)結(jié)構(gòu)與算法的正文內(nèi)容了。
為了讓你對數(shù)據(jù)結(jié)構(gòu)和算法能有個(gè)全面的認(rèn)識,我畫了一張圖,里面幾乎涵蓋了所有數(shù)據(jù)結(jié)構(gòu)和算法書籍中都會講到的知識點(diǎn)。
但是,作為初學(xué)者,或者一個(gè)非算法工程師來說,你并不需要掌握圖里面的所有知識點(diǎn)。很多高級的數(shù)據(jù)結(jié)構(gòu)與算法,比如二分圖、最大流等,這些在我們平常的開發(fā)中很少會用到。所以,你暫時(shí)可以不用看。我還是那句話,咱們學(xué)習(xí)要學(xué)會找重點(diǎn)。如果不分重點(diǎn)地學(xué)習(xí),眉毛胡子一把抓,學(xué)起來肯定會比較吃力。
所以,結(jié)合我自己的學(xué)習(xí)心得,還有這些年的面試、開發(fā)經(jīng)驗(yàn),我總結(jié)了20個(gè)最常用的、最基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)與算法,不管是應(yīng)付面試還是工作需要,只要集中精力逐一攻克這20個(gè)知識點(diǎn)就足夠了。
這里面有10個(gè)數(shù)據(jù)結(jié)構(gòu):數(shù)組、鏈表、棧、隊(duì)列、散列表、二叉樹、堆、跳表、圖、Trie樹;10個(gè)算法:遞歸、排序、二分查找、搜索、哈希算法、貪心算法、分治算法、回溯算法、動態(tài)規(guī)劃、字符串匹配算法。
掌握了這些基礎(chǔ)的數(shù)據(jù)結(jié)構(gòu)和算法,再學(xué)更加復(fù)雜的數(shù)據(jù)結(jié)構(gòu)和算法,就會非常容易、非常快。
在學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)和算法的過程中,你也要注意,不要只是死記硬背,不要為了學(xué)習(xí)而學(xué)習(xí),而是要學(xué)習(xí)它的“來歷”“自身的特點(diǎn)”“適合解決的問題”以及“實(shí)際的應(yīng)用場景”。對于每一種數(shù)據(jù)結(jié)構(gòu)或算法,我都會從這幾個(gè)方面進(jìn)行詳細(xì)講解。只要你掌握了我每節(jié)課里講的內(nèi)容,就能在開發(fā)中靈活應(yīng)用。
學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)和算法的過程,是非常好的思維訓(xùn)練的過程,所以,千萬不要被動地記憶,要多辯證地思考,多問為什么。如果你一直這么堅(jiān)持做,你會發(fā)現(xiàn),等你學(xué)完之后,寫代碼的時(shí)候就會不由自主地考慮到很多性能方面的事情,時(shí)間復(fù)雜度、空間復(fù)雜度非常高的垃圾代碼出現(xiàn)的次數(shù)就會越來越少。你的編程內(nèi)功就真正得到了修煉。
一些可以讓你事半功倍的學(xué)習(xí)技巧
前面我給你劃了學(xué)習(xí)的重點(diǎn),也講了學(xué)習(xí)這門課需要具備的基礎(chǔ)。作為一個(gè)過來人,現(xiàn)在我就給你分享一下,專欄學(xué)習(xí)的一些技巧。掌握了這些技巧,可以讓你化被動為主動,學(xué)起來更加輕松,更加有動力!
1.邊學(xué)邊練,適度刷題
“邊學(xué)邊練”這一招非常有用。建議你每周花1~2個(gè)小時(shí)的時(shí)間,集中把這周的三節(jié)內(nèi)容涉及的數(shù)據(jù)結(jié)構(gòu)和算法,全都自己寫出來,用代碼實(shí)現(xiàn)一遍。這樣一定會比單純地看或者聽的效果要好很多!
有面試需求的同學(xué),可能會問了,那我還要不要去刷題呢?
我個(gè)人的觀點(diǎn)是可以“適度”刷題,但一定不要浪費(fèi)太多時(shí)間在刷題上。我們學(xué)習(xí)的目的還是掌握,然后應(yīng)用。除非你要面試Google、Facebook這樣的公司,它們的算法題目非常非常難,必須大量刷題,才能在短期內(nèi)提升應(yīng)試正確率。如果是應(yīng)對國內(nèi)公司的技術(shù)面試,即便是BAT這樣的公司,你只要徹底掌握這個(gè)專欄的內(nèi)容,就足以應(yīng)對。
2.多問、多思考、多互動
學(xué)習(xí)最好的方法是,找到幾個(gè)人一起學(xué)習(xí),一塊兒討論切磋,有問題及時(shí)尋求老師答疑。但是,離開大學(xué)之后,既沒有同學(xué)也沒有老師,這個(gè)條件就比較難具備了。
不過,這也就是咱們專欄學(xué)習(xí)的優(yōu)勢。專欄里有很多跟你一樣的學(xué)習(xí)者。你可以多在留言區(qū)寫下自己的疑問、思考和總結(jié),也可以經(jīng)常看看別人的留言,和他們進(jìn)行互動。
除此之外,如果你有疑問,你可以隨時(shí)在留言區(qū)給我留言,我只要有空就會及時(shí)回復(fù)你。你不要擔(dān)心問的問題太小白。因?yàn)槲页鯇W(xué)的時(shí)候,也常常會被一些小白問題困擾。不懂一點(diǎn)都不丟人,只要你勇敢提出來,我們一起解決了就可以了。
我也會力爭每節(jié)課都最大限度地給你講透,幫你掃除知識盲點(diǎn),而你要做的就是,避免一知半解,要想盡一切辦法去搞懂我講的所有內(nèi)容。
3.打怪升級學(xué)習(xí)法
學(xué)習(xí)的過程中,我們碰到最大的問題就是,堅(jiān)持不下來。是的,很多基礎(chǔ)課程學(xué)起來都非常枯燥。為此,我自己總結(jié)了一套“打怪升級學(xué)習(xí)法”。
游戲你肯定玩過吧?為什么很多看起來非常簡單又沒有樂趣的游戲,你會玩得不亦樂乎呢?這是因?yàn)?#xff0c;當(dāng)你努力打到一定級別之后,每天看著自己的經(jīng)驗(yàn)值、戰(zhàn)斗力在慢慢提高,那種每天都在一點(diǎn)一點(diǎn)成長的成就感就不由自主地產(chǎn)生了。
所以,我們在枯燥的學(xué)習(xí)過程中,也可以給自己設(shè)立一個(gè)切實(shí)可行的目標(biāo),就像打怪升級一樣。
比如,針對這個(gè)專欄,你就可以設(shè)立這樣一個(gè)目標(biāo):每節(jié)課后的思考題都認(rèn)真思考,并且回復(fù)到留言區(qū)。當(dāng)你看到很多人給你點(diǎn)贊之后,你就會為了每次都能發(fā)一個(gè)漂亮的留言,而更加認(rèn)真地學(xué)習(xí)。
當(dāng)然,還有很多其他的目標(biāo),比如,每節(jié)課后都寫一篇學(xué)習(xí)筆記或者學(xué)習(xí)心得;或者你還可以每節(jié)課都找一下我講得不對、不合理的地方……諸如此類,你可以總結(jié)一個(gè)適合你的“打怪升級攻略”。
如果你能這樣學(xué)習(xí)一段時(shí)間,不僅能收獲到知識,你還會有意想不到的成就感。因?yàn)?#xff0c;這其實(shí)幫你改掉了一點(diǎn)學(xué)習(xí)的壞習(xí)慣。這個(gè)習(xí)慣一旦改掉了,你的人生也會變得不一樣。
4.知識需要沉淀,不要想試圖一下子掌握所有
在學(xué)習(xí)的過程中,一定會碰到“攔路虎”。如果哪個(gè)知識點(diǎn)沒有怎么學(xué)懂,不要著急,這是正常的。因?yàn)?#xff0c;想聽一遍、看一遍就把所有知識掌握,這肯定是不可能的。學(xué)習(xí)知識的過程是反復(fù)迭代、不斷沉淀的過程。
如果碰到“攔路虎”,你可以盡情地在留言區(qū)問我,也可以先沉淀一下,過幾天再重新學(xué)一遍。所謂,書讀百遍其義自見,我覺得是很有道理的!
我講的這些學(xué)習(xí)方法,不僅僅針對咱們這一個(gè)課程的學(xué)習(xí),其實(shí)完全適用任何知識的學(xué)習(xí)過程。你可以通過這個(gè)專欄的學(xué)習(xí),實(shí)踐一下這些方法。如果效果不錯(cuò),再推廣到之后的學(xué)習(xí)過程中。
內(nèi)容小結(jié)
今天,我?guī)銊澚藙潝?shù)據(jù)結(jié)構(gòu)和算法的學(xué)習(xí)重點(diǎn),復(fù)雜度分析,以及10個(gè)數(shù)據(jù)結(jié)構(gòu)和10個(gè)算法。
這些內(nèi)容是我根據(jù)平時(shí)的學(xué)習(xí)和工作、面試經(jīng)驗(yàn)積累,精心篩選出來的。只要掌握這些內(nèi)容,應(yīng)付日常的面試、工作,基本不會有問題。
除此之外,我還給你分享了我總結(jié)的一些學(xué)習(xí)技巧,比如邊學(xué)邊練、多問、多思考,還有兩個(gè)比較通用的學(xué)習(xí)方法,打怪升級法和沉淀法。掌握了這些學(xué)習(xí)技巧,可以讓你學(xué)習(xí)過程中事半功倍。所以,你一定要好好實(shí)踐哦!
戳此立即訂閱,42000+程序員已經(jīng)加入\u0026gt;\u0026gt;\u0026gt;
總結(jié)
以上是生活随笔為你收集整理的如何抓住重点,系统高效地学习数据结构与算法?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【安卓作业】星座查询小程序
- 下一篇: matlab系统数学模型建立,第五章 m