今天開始認真讀這本清華版的資料結構,嚴蔚敏和吳偉民編著。也許你會奇怪我為什麼會選擇這本C語言描述的資料結構書,現在的資料結構不都用物件導向語言描述嗎?其實這本書不是我選的,而是我參加的機試指定的參考書。不過對於本書選用的語言,我倒有自己的看法。用C語言描述顯然有很多不便,但是在一個充斥著用OO描述資料結構的世界裡,從OO中抽身出來用C看待資料結構的思想,也許更能看清資料結構的本質。
好了,言歸正傳。在今天這第一篇文章裡,我來探討一下資料結構的基本概念。作者一開篇就歸納了電腦解題的一般步驟:“首先要從具體問題抽象出一個適當的數學模型,然後設計一個解此數學模型的演算法,最後編出程式,進行測試、調試直至得到最終解答。”我把它再進一步歸納一下,就是:抽象數學模型——設計演算法——編寫程式。這個思路非常重要,除了一些非常簡單的問題,所有的程式設計都應該遵循這三個基本步驟。我們平時寫程式常犯的錯誤是忽略第一個或第二個步驟,或者更甚者,前兩個都忽略。
在設計數學模型的過程中,實際上就引出了資料結構的概念。本書中作者給出的定義是:“簡單來說,資料結構是一門研究非數值計算的程式設計問題中電腦的操作對象以及它們之間的關係和操作等的學科。”國內的教材為了語言上的嚴謹常常把話說得很難懂。請大家注意這句話裡的這幾個關鍵詞:1)非數值計算,這說明了資料結構這門學科的應用範圍,如果你想解一個線性方程組,大概很難直接找到合適的資料結構;2)操作對象,也就是問題中的資料及其表示的形式;3)關係,即資料間的關係;4)操作,即針對資料的操作。
把以上的定義用公式寫出來,就是
Data_Structure = (D, S)
其中D是資料元素的有限集,S是D上關係的有限集。所以在設計資料結構時,首要的任務就是找出要操作的資料,其次是挖掘出資料間的關係。這兩步完成以後,資料的邏輯結構就定下來了。其中資料間的結構有以下幾種:
- 集合,這和數學中的集合概念是一致的;
- 線性結構,即資料元素之間一對一的關係;
- 樹形結構,即資料元素之間一對多的關係;
- 圖狀結構或網狀結構,即資料元素之間多對多的關係。
然而只有邏輯結構是不夠的,程式要能夠運行,必須把資料的邏輯結構在電腦中表示出來,也就是設計物理結構。大多數進階語言都對資料的物理結構有較好支援,如各種資料類型。作者在解釋資料類型的概念時說到:“引入資料類型的目的,從硬體的角度看,是作為解釋電腦記憶體中資訊含義的一種手段,而對使用資料類型的使用者來說,實現了資訊的隱蔽,即將一切使用者不必瞭解的細節都封裝在類型中。”這個概括非常精闢,從中可以看出以後的OOP只是在更高層次上對資訊的封裝和隱蔽。
對資料類型進一步擴充,作者引出了抽象資料類型的概念。抽象資料類型(ADT)是指一個數學模型以及定義在該模型上的一組操作。在引入抽象資料類型後,使邏輯結構更加獨立,從而讓程式員可以更加專註於邏輯結構的設計。把抽象資料類型用公式表示出來,就是
(D, S, P)
其中D是資料對象,S是D上的關係集,P是對D的基本操作集。如果電腦解題一定要遵循一個通用的模式的話,上面這個式子就給出了答案。