剛學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)與算法時(shí)冯丙,就被告知?“程序=算法+數(shù)據(jù)結(jié)構(gòu)”既绩,而這段話來自于對(duì)點(diǎn)計(jì)算機(jī)科學(xué)家Niklaus Wirth在1976年出版的一本書的書名怠褐,后來這句話也成為計(jì)算機(jī)工作者之間流傳的一句名言昌腰,小編也用慘痛的經(jīng)歷告訴大家這也是一個(gè)很重要的知識(shí)點(diǎn)褂删。
那么到底什么是數(shù)據(jù)結(jié)構(gòu)和算法飞醉,數(shù)據(jù)結(jié)構(gòu)算法又有什么用呢?
首先來說說什么是數(shù)據(jù)結(jié)構(gòu)屯阀,直接上圖
從圖中我們可以很直觀的看出數(shù)據(jù)結(jié)構(gòu)涵蓋的內(nèi)容缅帘。
算法的介紹就相對(duì)抽象了,百度百科給出的解釋是
算法是對(duì)特定問題求解步驟的一種描述蹲盘,它是指令的有限序列股毫,其中每一條指令表示一個(gè)或者多個(gè)操作。
但是我們從他的特性來理解就會(huì)簡(jiǎn)單多了召衔。
算法主要有五個(gè)特性
· 有窮性:指令序列是有限的
· 確定性:每條語句的含義明確铃诬,無二義性
· 可行性:每條語句都應(yīng)在有限的時(shí)間內(nèi)完成
· 輸入:零個(gè)或者多個(gè)輸入
· 輸出:一個(gè)或者多個(gè)輸出?
說到數(shù)據(jù)結(jié)構(gòu)算法的用處,當(dāng)你用著java容器類很爽的時(shí)候苍凛,你有沒有想過趣席,怎么ArrayList像一個(gè)無限擴(kuò)充的數(shù)組,也好像一個(gè)鏈表醇蝴。好用嗎宣肚?當(dāng)然好用這就是數(shù)據(jù)結(jié)構(gòu)的用處,只不過你在不知不覺中使用了悠栓。
用于現(xiàn)實(shí)世界的存儲(chǔ)霉涨,我們使用的工具和建模。每種數(shù)據(jù)結(jié)構(gòu)有自己的優(yōu)點(diǎn)和缺點(diǎn)惭适,想想如果Google的數(shù)據(jù)用的是數(shù)組的存儲(chǔ)笙瑟,我們還能方便地查詢到所需要的數(shù)據(jù)嗎。
而算法癞志,在這么多的數(shù)據(jù)中如何做到最快的插入往枷,查找,刪除,也是在追求更快错洁。
說了這么多
算法和程序到底有什么區(qū)別呢秉宿?
程序是軟件開發(fā)人員根據(jù)用戶需求開發(fā)的、用程序設(shè)計(jì)語言描述的適合計(jì)算機(jī)執(zhí)行的指令(語句)序列屯碴。除此描睦,程序還包括四個(gè)要素,數(shù)據(jù)結(jié)構(gòu)窿锉、算法酌摇、程序設(shè)計(jì)方法、編程語言嗡载。
程序與算法又不同窑多。程序是算法用某種程序設(shè)計(jì)語言的具體實(shí)現(xiàn)。程序可以不滿足算法的有窮性洼滚,比如操作系統(tǒng)也是一種程序埂息,如果你愿意,你的電腦可以一直開著遥巴,保持操作系統(tǒng)的運(yùn)行千康。
程序、算法铲掐、軟件之間又存在著一定的關(guān)系:
程序:算法的計(jì)算機(jī)實(shí)現(xiàn)拾弃。用某種編程語言實(shí)現(xiàn)。
算法:表示問題的解摆霉。
軟件:程序+文檔?
算了豪椿,還是用圖片來表達(dá)他們相互之間的關(guān)系更加容易理解?
干貨太多就顯得太死板,下面來說說和技術(shù)無關(guān)的携栋。
大學(xué)里那本嚴(yán)蔚敏的數(shù)據(jù)結(jié)構(gòu)搭盾,大家都不陌生吧。 雖然不厚婉支,但是相信仍然會(huì)在多年后支配大家的恐懼鸯隅。?
這本書中的內(nèi)容也算豐富,但是對(duì)于復(fù)雜問題的講解就很少了向挖。
后來在知乎看到濤吳的回答蝌以,覺得很有意思,這里引用一下他的回答:?
如果說 Java 是自動(dòng)檔轎車何之,C 就是手動(dòng)檔吉普跟畅。數(shù)據(jù)結(jié)構(gòu)呢?是變速箱的工作原理帝美。你完全可以不知道變速箱怎樣工作,就把自動(dòng)檔的車子從 A 開到 B,而且未必就比懂得的人慢悼潭。
寫程序這件事庇忌,和開車一樣,經(jīng)驗(yàn)可以起到很大作用舰褪,但如果你不知道底層是怎么工作的皆疹,就永遠(yuǎn)只能開車,既不會(huì)修車占拍,也不能造車略就。如果你對(duì)這兩件事都不感興趣也就罷了,數(shù)據(jù)結(jié)構(gòu)懂得用就好晃酒。但若你此生在編程領(lǐng)域還有點(diǎn)更高的追求表牢,數(shù)據(jù)結(jié)構(gòu)是繞不開的課題。?
Java 替你做了太多事情贝次,那么多動(dòng)不動(dòng)還支持范型的容器類崔兴,加上垃圾收集,會(huì)讓你覺得編程很容易蛔翅。但你有沒有想過敲茄,那些容器類是怎么來的,以及它存在的意義是什么山析?最粗淺的堰燎,比如 ArrayList 這個(gè)類,你想過它的存在是多么大的福利嗎——一個(gè)可以隨機(jī)訪問笋轨、自動(dòng)增加容量的數(shù)組秆剪,這種東西 C 是沒有的,要自己實(shí)現(xiàn)翩腐。
但是鸟款,具體怎么實(shí)現(xiàn)呢?如果你對(duì)這種問題感興趣茂卦,那數(shù)據(jù)結(jié)構(gòu)是一定要看的何什。甚至,面向?qū)ο缶幊谭妒奖旧淼攘褪莻€(gè)數(shù)據(jù)結(jié)構(gòu)問題:怎么才能把數(shù)據(jù)和操作數(shù)據(jù)的方法封裝到一起处渣,來造出 class / prototype 這種東西?
此外蛛砰,很重要的一點(diǎn)是罐栈,數(shù)據(jù)結(jié)構(gòu)也是通向各種實(shí)用算法的基石,所以學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)都是提升內(nèi)力的事情泥畅。?
反正我有醍醐灌頂?shù)母杏X荠诬,能把復(fù)雜的東西這么通俗的講解出來,大牛的視角果然與常人不同。
其實(shí)當(dāng)你生活中的編程問題需要解決的時(shí)候柑贞,你會(huì)發(fā)現(xiàn)到處都是數(shù)據(jù)結(jié)構(gòu)的使用方椎,像基金買入買出不是隊(duì)列嗎,先進(jìn)先出钧嘶;像簡(jiǎn)單的一個(gè)班級(jí)學(xué)生的數(shù)據(jù)保存棠众,用個(gè)數(shù)組不就可以解決了嗎;再復(fù)雜的游戲路線問題有决,這不是圖的問題嗎闸拿;Java里面有Tree這字的,其實(shí)不也是用到樹的原理嗎书幕??
種種下來新荤,你會(huì)發(fā)現(xiàn),原來現(xiàn)實(shí)問題和語言里面的封裝按咒,都是和這些有聯(lián)系的迟隅,每當(dāng)你學(xué)會(huì)一種,就會(huì)恍然大悟励七,這不就是當(dāng)年西湖河畔的夏雨荷智袭,就是這種感覺。
好了掠抬,關(guān)于數(shù)據(jù)結(jié)構(gòu)今天就聊這么多吼野。