資料結構是幹什麼的?為什麼它總是跟演算法扯上關係?概括的說,要用計算機求解實際問題需要做兩件事:第一,
把實際問題用計算語言描述
;第二,
用計算機語言求解這個問題
。第一件事情是資料結構幹的,第二件事情就是演算法幹的。有乙個著名的公式:
程式 = 資料結構 + 演算法
非常形象的描述了它們之間的關係。
通常,我們都是介紹一種資料結構,然後介紹對應於這種結構的演算法。
1.先看資料結構。舉乙個例子:學生的資訊。有人可能覺得,學生的資訊儲存很簡單啊,把學號、姓名、年齡、性別等等做成乙個結構體,然後做成乙個陣列不就行了麼?但是你是否考慮過一下問題:第一,萬一有人退學、插班,條換專業,那麼這個陣列中元素的順序如何管理?第二,學校有幾萬人,陣列要求連續存放,你能保證有這麼大的連續儲存空間麼?也許你為這個看似複雜的問題想破了腦袋,都沒有想出來怎麼解決,但是如果你學過資料結構,就能迎刃而解了,用乙個鍊錶就能實現:每個乙個學生中都有乙個指標,指向它的下乙個元素,依次類推。這樣既不需要連續的空間,也可以靈活的進行插入、刪除等操作。
可見,資料結構是對現實中問題的高度抽象。那麼世界上的問題千奇百怪,抽象出來的資料結構有多少種呢?答案只有3中:線性結構、樹、圖。通常,如果是把資料放在一起,而不考慮它們之間的關係的話,使用線性結構就可以了,比如我們的學生資訊;而對於那些互相連續的資料,也許就需要樹來表示了,比如:乙個學校分成了很多學院、每個學院又分成了多個專業,每個專業又分成了幾個班;最後,如果前兩個種結構都沒法解決,我們就要用到圖了。比如有a、b、c、d、e、f、g七個地方,它們之間有的相通,有的不相通,我想從乙個地方到達另乙個地方,走那條路最近。
2.再看演算法:有的演算法比較簡單,比如鍊錶的插入,刪除之類的,有的演算法卻異常複雜,比如那個求最短路徑的問題(如果我沒有記錯,維特比演算法就是解決這類問題的方法之一,這個演算法在卷積碼解碼、隱馬爾科夫鏈等等領域有重要應用。這裡就不展開說了)。很多人寫**也經常寫演算法,那麼到底什麼是演算法呢?就是解決問題的方法步驟,它必須包含以下要求:
1.有輸入。它能夠處理你讓它處理的資料。
2.有輸出。它能夠訴你計算的結果。
3.有窮性。這裡的有窮不是數學上的有窮,每個演算法總是針對於特定應用的。如果對於這個應用來說,演算法太慢了也不行。比如,對乙個實時監控系統,我們希望檢測畫面內是否有運動目標。如果你的演算法過了一天才能計算出結果,那也不行。
4.每一步都是明確的。
5.每一步可實現。
那麼如何評價演算法呢?演算法是在電腦上算的,所以演算法好不好得電腦說了算。那無非就是兩種:算的快不快,占用的記憶體多不多。後一種很好理解,前一種就要費點腦筋了。我們不能簡單把程式搬到電腦上執行來比較快慢,因為各個電腦的差別是很明顯的:配置不同,新舊不同等等。我們通常採用數學的方法來估計執行演算法大約需要多少步驟。當你的演算法與問題規模的增長速度相同時,你的演算法複雜度就稱為o(n)。比如如果你的演算法中主要的工作是乙個for迴圈執行了n次;如果你的演算法中是兩個巢狀的for迴圈,那麼就是o(n^2)。這裡使用的是高等數學中無窮小的階數的概念,也不多說了。
其實,完整的評價乙個演算法考慮的因素很多,有的演算法很精細,但是執行速度慢,有的演算法計算效果一般,但是執行速度很快;還有的演算法,雖然又快又好,但是健壯性很差;甚至有些演算法很好,但是由於理論過於高深,在很長是一段時間內都沒有被大家接受。所以,咱們還是不要貿然評價別人的演算法了吧,時間會證明一切。
Swift資料結構引言
了解不同資料結構的優劣,對我們今後的程式設計工作將十分有幫助 至於有什麼幫助,可以自行,也可以翻書 作為這個系列的第一篇部落格,我們將重新複習一下swift中幾種內建的基本資料結構。通常情況下,從元素之間的關係上來講,我們習慣上將資料結構分為兩種基本型別 順序儲存資料結構和連式儲存資料結構。順序儲存...
資料結構和演算法
判斷乙個演算法的效率時,函式中的常數和其它次要項常常可以忽略,而更應該關注主項 最高項 的階數。演算法時間複雜度的定義 在進行演算法分析時,語句中的執行次數t n 是關於問題規模n的函式,進而分析t n 隨n的變化情況並確定t n 的數量級。演算法的時間複雜度,也就是演算法的時間量度,記作 t n ...
資料結構和演算法
程式是什麼?好多書上都寫著 程式 資料結構 演算法。可是怎麼去理解呢?好多程式設計人員對資料結構和演算法說不上熟悉,因為在他們所從事的工作中很少用到這些知識點。但並不表示他們不重要。還有一些人是這樣的想法 大公司才會注重這些知識點,小公司可能就不注重了。寫這篇文章之前我也是持這種想法的。但是,此時此...