基本概念以及術語
數據
數據:信息的載體,是描述客觀事物屬性的數、字符及所有能輸入到計算機中並被計算機程序識別和處理的符號的集合。例如在生活中,我們的身份信息、看到的圖片、聽到的音樂都可以作為數據來進行輸入和處理。
數據對象:具有相同性質的數據元素的集合,是數據的一個子集。例如所有人的身份信息可以作為一個數據對象。
數據元素:數據的基本單位,通常作為一個整體進行考慮和處理。例如每一個人的身份信息可能就是一個數據元素。
數據項:構成數據元素的不可分割的最小單位。在身份信息中,有姓名、有身份證編號,這樣的信息就是數據元素中的數據項。
例如,上圖是具有人物和螃蟹的數據的集合。其中所有的人物就是一個數據對象,它是具有相同性質的數據元素的集合;每一個人物都是一個數據元素,可能在該人物當中,帽子的顏色、書包的顏色都可以作為數據項。
數據類型:是一組值的集合和定義在該集合上的操作的總和。其中有原子類型,原子就是不可再分割的意思,它是原子類型值的集合和定義在該集合上的操作。例如在 C 語言中的 int、char、float 等都是原子類型。除了原子類型,還有結構類型,它是結構的集合和定義在集合上的操作。結構就是多個原子類型值的組合,其中有 list、map、set 等。最后還有抽象數據類型,它是數據模型以及定義在該數據模型上的操作,可以用一個三元組來表示,分別是數據對象、數據關系和相關的操作。對於抽象數據類型,只考慮它的邏輯特性,具體的內部實現是不考慮的。例如在生活中所有的人、汽車都可以把它抽象出來作為一種抽象數據類型。
結構
這是一張成績單,如果把這張成績單叫做一個數據對象的話,那么每一個人的姓名可以稱作為一個數據項,而每一個人所有的信息是一個數據元素。這張表還有類似於小明排在小紅前面這樣的關系,這樣的關系就是所說的結構。
結構:數據不是孤立存在的,它們存在着某種關系,這種相互的關系我們叫做結構。
這樣就有了數據結構的一個概念。數據結構是相互之間存在一種或多種特定關系的數據元素的集合。
數據結構的三要素
數據結構有三個要素:邏輯結構、物理結構、數據的運算
邏輯結構
邏輯結構是指數據元素之間的邏輯關系,它更貼近於現實,即從邏輯關系上來描述數據。它是獨立於計算機的,與計算機內部如何存儲是無關的。
在邏輯結構中,具體分為四種:線性結構、集合、樹形結構、圖狀結構。其中,把集合、樹形結構、圖狀結構統稱為非線性結構。
線性結構
在生活中有許多線性結構的例子,比如排隊買票時,排的隊伍就是一個線性結構。在對成績進行從小到大排序,它也是一個線性的結構。
集合
集合是指除了所有的元素均在一個集合之內,之外再無其他的關系。在數學中,所有整數就是一個集合,所有的小數也是一個集合。
樹形結構
樹形結構是指一對多的關系。比如說狗是一類的總稱,狗中又有柯基、哈士奇等具體的種類,這樣一個種類的分支關系,它們就是一個樹形結構。
圖狀結構
圖狀結構也叫做網狀結構,它是多對多的關系。比如城市的交通網絡,每一個城市都連接這其他的許多城市。
存儲結構
存儲結構是指數據結構在計算機內的表示,也稱為物理結構。它既包括數據元素本身的表示,也包括數據元素之間關系的表示。
存儲結構也分為四種:順序存儲、鏈式存儲、索引存儲、散列存儲。
順序存儲
數據在內存當中,會把它存放在一個一個的存儲單元之中,而順序存儲的意思是指在邏輯上相鄰的元素在物理存儲上也讓它相鄰。
例如,a、b、c、d、e 五個元素在邏輯上是相鄰的,那么把它存放到存儲單元之中也讓它相鄰。
順序存儲元素之間的關系是通過物理位置相鄰來體現的,其最大的好處就是可以實現隨機存儲,在知道第一個單元的位置時,通過簡單運算,根據它相鄰的特性也就知道其后所有元素的數據位置
鏈式存儲
鏈式存儲是指在邏輯上相鄰的元素,在物理存儲位置上是不相鄰的。鏈式存儲通過名字來看,它有一個鏈接的含義,它在具體的實現上也是利用這樣一個具體操作的。
存放數據元素 a 的位置同時后面也存放了下一個元素的地址,通過這個地址來體現元素之間的關系達到一個指針的效果。
在鏈式存儲當中,每一個數據元素存放的物理單元位置是不確定的,它們的距離可能很遠也可能很近,無法通過順序存儲那樣的手段來找到下一個元素的位置。但是在鏈式存儲中,是通過指針來表示相鄰元素的關系的。所以在存取手段上,要通過指針來找到下一個元素的位置。所以在鏈式存儲中只能實現順序存儲而無法實現隨機存儲。
例如在圖 1-4 中 a、b、c 三個元素在邏輯上是相連的,假設它是順序存取的,那么想要找到 c 這個元素,就可以通過鎖定 addr2
找到了,因為它在邏輯單元上是連續存放的。而在圖 1-5 中,首先通過存放 a 元素的存儲單元知道下一個存儲單元的地址是 addr7
,找到了 b 的位置之后,再通過 b 存儲單元中 c 的指針,也就是 addr9
找到了 c,只有這樣以此的查找才能找到 c 的位置。
索引存儲
索引存儲在內存中不僅僅要存放每一個數據元素,還要建立一張索引表。在索引表中有一個個索引項,每一個索引項都存放兩個信息,一個是關鍵字,另一個是該關鍵字查找數據對應的地址。
例如,想要鎖定 c 在存儲單元中的位置,通過關鍵字 n 找到了 c 對應的存儲單元地址是 addr8
。通過這樣一個個索引項可以非常快速的找到對應存儲數據的地址。
但是,索引存儲有一個缺點,就是既要存放數據元素,又要存放索引表,在存放索引表的時候會消耗內存資源。
散列存儲
散列存儲也稱為哈希存儲,它是通過關鍵字的相應函數運算直接求得對應數據元素的地址
例如,通過 f(n) 的這個函數運算直接求得數據元素 c 的存放地址 addr8
。它的查找速度也是非常快的。
數據的運算
數據的運算包括運算的定義和實現方式,運算的定義針對邏輯結構,運算的實現針對存儲結構。
例如:現在有這樣一個簡單的邏輯結構,其中 C 是 A 的后繼節點,B 是 C 的后繼節點,為了理解對應關系,設計了這樣一個存儲結構,數據元素 A 存放在了地址單元當中的 addr0
,數據元素 B 存放在了 addr1
,數據元素 C 存放在了 addr2
。現在要實現的運算是找到 A 的下一個節點。可以發現,在這個例子中,A 的下一個節點是有所不同的
根據上述的概念,運算的定義針對邏輯結構,找到的 A 的下一個節點是 C,運算的實現針對存儲結構,找到的 A 的下一個節點是 B,所以說不同的結構,數據的運算也是不同的。
總結
重點:數據結構的三要素