前言
2016年又是一個全新的開始,每到一年的這個時候,總是頗有感慨。想對過去的一年做一些總結,但又覺得經歷和精力總是不夠。
俗話說,一年之計在於春,當然,新的一年,也總是計划着N多事情,想做什么事情?做到什么程度?哪些一定要做好?哪些一定要完成?每一年都會列出來,到最后卻發現,在這走過的一年里,有時候完全沒有按照原定的路線執行。所以,針對於此,我便不再對自己進行規划,當然並不代表沒有目標。我把時間分的更加粗顆粒化,不再細化到沒有余地,因為生活本來就充滿了變化。人不能做到按照原定的計划一步一步的執行,我必須承認這一點。不是有句話嗎,計划趕不上變化。
在這里,我要說的是,在這一年里,我會嘗試着回顧一些基礎的知識,比如數據結構,比如算法設計與分析。因為,自從大學畢業到現在也有2年了,數據結構和算法里面的N多概念已經忘記的快沒有印象了。但我又不得不說的是,這些最基礎的,對於一個程序員的提升也是最必要的。這大概就是程序員和工程師的區別吧。
我要聲明的是,我在今后的日子里,會接二連三的更新一些關於數據結構和算法的知識。但時間會存在不確定性,可能會每隔兩天就出一篇文章,可能是一個星期,當然也可能是一個月,這些東西是我不能控制的。所以,還請廣大博友理解!
廢話少說,時間不等人,直入主題!
數據結構這門課程不太好學,在大學的時候老師講的都聽明白了,但是現在依舊忘記了很多。如果你想讓自己的編程能力有質的飛躍,不再停留於調用現成的東西而是追求更完美的實現,那么這是你大學畢業后的必修課!
什么是數據結構
概念
官方定義:
數據結構是一門研究非數值計算的程序設計問題中的操作對象,以及它們之間的關系和操作等相關問題的學科。
我的理解:
程序設計 = 數據結構 + 算法
數據結構,顧名思義,就是數據之間的結構關系,或者理解成數據元素相互之間存在的一種或多種特定關系的集合。當然這些概念都是大學喜歡考的,我們沒必要糾結於這個概念,有自己恰當的、並且可以為他人所接受的解釋就可以。
數據結構中結構的概念
數據結構中的結構,也就是我們研究的主體對象。數據結構中我們很少研究數據,因為數據在內存中的表現形式對於我們都是一樣的,也就是二進制。傳統上,我們把數據結構分為邏輯結構和物理結構。
邏輯結構
指反映數據元素之間的邏輯關系的數據結構,其中的邏輯關系是指數據元素之間的前后關系,而與他們在計算機中的存儲位置無關。邏輯結構分為以下四類:
1.集合結構
集合結構中的數據元素同屬於一個集合,他們之間是並列的關系,除此之外沒有其他關系。如下圖,可以很好的表示集合結構中的元素之間的關系:

2.線性結構
線性結構中的元素存在一對一的相互關系。如下圖,可以很好的表示線性結構中的元素之間的關系:

3.樹形結構
樹形結構中的元素存在一對多的相互關系。如下圖,可以很好的表示樹形結構中的元素之間的關系:

4.圖形結構
圖形結構中的元素存在多對多的相互關系。如下圖,可以很好的表示圖形結構中的元素之間的關系:

物理結構
物理結構又叫存儲結構,指數據的邏輯結構在計算機存儲空間的存放形式。通俗的講,物理結構研究的是數據在存儲器中存放的形式。 存儲器主要針對於內存而言,像硬盤、軟盤、光盤等外部存儲器的數據組織通常用文件結構來描述。
數據在內存中的存儲結構,也就是物理結構,分為兩種:順序存儲結構和鏈式存儲結構。
順序存儲結構
順序存儲結構:是把數據元素存放在地址連續的存儲單元里,其數據間的邏輯關系和物理關系是一致的。數組就是順序存儲結構的典型代表。其在內存中的存儲形式類似於下圖:
鏈式存儲結構
鏈式存儲結構:是把數據元素存放在內存中的任意存儲單元里,也就是可以把數據存放在內存的各個位置。這些數據在內存中的地址可以是連續的,也可以是不連續的。
和順序存儲結構不同的是,鏈式存儲結構的數據元素之間是通過指針來連接的,我們可以通使用指針來找到某個數據元素的位置,然后對這個數據元素進行一些操作。如下圖,可以幫助我們理解鏈式存儲結構:

順序存儲結構和鏈式存儲結構的區別
算法
說到數據結構,必須要一並帶上算法,在筆者看來,不談算法的數據結構只是你理解了概念,只能夠出去裝X而已。即談數據結構又談算法才能夠真正裝爺。只可惜,以我現在腦海里殘留的一點概念,我出去只能夠裝X。廢話少說,直接行干貨!
算法的概念
是指解題方案的准確而完整的描述,是一系列解決問題的清晰指令,算法代表着用系統的方法描述解決問題的策略機制。
以上是我在百度百科找到的解釋,在我看來,算法就是求解一個問題所需要的步驟所形成的解決方法,每一步包括一個或者多個操作。無論是現實生活中還是計算機中,解決同一個問題的方法可能有很多種,在這N多種算法中,肯定存在一個執行效率最快的方法,那么這個方法就是最優算法。
算法的特性
算法具有五個基本特征:輸入、輸出、有窮性、確定性和可行性。
輸入
一個算法具有零個或者多個輸出。以刻畫運算對象的初始情況,所謂0個輸入是指算法本身定出了初始條件。后面一句話翻譯過來就是,如果一個算法本身給出了初始條件,那么可以沒有輸出。比如,打印一句話:NSLog(@"你最牛逼!");
輸出
算法至少有一個輸出。也就是說,算法一定要有輸出。輸出的形式可以是打印,也可以使返回一個值或者多個值等。也可以是顯示某些提示。
有窮性
算法的執行步驟是有限的,算法的執行時間也是有限的。
確定性
可行性
算法的設計要求
要設計一個好的算法,需要考慮以下4個特性(其實多半是廢話)。
正確性
廢話,誰會設計一個不能夠解決問題的方法。
可讀性
指算法無論是從設計思路上,還是從注釋方面,都要能夠保證算法是可讀的,也就是可以被其他人員能夠讀懂的。其實也是廢話,這是一個優秀的程序員必備的。
健壯性
通俗的講,一個好的算法應該具有捕獲異常/處理異常的能力。另外,對於測試人員的壓力測試、邊界值測試等刁難的測試手段,算法應該能夠輕松的扛過去。
時間效率高和存儲量低
這其實是兩個概念,時間效率就是指的時間復雜度,存儲量就是指的空間復雜度。翻譯過來就是一個好的算法應該考慮時間復雜度和空間復雜度。而往往時間復雜度和空間復雜度是相互彌補的。也就是從某些角度,我們可以了通過犧牲算法運算時間的方式來減少對內存的占用,反之亦然。對於時間復雜度和空間復雜度這兩個概念,大家不用泰國迷惑,我會拿出來一篇文章專門講解,請大家稍安勿躁,持續關注。

