如何理解「程序=演算法+數據結構」這句話?

"演算法+數據結構=程序"過時了嗎?-C/C++-ChinaUnix.net

這裡有個很激烈的討論


這就相當於:"作文=語法+詞語"

你不能說它有錯,但這話也沒什麼意義。

因為你掌握了語法和辭彙並不意味著你會寫作文,同樣你掌握了演算法和數據結構並不意味著你會寫程序。


你知道么,這其實是一本書,到處都有介紹。

所以,你們這種伸手黨真是毫無前途。


多用心寫一些代碼,被bug折磨到引以為樂估計你就明白了


不需要理解,寫多了自然就懂。如果沒寫過程序就深刻理解了這句話,反而比較奇怪。

計算機不是政治 馬哲,需要靠實踐和思考,不看參悟。


程序不等於軟體


按自頂向下的方式來看。

首先,程序本質上是由一組指令按一定規則組織而成的指令序列。

其次,指令由數據類型(即類)的實例(即對象)以及對實例執行的運算組成。

再者,數據類型是由一個數據集以及作用於此數據集上的運算集構成的系統,即數據類型 = 數據集 + 運算集。

最後,數據結構用於定義及實現數據集,而演算法則用於定義及實現運算集。

綜上所述,程序 = 數據結構 + 演算法。

本人才疏學淺,若回答中有錯漏之處,還請各位知友批評指正。


之前確實有點小感觸。。。。先佔座

/*********************

** 版權所有,僅供參考

**********************/

演算法相當於邏輯,小部分已為人們發掘出來(這裡的小部分指的是書本里講的各種演算法,屬於人們對於特定模式抽象出來的核心,比如排序),可以看做一種模式。對應於業務來說,一種邏輯(可能由其他元子邏輯組合而成)一旦確定下來,便可看做常量,固定不變。

數據結構即數據表示,說白了就是數據,比如用戶數據,屬於互聯網玩的主要部分。這裡面有一個問題,就是如何合理高效表示數據。為此,人們想出了各種各樣的數據結構,比如數組,比如樹。還有一點就是代碼通用性的考量。對於一個設計良好的數據(結構)來講,應當可以保證在代碼邏輯不變的基礎上,功能的增加只需在數據層動點手腳完成:下拉菜單數據中追加一條「詳情頁」的數據和對應的回調方法,即可完成新菜單項的添加工作。

【摘自 http://dingzhihao.github.io/blog/2015/01/11/codingzhi-jian-ru-jia-jing/】


等你看了好多源碼之後,你會發現:程序的具體實現完全靠數據結構和演算法啊。

日常生活中的,一個個問題都需要建模,建立數據結構,具體執行的策略,那就要靠演算法了。

如果再加上設計模式,就為了讓代碼實現起來更優雅。

問題 —&> 數據結構+演算法 == 程序 —&> 解決問題

可以說,只要你用程序來解決現實中的問題,數據結構演算法一天都不會過時。


「演算法「 -&> 邏輯

「數據結構「 -&> 存儲

當然一般而言程序還有通訊這東西。。。

其實程序=演算法+數據結構用在OI上是很適用的。。。


總起

先放結論,根據實際問題去設計數據結構,在數據結構基礎上進行演算法設計。即,數據結構特點決定了演算法的設計。

舉一些簡單的例子,如果數據結構是鏈式存儲的二叉樹,那麼就可以在其上面使用深度優先搜索以及廣度優先搜索。如果是圖數據結構,需要根據圖的特點來設計演算法,在深度優先遍歷或廣度優先遍歷的時候就需要考慮記錄訪問過的結點。

數據結構

數據結構很重要。一些大師在進行編程之前在數據結構上花費的時間是最多的。只有將數據結構設計好了,才能在此基礎上使用演算法。

接下來,介紹一下數組,鏈表,樹,圖,隊列,棧相關的內容以及它們之間存在的一些關係。

數組這種數據結構有其隨機訪問的特點,靠下標就能訪問。這種訪問方式十分高效。

鏈表雖然不能利用下標訪問,但對於內存的使用很具有靈活性,所以這個優點讓它應用也十分廣泛。因為在實際程序我們不能總是確定內存中有合適的空間。鏈表最大的作用感覺也在於此,其更適用於非隨機訪問的情況。

但是顯然鏈表這種結構存在查找效率低的特點,這種問題應該如何解決呢?有沒有一種辦法既可以靈活分配內存,同時又能提高查找效率呢?(查找這個動作,往往是程序必不可少的一部分,幾乎所有的程序都會涉及到查找這個動作,所以其效率便十分重要了)

