數據結構和算法


前言

2016年又是一個全新的開始,每到一年的這個時候,總是頗有感慨。想對過去的一年做一些總結,但又覺得經歷和精力總是不夠。

俗話說,一年之計在於春,當然,新的一年,也總是計划着N多事情,想做什么事情?做到什么程度?哪些一定要做好?哪些一定要完成?每一年都會列出來,到最后卻發現,在這走過的一年里,有時候完全沒有按照原定的路線執行。所以,針對於此,我便不再對自己進行規划,當然並不代表沒有目標。我把時間分的更加粗顆粒化,不再細化到沒有余地,因為生活本來就充滿了變化。人不能做到按照原定的計划一步一步的執行,我必須承認這一點。不是有句話嗎,計划趕不上變化。

在這里,我要說的是,在這一年里,我會嘗試着回顧一些基礎的知識,比如數據結構,比如算法設計與分析。因為,自從大學畢業到現在也有2年了,數據結構和算法里面的N多概念已經忘記的快沒有印象了。但我又不得不說的是,這些最基礎的,對於一個程序員的提升也是最必要的。這大概就是程序員和工程師的區別吧。

我要聲明的是,我在今后的日子里,會接二連三的更新一些關於數據結構和算法的知識。但時間會存在不確定性,可能會每隔兩天就出一篇文章,可能是一個星期,當然也可能是一個月,這些東西是我不能控制的。所以,還請廣大博友理解!

廢話少說,時間不等人,直入主題!

數據結構這門課程不太好學,在大學的時候老師講的都聽明白了,但是現在依舊忘記了很多。如果你想讓自己的編程能力有質的飛躍,不再停留於調用現成的東西而是追求更完美的實現,那么這是你大學畢業后的必修課!

什么是數據結構

概念

官方定義:

數據結構是一門研究非數值計算的程序設計問題中的操作對象,以及它們之間的關系和操作等相關問題的學科。

我的理解:

程序設計 = 數據結構 + 算法

數據結構,顧名思義,就是數據之間的結構關系,或者理解成數據元素相互之間存在的一種或多種特定關系的集合。當然這些概念都是大學喜歡考的,我們沒必要糾結於這個概念,有自己恰當的、並且可以為他人所接受的解釋就可以。

數據結構中結構的概念

數據結構中的結構,也就是我們研究的主體對象。數據結構中我們很少研究數據,因為數據在內存中的表現形式對於我們都是一樣的,也就是二進制。傳統上,我們把數據結構分為邏輯結構物理結構

邏輯結構

指反映數據元素之間的邏輯關系的數據結構,其中的邏輯關系是指數據元素之間的前后關系,而與他們在計算機中的存儲位置無關。邏輯結構分為以下四類:

1.集合結構

集合結構中的數據元素同屬於一個集合,他們之間是並列的關系,除此之外沒有其他關系。如下圖,可以很好的表示集合結構中的元素之間的關系:

http://blog.fishc.com/wp-content/uploads/2012/08/%E9%9B%86%E5%90%88%E7%BB%93%E6%9E%84.jpg

2.線性結構

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

http://blog.fishc.com/wp-content/uploads/2012/08/%E7%BA%BF%E6%80%A7%E7%BB%93%E6%9E%84.jpg

3.樹形結構

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

http://blog.fishc.com/wp-content/uploads/2012/08/%E6%A0%91%E5%BD%A2%E7%BB%93%E6%9E%84.jpg

4.圖形結構

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

http://blog.fishc.com/wp-content/uploads/2012/08/%E5%9B%BE%E5%BD%A2%E7%BB%93%E6%9E%84.jpg

物理結構

物理結構又叫存儲結構,指數據的邏輯結構在計算機存儲空間的存放形式。通俗的講,物理結構研究的是數據在存儲器中存放的形式。 存儲器主要針對於內存而言,像硬盤、軟盤、光盤等外部存儲器的數據組織通常用文件結構來描述。

數據在內存中的存儲結構,也就是物理結構,分為兩種:順序存儲結構鏈式存儲結構

順序存儲結構

順序存儲結構:是把數據元素存放在地址連續的存儲單元里,其數據間的邏輯關系和物理關系是一致的。數組就是順序存儲結構的典型代表。其在內存中的存儲形式類似於下圖:

鏈式存儲結構

鏈式存儲結構:是把數據元素存放在內存中的任意存儲單元里,也就是可以把數據存放在內存的各個位置。這些數據在內存中的地址可以是連續的,也可以是不連續的。

