1. 程式人生 > >為什麼說程式=演算法+資料結構!

為什麼說程式=演算法+資料結構!

本文將描述自己對演算法的數學表達的理解。將使用提問的方式來引導大家思考,進而對問題一步一步的分析,是一個循序漸進的過程。本文側重講講筆者的看法,沒有什麼實質的內容。但我相信,一些看法對於你從事程式設計工作來說,可能還是有幫助滴。廢話少說,看題!

1.      什麼是程式的構成?

程式碼?程式語言?編譯器?連結器?不不不 ……。我想聽到的答案是演算法+資料結構

沒有演算法的程式,只是一些程式碼的堆砌,談不上是一個優秀的軟體(即便一個簡單的微控制器流水燈的程式也應該有一個演算法,當然可能你覺的太簡單了沒有必要)。傳說!演算法是軟體的靈魂。這個還真不是傳說。你看,某某雲音樂對使用者行為進行資料分析並通過一些演算法進行個性化推薦,短時間就搶奪了多少的音訊播放終端,廣受使用者歡迎。之所以稱為,演算法是軟體的靈魂,得益於好的演算法會給軟體帶來的往往都是質的變化,效能都是呈指數倍提高滴

資料結構是什麼?不要問我,資料結構用什麼實現。因為那都不是事兒!我要告訴大家的是,如果沒有它,你的軟體系統就會變得極其不值錢。甚至於到你開發完成之後,你再也不想理他了。很多年前,我用java編寫了一個類似QQ的軟體,費了好大的勁才把開發完成,實現了低版本QQ的所有聊天功能,發文字、圖片、表情、截圖、檔案以及抖動視窗等等。還有群聊功能,推送系統、會員積分系統等,可謂應有盡有。遺憾的是,後期我並不想維護它了,原因是軟體模組實在難於管理,耦合性大。可能那是我學java的第一個專案,當時只關注語法並沒有過多面向物件的設計,壓根不知道其中的奧祕是沒有合理的資料結構將各個模組串聯起來管理。看了失敗的例子,大家都知道的一個成功的例子:Linux。Linux資料結構可謂信手拈來。最重要的思想:一切皆檔案!看,當所有模組使用“檔案”這個資料結構時,你會發現Linux所有模組近乎相同

。非要說會用資料結構的好處,數數Linux系統的好處就知道了,不必多說。

2.      演算法

a.      怎麼描述一個演算法?

通常,我們描述一個演算法使用的是虛擬碼。例如:

Insertion-sort(A[1, n])

for j = 2 to n

do

   key = A[j]

   i   = j-1

   while i > 0 and A[i] > key

   do

      A[i+1] = A[i]

      i = i-1

   A[i+1] = key

之所以選擇虛擬碼是因為簡潔,不需要做一些不必要的定義。一般採用縮排的形式來區分層次關係。值得一提的是,某些程式語言也採用縮排的方式來區分層次關係。但我覺得不如使用“{}”括號來的簡單暴力。也許計算器程式設計書寫影響不大,但是可能會影響程式設計書籍的跨頁閱讀。但是對於簡單的程式來說,採用縮排又不失簡約方便,就像用於描述演算法。

採用虛擬碼的另一個好處,在於不用關心程式的具體實現(也有可能一種演算法誕生之後,沒有對應的語言能實現)。演算法應當不依賴於某種程式語言的實現,像上面的插入排序演算法,不管你使用C、Java還是Python都可以實現。

b.     相同演算法間怎麼比較?不同演算法間又是如何比較?

上面所說,使用虛擬碼來描述的演算法不依賴於具體程式語言。那麼怎麼比較C和Java實現的插入排序演算法?又怎麼比較使用C實現的插入排序演算法和歸併排序演算法。那有怎麼比較使用C實現的歸併排序演算法和使用Java實現的插入排序演算法。

那麼怎麼比較C和Java實現的插入排序演算法?(前提是同一臺機器)

不用問阿貴都知道,Java的執行較慢些。原因是Java語言本身使用更多的系統資源用於為使用者提供更好的面向物件特性。注意這句話並不是一味將這個黑鍋扔到Java虛擬機器身上,此中緣由此處不再深究。這需要分析語言本身的特性。

怎麼比較使用C實現的插入排序演算法和歸併排序演算法?

大家說插入排序演算法的時間複雜度是多少?θ(n^2 )  。 歸併排序演算法呢?θ(log⁡n )。你說誰快?我只能說n比較大的時候,歸併排序演算法更快。這個要分析演算法自身的特性。

那有怎麼比較使用C實現的插入排序演算法和使用Java實現的歸併排序演算法?

這個問題是上兩個問題的綜合體!滿分100分。A君:你猜我得了多少分。B君:猜完了。A君:多少分?B君:你猜!首先,對於同一演算法來說,C實現和Java實現的程式,效能來說差的只是一個常量,Java執行的更慢。對於兩種演算法的時間複雜性,我們發現歸併排序演算法更快。那麼下面等式是否成立呢?

  C語言:          執行快+演算法跑得慢=快?

 Java語言:     執行慢+演算法跑得快=快?

      為此,我們高數的知識就要用的上了,無窮大+∞!當排序陣列的輸入規模很大的時候,即n →+∞,插入排序演算法的時間複雜度增長速度遠遠大於歸併排序演算法,而因語言差異造成的一丁點影響也會忽略不計。所以最後算法佔了主導作用。所以Java實現的歸併排序演算法會執行的更快!

3.      資料結構

此內容就不多講。因為我從教材學到的這方面東西也並不多。即使修過“資料結構”相關課程,我也不認為課本的知識能讓大家在資料結構的應用上融會貫通,即使做到有所感悟,我認為這也是難事。原因是目前大家都偏向於關注演算法,而對於軟體架構的設計,模組的耦合分析,程式的可擴充套件性等這方面內容缺乏深入研究。在這裡我就扔下這塊磚(曾經有個體會,先不說,今天寫累了)。希望有大牛大神來為我解答一下資料結構對程式的影響。

 ————————————————————————————————————————————————————————————————————————————

演算法比較厲害的~去做大資料分析,資料探勘,數值分析……!

資料結構比較厲害的~去做軟體架構師、作業系統設計……!

以後,別問人家問你什麼職業。別回答成敲程式碼的,也不要簡單回答軟體工程師。這樣顯得自己不夠專業。你一定要說清楚你是曾經側重或者精於搞演算法或者資料結構的軟體系統建築師(還是碼農~)。