瑞士的計算機專家在1976年出版了一本書,書名為
《算法+數(shù)據(jù)結(jié)構(gòu) = 程序設計》,它正說明了數(shù)據(jù)結(jié)構(gòu)在程序設計中的作用。程序設計的實質(zhì)即為計算機處理問題編制一組"指令",首先需要解決兩個問題:即算法和數(shù)據(jù)結(jié)構(gòu)。算法即處理問題的策略,而數(shù)據(jù)結(jié)構(gòu)即為問題的數(shù)學模型。
很多數(shù)值計算問題的數(shù)學模型通??捎靡唤M線性或非線性的代數(shù)方程組或微分方程組來描述,而大量非數(shù)值計算問題的數(shù)學模型正是本門課程要討論的數(shù)據(jù)結(jié)構(gòu)。
例一、求 n 個整數(shù)中的最大值。這似乎不成問題,但如果這些整數(shù)的值有可能達到10
12,那么對32位的計算機來說,就存在一個如何表示的問題。
例二、交叉路口的紅綠燈管理。如今十字路口橫豎兩個方向都有三個紅綠燈,分別控制左拐、直行和右拐,那么如何控制這些紅綠燈既使交通不堵塞,又使流量最大呢?若要編制程序解決問題,首先要解決一個如何表示的問題。
例三、煤氣管道的鋪設問題。如右圖需為城市的各小區(qū)之間鋪設煤氣管道,對 n 個小區(qū)只需鋪設 n-1 條管線,由于地理環(huán)境不同等因素使各條管線所需投資不同(如圖上所標識),如何使投資成本最低?這是一個討論圖的生成樹的問題。
以上所舉例子中的數(shù)學模型正是數(shù)據(jù)結(jié)構(gòu)要討論的問題。因此,簡單地說,
數(shù)據(jù)結(jié)構(gòu)是一門討論"描述現(xiàn)實世界實體的數(shù)學模型(非數(shù)值計算)及其上的操作在計算機中如何表示和實現(xiàn)"的學科。很多問題求解最后都轉(zhuǎn)化為求解數(shù)學方程或數(shù)學方程組,即使是不需要用計算機求解的簡單問題也需要一個數(shù)學模型來描述,例如,大家都熟悉的"雞兔同籠"問題,可轉(zhuǎn)化為對"二元一次方程組"進行求解。又如在房屋設計或橋梁設計中的結(jié)構(gòu)應力分析計算可化解為線性代數(shù)方程組求解的問題,再如,天天看到的天氣預報,它的數(shù)學模型是一個環(huán)流模式方程。
而當計算機進入非數(shù)值計算領域、特別是用在管理上的時候,計算機的操作對象之間的關系就無法用數(shù)學方程加以描述了。
第二節(jié) 與數(shù)據(jù)結(jié)構(gòu)相關的基本概念
·數(shù)據(jù)
是所有能被輸入到計算機中,且能被計算機處理的符號(數(shù)字、字符等)的集合,它是計算機操作對象的總稱。
是計算機處理的信息的某種特定的符號表示形式。
數(shù)據(jù)是個集合,如果用集合的表示方法來寫的話,就是
數(shù)據(jù)={x|x是計算機操作的對象}
·數(shù)據(jù)元素
是數(shù)據(jù)(集合)中的一個"個體",在計算機中通常作為一個整體進行考慮和處理,是數(shù)據(jù)結(jié)構(gòu)中討論的"基本單位"。
有兩類數(shù)據(jù)元素:一類是不可分割的"原子"型數(shù)據(jù)元素,如:整數(shù)"5",字符 "N" 等;另一類是由多個款項構(gòu)成的數(shù)據(jù)元素,其中每個款項被稱為一個"數(shù)據(jù)項"。例如描述一個學生的信息的數(shù)據(jù)元素可由下列6個數(shù)據(jù)項組成。其中的出身日期又可以由三個數(shù)據(jù)項:"年"、"月"和"日"組成,則稱"出身日期"為"組合項",而其它不可分割的數(shù)據(jù)項為"原子項"。
數(shù)據(jù)項是數(shù)據(jù)結(jié)構(gòu)中討論的"最小單位"。
它包括所有的數(shù)字和字符。圖形和聲音等信息最后也都可以轉(zhuǎn)化為"字符"進行處理。而這些字符和數(shù)字是客觀信息的一種描述。如"3000",可以表示某個城市的3000萬人口,也可表示3000元/平方的房價。
·關鍵字
指的是能識別一個或多個數(shù)據(jù)元素的數(shù)據(jù)項。若能起唯一識別作用,則稱之為 "主" 關鍵字,否則稱之為 "次" 關鍵字。
·數(shù)據(jù)對象
是具有相同特性的數(shù)據(jù)元素的集合,如:整數(shù)、實數(shù)等。它是數(shù)據(jù)的一個子集。
若在特性相同的數(shù)據(jù)元素集合中的數(shù)據(jù)元素之間存在一種或多種特定的關系,則稱該數(shù)據(jù)元素的集合為"數(shù)據(jù)結(jié)構(gòu)",換句話說,數(shù)據(jù)結(jié)構(gòu)是帶"結(jié)構(gòu)"的數(shù)據(jù)元素的集合。"結(jié)構(gòu)"即指數(shù)據(jù)元素之間存在的關系。
在客觀世界中存在的各個事物之間存在著千絲萬縷的"聯(lián)系",因此在計算機對它進行處理的時候必然也要將這種關系描述進去,如數(shù)學方程就是變量之間的約束關系的一種描述,在此稱這種關系為結(jié)構(gòu),因此,數(shù)據(jù)結(jié)構(gòu)是一堆數(shù)據(jù)元素和這些數(shù)據(jù)元素之間的關系的總和。
<x,y> 意為 x 和 y 之間存在 "x領先于y" 的次序關系。
假設以三個4位的十進制數(shù)表示一個含12位十進制數(shù)的"長整數(shù)",則可用如下描述的數(shù)學模型表示:它是一個含三個數(shù)據(jù)元素{a1,a2,a3}的集合,且在集合上存在下列次序關系:{<a1,a2>,<a2,a3>}。
例如,長整數(shù) "321465879345" 可用 a1=3214,a2=4658 和 a3=9345 的集合表示,且三者之間的次序關系必須是,a1 表示最高4位,a3 表示最低的4位,a2 則是中間4位。
又如,可以用下述數(shù)據(jù)結(jié)構(gòu)來描述2行3列的矩陣:它是一個含6個數(shù)據(jù)元素{a1,a2,a3,a4,a5,a6} 的集合,且集合上存在"行關系"和"列關系"兩個次序關系,其中行關系為{<a1,a2>,<a2,a3>,<a4,a5>,<a5,a6>},列關系為
{<a1,a4>,<a2,a5>,<a3,a6>}。
再如,描述1行6列的矩陣的數(shù)據(jù)結(jié)構(gòu)的定義為:它是一個含6個數(shù)據(jù)元素{a1,a2,a3,a4,a5,a6}的集合,且集合上只存在一個次序關系,即:
{<a1,a2>,<a2,a3>,<a3,a4>,<a4,a5>,<a5,a6>}。
從這兩個例子可見,即使數(shù)據(jù)元素集合相同,而其上的關系不同,則構(gòu)成的數(shù)據(jù)結(jié)構(gòu)不同。
1.2.2 數(shù)據(jù)結(jié)構(gòu)
數(shù)據(jù)結(jié)構(gòu)的形式定義為:
數(shù)據(jù)結(jié)構(gòu)是一個二元組
Data_Structures = ( D,S )
其中:D是數(shù)據(jù)元素的有限集,
S是D上關系的有限集。
按關系或結(jié)構(gòu)分,數(shù)據(jù)結(jié)構(gòu)可歸結(jié)為以下四類:線性結(jié)構(gòu)、樹形結(jié)構(gòu)、圖狀結(jié)構(gòu)和集合結(jié)構(gòu)。
數(shù)據(jù)結(jié)構(gòu)應該包括數(shù)據(jù)的"邏輯結(jié)構(gòu)"和數(shù)據(jù)的"物理結(jié)構(gòu)"兩個方面(層次)。
數(shù)據(jù)邏輯結(jié)構(gòu)是對數(shù)據(jù)元素之間存在的邏輯關系的描述,它可以用一個數(shù)據(jù)元素的集合和定義在此集合上的若干關系表示。
數(shù)據(jù)物理結(jié)構(gòu)是數(shù)據(jù)邏輯結(jié)構(gòu)在計算機中的表示和實現(xiàn),故又稱數(shù)據(jù)"存儲結(jié)構(gòu)"。
上述對數(shù)據(jù)結(jié)構(gòu)的定義還只是數(shù)學上的抽象概念,并沒有涉及計算機,完整的數(shù)據(jù)結(jié)構(gòu)定義還應該包括它在計算機中的表示-即數(shù)據(jù)的存儲結(jié)構(gòu)。
存儲結(jié)構(gòu)是邏輯結(jié)構(gòu)在存儲器中的映象,它包含數(shù)據(jù)元素的映象和關系的映象。
在計算機中表示信息的最小單位是"位(bit)",任何一個數(shù)據(jù)元素都可以用一個 "位串" 表示,如,數(shù)值"321" 可用位串 101000001 表示,字母"A"可用位串 001000001 表示。當數(shù)據(jù)元素由多個數(shù)據(jù)項構(gòu)成時,每個數(shù)據(jù)項即為表示數(shù)據(jù)元素的位串中的一個"子位串"。
由于邏輯結(jié)構(gòu)包括數(shù)據(jù)元素集合和關系的集合,則討論存儲結(jié)構(gòu)只需要分別討論數(shù)據(jù)元素和關系在計算機中如何表示即可。
關系有兩種表示方法:
其一為"
順序映象"。以 "y 相對于 x 的存儲位置" 表示 "y 是x的后繼",例如,令 y 的存儲位置和 x 的存儲位置之間相差一個預設常量C,C本身是個隱含值,由此得到的數(shù)據(jù)存儲結(jié)構(gòu)為"
順序存儲結(jié)構(gòu)"。
其二為"鏈式映象"。以和x綁定在一起的附加信息(指針)表示后繼關系,這個指針即為 y 的存儲地址,由此得到的數(shù)據(jù)存儲結(jié)構(gòu)為"
鏈式存儲結(jié)構(gòu)"。
可見,在順序存儲結(jié)構(gòu)中只包含數(shù)據(jù)元素本身的信息,而鏈式存儲結(jié)構(gòu)中以"由數(shù)據(jù)元素 x 的存儲映象和附加指針合成的結(jié)點"表示數(shù)據(jù)元素。
關系的最小單位是一個<x,y>的有序?qū)?,則討論關系的表示方法只需討論這個有序?qū)Φ谋硎痉椒纯?,即如何表?"y是x的后繼"。
順序映象
鏈式映象
1.2.3 數(shù)據(jù)類型和抽象數(shù)據(jù)類型
在用高級程序設計語言編寫的程序中,必須對程序中出現(xiàn)的每個變量、常量或表達式,明確說明它們所屬的數(shù)據(jù)類型。例如,C語言中的基本數(shù)據(jù)類型有:整型、字符型、實型(包括單精度型和雙精度型)及枚舉型。
數(shù)據(jù)類型是一個"值"的集合和定義在此集合上的"一組操作"的總稱。
所有高級語言中都有"整型"數(shù)據(jù)類型,它們的實現(xiàn)方法可以各自不同,但對程序員而言,它們是"相同"的。程序員使用它們時僅需了解它們的數(shù)學特性,而不需要了解它們在語言中是如何實現(xiàn)的。換句話說,各種語言中實現(xiàn)的是同一個"整數(shù)類型",而這個"整數(shù)類"的定義僅對"整數(shù)的數(shù)學特性"有明確規(guī)定。可稱這個"整數(shù)類型"為"抽象數(shù)據(jù)類型"。
抽象數(shù)據(jù)類型(
Abstract
Data
Type 簡稱
ADT)
是指一個數(shù)學模型以及定義在此數(shù)學模型上的一組操作。 例如,矩陣的抽象數(shù)據(jù)類型定義為,矩陣是一個由 m
n 個數(shù)排成 m 行 n 列的表,它可以進行初等變換、相加、相乘、求逆、……等運算。
抽象數(shù)據(jù)類型有兩個重要特性:
·數(shù)據(jù)抽象 用ADT描述程序處理的實體時,強調(diào)的是其本質(zhì)的特征、其所能完成的功能以及它和外部用戶的接口(即外界使用它的方法)。
·數(shù)據(jù)封裝 將實體的外部特性和其內(nèi)部實現(xiàn)細節(jié)分離,并且對外部用戶隱藏其內(nèi)部實現(xiàn)細節(jié)。
程序中對變量或常量說明其所屬類型的作用是,對它們加上兩個約束條件:一是可取值的范圍,二是可進行的操作。
在高級編程語言中實現(xiàn)的整數(shù)都具有下列"數(shù)學特性":
它是這樣一個序列:
……,-2,-1,0,1,2,……
此外,它可以進行"+"、"-"、"
"、"/"及"取模"等運算。
抽象"意為提取"數(shù)學特性"。
抽象數(shù)據(jù)類型必須給它的外部用戶提供完整的 "接口",例如,明確長整數(shù)是三個整數(shù)的序列以及可以對它進行的操作等。
同時,對外部用戶來說,不需要了解它是如何實現(xiàn)的,內(nèi)部實現(xiàn)的改變不影響外部的使用,更重要的是應該做到,不能讓外部用戶侵入內(nèi)部。對外部用戶來說,抽象數(shù)據(jù)類型應該完全是一個黑盒子。