先說一下總的方法,有序是查詢得以優化的重要原因。先來說說樹,樹的組織一般也是鏈式存儲的,好處就在於原來n個條目的數據存儲在鏈表中,當我們進行查詢時,查詢第3個就必須經過第2個。查詢第n個,就必須得經過前n-1個結點。那麼問題來了,難道結點n前面的那些結點都需要經過嗎?顯然不是,這也說明了鏈表的局限性。相對而言,樹的組織方式使我們在遍歷時可以進行選擇,比如說,二叉樹中我們需要選定一個分支,相對而言,鏈表中我們沒得選擇。選擇的出現帶來了一定的優化。比如二叉排序樹,堆等。這些樹的構建,都是根據我們的目的來進行構建的。

棧,隊列,則是由現實世界借鑒而來的。首先,現實世界中,隊列棧這些形式普遍存在於現實生活中,而程序從某種角度是服務於現實生活中,所以就抽象出了計算機中的所謂棧,隊列的概念。思想體現在程序的執行過程中,體現在程序開發設計中。事實上,棧,隊列的思想不僅體現在了軟體層面,計算機硬體層面也是很多地方應用了這中思想,比如指令隊列(指令執行的先後順序決定了隊列適用於它),比如說寄存器棧(計算的次序決定了可以用棧來實現)。另外,函數調用機制也是棧的應用,a調用b,b調用c,這個過程在我們看來比較簡單,但是在計算機中,在調用時則需要保存一系列信息,調用的過程以及返回的過程(c只能返回到b,不能直接返回到c)這個過程適合通過棧這種結構來進行模擬。

演算法

設計了好的數據結構,只是成功了一半,因為數據結構是靜態的,只是組織數據的一種方式,你不去操作它(如訪問),它是無法發揮它的作用的。所以,我們需要在此基礎上去根據我們的目的進行相應的操作,而操作的方式不同,耗費的時間也是不一樣的,我們需要找到好的操作方案。這裡所說的方案,就是演算法。

舉一個簡單的例子,你打算從家到學校,有多個公交可以坐,可以產生很多方案,每一種方案都是你對於達成目標的一種設計,我們稱之為演算法。人們往往會在眾多方案中尋找最優的演算法。我們這裡的方案的數量是有限的,但是事實上,很多問題的方案是無限的,甚至巨大的,我們無法一一去嘗試這些方案。所以我們總結了一些優秀演算法的準則,思想,比如說貪心演算法,動態規劃等思想。

演算法為何依賴於數據結構呢?為回答這個問題,舉一個通俗的例子。你在學校撿到了一張飯卡,上面有姓名,學院,班級。然後你要去將飯卡還給失主。接下來,你會找到其學院,然後找到班級,然後在班級中通過詢問同學找到失主。(姓名,學院,班級)在這裡我們認為是數據結構,因其把這些數據組織到一張卡上了。接下來,想像另一種情形,假如說飯卡上只有姓名,而學院,班級在另一張信息卡上。那麼你可能找遍全校也找不到失主。

將一些數據組織在一起,能夠為演算法提供必要的基礎信息,關聯信息,使得演算法在執行過程中能夠快速找到相關信息(比如,上面例子中的學院,班級)。


數據結構就是底層實現的意思。演算法相當於如何用抽象數據形式們解決一個問題。


不能說過時吧。比如從牛頓到麥克斯韋再到愛因斯坦。不能說誰是過時,只能說是解決問題的領域不同。程序簡單粗暴的看就是對數據的處理,所以可以從微觀來看程序是:「數據 + 操作」,中觀來看程序:「數據結構 + 演算法」。從宏觀(工程)看程序:「 對象 + 消息」。


數據結構是一門研究非數值計算的程序設計問題中計算機的(操作對象)以及它們之間的(關係)和運算的學科。


好吧,作為曾經搞演算法的,對演算法和數據結構的理解是演算法可以想像成從廣州到深圳,該走哪條路最近。而數據結構可以理解成這段路上你是走過去還是開車過去,不管用什麼方式,只要路線(演算法)對了,都能到深圳,只是所用的時間上有差別而已。對於題主說的程序嘛,沒有啥理解。


《計算機導論》里就有提到。


推薦閱讀:

上海交通大學 ACM 的 Dreadnought 隊伍怎麼這麼強?
編程是什麼?如何從零開始學習?
如何快速地在每個函數入口處加入相同的語句?
自學python,目標是web開發,請問我現在應該怎樣學習最合理?
什麼是體素渲染,如何從頭編寫一個體素渲染器?

TAG:演算法 | 編程 | 程序 | 數據結構 | 演算法與數據結構 |