和順序存儲結構不同的是,鏈式存儲結構的數據元素之間是通過指針來連接的,我們可以通使用指針來找到某個數據元素的位置,然后對這個數據元素進行一些操作。如下圖,可以幫助我們理解鏈式存儲結構:

順序存儲結構和鏈式存儲結構的區別

打個比方說一下順序存儲結構和鏈式存儲結構的區別:
比如去銀行取錢,順序存儲結構就相當於,所有的客戶按照先來后到的順序有序的的坐在大廳的椅子上(注意:是有順序的坐着哦)。
而鏈式存儲結構相當於,所有的客戶只要一到銀行,大堂經理就給他們每人一個號碼,然后他們可以隨便坐在哪個椅子上(隨便坐,不需要按照什么順序坐),只需要等待工作人員廣播叫號即可。
而每個客戶手里的號碼就相當於指針,當前的指針指向下一個存儲空間,這樣,所有不連續的空間就可以被有順序的按照線性連接在一起了。

算法

說到數據結構,必須要一並帶上算法,在筆者看來,不談算法的數據結構只是你理解了概念,只能夠出去裝X而已。即談數據結構又談算法才能夠真正裝爺。只可惜,以我現在腦海里殘留的一點概念,我出去只能夠裝X。廢話少說,直接行干貨!

算法的概念

是指解題方案的准確而完整的描述,是一系列解決問題的清晰指令,算法代表着用系統的方法描述解決問題的策略機制。

以上是我在百度百科找到的解釋,在我看來,算法就是求解一個問題所需要的步驟所形成的解決方法,每一步包括一個或者多個操作。無論是現實生活中還是計算機中,解決同一個問題的方法可能有很多種,在這N多種算法中,肯定存在一個執行效率最快的方法,那么這個方法就是最優算法

算法的特性

算法具有五個基本特征:輸入、輸出、有窮性、確定性和可行性

輸入

一個算法具有零個或者多個輸出。以刻畫運算對象的初始情況,所謂0個輸入是指算法本身定出了初始條件。后面一句話翻譯過來就是,如果一個算法本身給出了初始條件,那么可以沒有輸出。比如,打印一句話:NSLog(@"你最牛逼!");

輸出

算法至少有一個輸出。也就是說,算法一定要有輸出。輸出的形式可以是打印,也可以使返回一個值或者多個值等。也可以是顯示某些提示。

 

有窮性

算法的執行步驟是有限的,算法的執行時間也是有限的。

 

確定性

算法的每個步驟都有確定的含義,不會出現二義性。

可行性

算法是可用的,也就是能夠解決當前問題。
當然,回過頭來一看,這五個特性都是廢話,並且依稀記得大學老師都教過。所以,我們不用浪費腦力在這些不必要的概念上,因為大學早已離我遠去,考試什么的跟我也沒有一毛錢關系,只要知道這么回事就好。

算法的設計要求

要設計一個好的算法,需要考慮以下4個特性(其實多半是廢話)。

正確性

廢話,誰會設計一個不能夠解決問題的方法。

可讀性

指算法無論是從設計思路上,還是從注釋方面,都要能夠保證算法是可讀的,也就是可以被其他人員能夠讀懂的。其實也是廢話,這是一個優秀的程序員必備的。

健壯性

通俗的講,一個好的算法應該具有捕獲異常/處理異常的能力。另外,對於測試人員的壓力測試、邊界值測試等刁難的測試手段,算法應該能夠輕松的扛過去。

時間效率高和存儲量低

這其實是兩個概念,時間效率就是指的時間復雜度,存儲量就是指的空間復雜度。翻譯過來就是一個好的算法應該考慮時間復雜度和空間復雜度。而往往時間復雜度和空間復雜度是相互彌補的。也就是從某些角度,我們可以了通過犧牲算法運算時間的方式來減少對內存的占用,反之亦然。對於時間復雜度和空間復雜度這兩個概念,大家不用泰國迷惑,我會拿出來一篇文章專門講解,請大家稍安勿躁,持續關注。

PS:本篇文章是一個簡單的開始,里面涉及了一些概念大家不必太過計較,以后的文章中會逐步的對這些概念進行展開講解。請大家不要急躁,不要氣餒!
 
圖片來源參考自:魚C工作室。感謝魚C工作室貢獻出了這么好的圖片。
如非特別說明,筆者所有文章都是原創文章。如果您喜歡這篇文章,轉載請注明出處。如果您對數據結構感興趣,請關注我,后續會更新大量晶品文章供大家參考!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM