本書在選材與編排上貼近當(dāng)前普通高等院校“數(shù)據(jù)結(jié)構(gòu)”課程的現(xiàn)狀和發(fā)展趨勢,內(nèi)容難度適中,突出實用性和應(yīng)用性。本書的具體內(nèi)容并未涉及各種數(shù)據(jù)結(jié)構(gòu),而是通過分類和講解典型結(jié)構(gòu)使讀者形成對數(shù)據(jù)結(jié)構(gòu)的宏觀認(rèn)識。根據(jù)內(nèi)容的側(cè)重,本書共分8章,分別為緒論、線性表、棧和隊列、串和數(shù)組、樹形結(jié)構(gòu)、圖、排序和查找。
本書可作為普通高校計算機相關(guān)專業(yè)“數(shù)據(jù)結(jié)構(gòu)”課程的教材,也可供學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)的讀者自學(xué)使用(包括參加計算機等級考試或相關(guān)專業(yè)自學(xué)考試)、參考,還可供程序員、系統(tǒng)工程師等相關(guān)人員閱讀參考。
本書是高等院校計算機科學(xué)、軟件工程及相關(guān)專業(yè)“數(shù)據(jù)結(jié)構(gòu)”課程的理想教材。
內(nèi)容精煉、強化基礎(chǔ)、合理安排內(nèi)容結(jié)構(gòu),做到內(nèi)容由淺入深,循序漸進。
應(yīng)用實例豐富完整。代碼有詳細(xì)明了的注釋,易于閱讀。
章節(jié)后附有小結(jié)和習(xí)題,便于學(xué)習(xí)總結(jié)和提高。
采用Java的泛型方法來體現(xiàn)方法的通用性。
圖文并茂,便于學(xué)生直觀地理解數(shù)據(jù)結(jié)構(gòu)與算法。
前言
隨著近年來計算概念的快速發(fā)展,計算學(xué)科已經(jīng)發(fā)展成為一個內(nèi)涵繁雜的綜合性學(xué)科,其至少可以劃分為計算機工程(CE)、計算機科學(xué)(CS)、信息系統(tǒng)(IS)、信息技術(shù)(IT)和軟件工程(SE)5個領(lǐng)域,而且不同領(lǐng)域的人才所應(yīng)具備的知識結(jié)構(gòu)與能力側(cè)重也不盡相同。盡管如此,從目前已經(jīng)完成的部分來看,數(shù)據(jù)結(jié)構(gòu)在各領(lǐng)域的知識體系中仍然占據(jù)著重要的位置!皵(shù)據(jù)結(jié)構(gòu)”是普通高等院校計算機和信息管理等專業(yè)的一門必修課程,主要討論數(shù)據(jù)的邏輯結(jié)構(gòu)、在計算機中的存儲結(jié)構(gòu)以及對其進行的各種處理運算的方法和算法。
N.Wirth早在20世紀(jì)70年代就指出“程序=數(shù)據(jù)結(jié)構(gòu)+算法”。數(shù)據(jù)結(jié)構(gòu)主要研究數(shù)據(jù)在計算機中存儲、組織、傳遞和轉(zhuǎn)換的過程及方法,這些也是構(gòu)成與支撐算法的基礎(chǔ)。近年來,隨著面向?qū)ο蠹夹g(shù)的廣泛應(yīng)用,從數(shù)據(jù)結(jié)構(gòu)的定義、分類、組成到設(shè)計、實現(xiàn)與分析的模式和方法都有了長足的發(fā)展,現(xiàn)代數(shù)據(jù)結(jié)構(gòu)更加注重和強調(diào)數(shù)據(jù)結(jié)構(gòu)的整體性、通用性、復(fù)用性、簡潔性和安全性。
為遵循上述原則,本書選擇Java作為描述語言,因為相對于其他語言,Java程序設(shè)計語言是應(yīng)用最廣泛、面向?qū)ο蟪潭然罡叩恼Z言,利用Java語言中的類和接口能夠準(zhǔn)確地描述任何一種數(shù)據(jù)結(jié)構(gòu)的邏輯定義和運算,利用一種存儲結(jié)構(gòu)定義的派生類能夠高效地實現(xiàn)對數(shù)據(jù)的運算。
在內(nèi)容的選取與結(jié)構(gòu)上,本書并未涉及各種數(shù)據(jù)結(jié)構(gòu),而是通過分類和講解典型結(jié)構(gòu)使讀者形成對數(shù)據(jù)結(jié)構(gòu)的宏觀認(rèn)識。根據(jù)內(nèi)容的側(cè)重,本書共分8章,分別為緒論、線性表、棧和隊列、串和數(shù)組、樹形結(jié)構(gòu)、圖、排序和查找。
第1章介紹數(shù)據(jù)結(jié)構(gòu)的基本概念,算法的描述和算法時間復(fù)雜度、空間復(fù)雜度等內(nèi)容,是全書的基礎(chǔ)。
第2章主要介紹線性表的基本概念和抽象數(shù)據(jù)類型定義、線性表順序和鏈?zhǔn)絻煞N存儲方式的表示、基本操作的實現(xiàn)和相應(yīng)的應(yīng)用。
第3章簡要介紹棧和隊列的基本概念和抽象數(shù)據(jù)類型定義、棧和隊列在順序存儲和鏈?zhǔn)酱鎯Y(jié)構(gòu)下的基本操作和應(yīng)用。
第4章主要介紹串的基本概念和數(shù)據(jù)類型定義、串的存儲結(jié)構(gòu)、基本操作實現(xiàn)和應(yīng)用等內(nèi)容。
第5章主要介紹樹和二叉樹的基本概念,詳細(xì)介紹二叉樹的性質(zhì)和存儲結(jié)構(gòu)、遍歷方法的實現(xiàn)及應(yīng)用、哈夫曼樹的概念和構(gòu)造方法。
第6章主要介紹圖的基本概念、抽象數(shù)據(jù)類型定義、存儲結(jié)構(gòu)和遍歷方法,還介紹最小生成樹的基本概念和算法、最短路徑的相關(guān)算法、拓?fù)渑判虻母拍詈蛯崿F(xiàn)方法。
第7章介紹排序的基本概念,插入排序、交換排序、選擇排序、歸并排序等多種排序的原理、實現(xiàn)方法及性能分析。
第8章主要介紹查找的基本概念,順序查找、二分查找等查找的原理、實現(xiàn)方法和性能分析,平衡二叉樹、哈希表的概念、結(jié)構(gòu)定義和實現(xiàn)方法。
本書的理論知識的教學(xué)安排建議如下:
章節(jié)內(nèi)容學(xué)時數(shù)
第1章緒論2
第2章線性表4~6
第3章棧和隊列6~8
第4章串和數(shù)組2~4
第5章樹形結(jié)構(gòu)6~8
第6章圖4~8
第7章排序4~6
第8章查找4~6
建議先修課程:Java語言
建議理論教學(xué)時數(shù):32~48學(xué)時
建議實驗(實踐)教學(xué)時數(shù):16~32學(xué)時
本書中的所有算法都已經(jīng)通過上機調(diào)試,盡量確保算法的正確性。在每章內(nèi)容后都有小結(jié),便于讀者復(fù)習(xí)總結(jié),并配有豐富的習(xí)題,包括選擇題、填空題、算法設(shè)計題等,給讀者更多思考的空間。
本書在以下幾個方面具有突出特色:
(1)內(nèi)容精練,強化基礎(chǔ),合理安排內(nèi)容結(jié)構(gòu),做到由淺入深、循序漸進。
本書各章節(jié)都從基本概念入手,逐步介紹其特點和基本操作的實現(xiàn),把重點放在基礎(chǔ)知識的介紹上,縮減難度較大的內(nèi)容,使理論敘述簡潔明了、重點突出、詳略得當(dāng)。
(2)應(yīng)用實例豐富、完整。
本書通過豐富的應(yīng)用實例和源代碼使理論和應(yīng)用緊密結(jié)合,增強學(xué)生的理解能力,鍛煉程序設(shè)計思維,并且代碼有詳細(xì)明了的注釋,易于閱讀。
。3)每章后面附有小結(jié)和習(xí)題,便于學(xué)習(xí)、總結(jié)和提高。
本書結(jié)合學(xué)生的學(xué)習(xí)實際選擇難度適中、邏輯合理,適于初學(xué)者和進階者開拓思路、深入了解數(shù)據(jù)結(jié)構(gòu)使用方法和技巧的習(xí)題,并附有詳細(xì)的解答過程和注意要點,達到通俗易懂、由淺入深的效果,培養(yǎng)讀者遷移知識的能力。
。4)采用Java的泛型方法來體現(xiàn)方法的通用性。
本書采用面向?qū)ο蟮挠^點討論數(shù)據(jù)結(jié)構(gòu)技術(shù),先將抽象數(shù)據(jù)類型定義成接口,再結(jié)合具體的存儲結(jié)構(gòu)加以實現(xiàn),并以各實現(xiàn)類為線索對類中各種操作的實現(xiàn)方法加以說明。
(5)圖文并茂,便于學(xué)生直觀地理解數(shù)據(jù)結(jié)構(gòu)與算法。
本書通過圖表的方式對數(shù)據(jù)結(jié)構(gòu)及相應(yīng)操作進行簡單直接的描述,使內(nèi)容更加淺顯易懂。
教師可以按照自己對數(shù)據(jù)結(jié)構(gòu)的理解適當(dāng)?shù)靥^一些章節(jié),也可以根據(jù)教學(xué)目標(biāo)靈活地調(diào)整章節(jié)的順序,增減各章的學(xué)時數(shù)。
由于數(shù)據(jù)結(jié)構(gòu)本身還在探索之中,加上我們的水平和能力有限,本書難免有疏漏之處,懇請各位同仁和廣大讀者給予批評指正,也希望各位能將實踐過程中的經(jīng)驗和心得與我們交流(yunxianglu@hotmail.com)。
作者
2017年6月
第1章緒論
1.1引言
1.1.1學(xué)習(xí)目的
1.1.2課程內(nèi)容
1.2基本概念
1.2.1數(shù)據(jù)與數(shù)據(jù)結(jié)構(gòu)
1.2.2數(shù)據(jù)類型與抽象數(shù)據(jù)類型
1.3算法
1.3.1算法的概念
1.3.2算法描述
1.3.3算法分析
1.4Java提供的泛型方法
1.4.1使用Object類表示泛型
1.4.2使用Comparable接口類型表示泛型
小結(jié)
習(xí)題1
第2章線性表
2.1線性表及其基本操作
2.1.1線性表的基本概念
2.1.2抽象數(shù)據(jù)類型描述
2.1.3線性表的存儲和實現(xiàn)
2.2線性表的順序存儲
2.2.1順序表
2.2.2順序表的基本操作實現(xiàn)
2.3線性表的鏈?zhǔn)酱鎯蛯崿F(xiàn)
2.3.1單鏈表
2.3.2單鏈表的基本操作實現(xiàn)
2.3.3其他鏈表
2.4順序表與鏈表的比較
小結(jié)
習(xí)題2
第3章棧和隊列
3.1棧
3.1.1棧的基本概念
3.1.2棧的抽象數(shù)據(jù)類型描述
3.1.3順序棧
3.1.4鏈棧
3.2隊列
3.2.1隊列的基本概念
3.2.2隊列的抽象數(shù)據(jù)類型描述
3.2.3順序隊列
3.2.4鏈隊列
3.2.5優(yōu)先級隊列
3.3棧和隊列的比較
小結(jié)
習(xí)題3
第4章串和數(shù)組
4.1串
4.1.1串的基本概念
4.1.2串的抽象數(shù)據(jù)類型描述
4.1.3順序串
4.1.4鏈串
4.2串的模式匹配
4.2.1BruteForce算法
4.2.2KMP算法
4.3數(shù)組
4.3.1數(shù)組的基本概念
4.3.2數(shù)組的特性
4.3.3數(shù)組的遍歷
4.4特殊矩陣的壓縮存儲
4.4.1三角矩陣的壓縮存儲
4.4.2對稱矩陣的壓縮存儲
4.4.3對角矩陣的壓縮存儲
4.4.4稀疏矩陣的壓縮存儲
小結(jié)
習(xí)題4
第5章樹形結(jié)構(gòu)
5.1樹
5.1.1樹的基本概念
5.1.2樹的術(shù)語
5.2二叉樹
5.2.1二叉樹的基本概念
5.2.2二叉樹的性質(zhì)
5.2.3二叉樹的存儲結(jié)構(gòu)
5.2.4二叉樹的遍歷
5.2.5二叉樹遍歷算法的應(yīng)用
5.2.6二叉樹的建立
5.3哈夫曼樹及哈夫曼編碼
5.3.1哈夫曼樹的基本概念
5.3.2哈夫曼樹的構(gòu)造
5.3.3哈夫曼編碼
5.3.4構(gòu)造哈夫曼樹和哈夫曼編碼的類的描述
5.4樹和森林
5.4.1樹的存儲結(jié)構(gòu)
5.4.2樹的遍歷規(guī)則
小結(jié)
習(xí)題5
第6章圖
6.1圖概述
6.1.1圖的基本概念
6.1.2圖的抽象數(shù)據(jù)類型描述
6.2圖的存儲結(jié)構(gòu)
6.2.1鄰接矩陣
6.2.2鄰接表
6.3圖的遍歷
6.4最小生成樹
6.4.1最小生成樹的基本概念
6.4.2Kruskal算法
6.4.3Prim算法
6.5最短路徑
6.5.1求某個頂點到其余頂點的最短路徑
6.5.2求任意兩個頂點間的最短路徑
6.6拓?fù)渑判蚝完P(guān)鍵路徑
6.6.1拓?fù)渑判?
6.6.2關(guān)鍵路徑
小結(jié)
習(xí)題6
第7章排序
7.1排序概述
7.1.1排序的基本概念
7.1.2排序算法的性能評價
7.1.3待排序的記錄和順序表的類描述
7.2插入排序
7.2.1直接插入排序
7.2.2希爾排序
7.3交換排序
7.3.1冒泡排序
7.3.2快速排序
7.4選擇排序
7.4.1直接選擇排序
7.4.2堆排序
7.5歸并排序
小結(jié)
習(xí)題7
第8章查找
8.1查找的基本概念
8.1.1什么是查找
8.1.2查找表
8.1.3平均查找長度
8.2靜態(tài)表查找
8.2.1順序查找
8.2.2二分查找
8.2.3分塊查找
8.3動態(tài)表查找
8.3.1二叉排序樹查找
8.3.2平衡二叉樹
8.3.3B-樹和B+樹
8.4哈希表查找
8.4.1哈希表的概念
8.4.2哈希函數(shù)
8.4.3解決沖突的方法
8.4.4哈希表查找性能分析
小結(jié)
習(xí)題8
附錄A數(shù)據(jù)結(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ù)結(jié)構(gòu)試卷(五)
附錄B實踐題
參考文獻
第5章
樹形結(jié)構(gòu)
5.1樹
5.1.1樹的基本概念
樹是數(shù)據(jù)元素之間具有層次關(guān)系的非線性結(jié)構(gòu),是由n個結(jié)點構(gòu)成的有限集合,結(jié)點數(shù)為0的樹叫空樹。樹必須滿足以下條件。
(1)有且僅有一個被稱為根的結(jié)點。
(2)其余結(jié)點可分為m個互不相交的有限集合,每個集合又構(gòu)成一棵樹,叫根結(jié)點的子樹。
與線性結(jié)構(gòu)不同,樹中的數(shù)據(jù)元素具有一對多的邏輯關(guān)系,除根結(jié)點以外,每個數(shù)據(jù)元素可以有多個后繼但有且僅有一個前驅(qū),反映了數(shù)據(jù)元素之間的層次關(guān)系。
樹是遞歸定義的。結(jié)點是樹的基本單位,若干個結(jié)點組成一棵子樹,若干棵互不相交的子樹組成一棵樹。
圖5.1樹的邏輯結(jié)構(gòu)示意圖
人們在生活中所見的家譜、Windows的文件系統(tǒng)等,雖然表現(xiàn)形式各異,在本質(zhì)上是樹結(jié)構(gòu)。圖5.1給出了樹的邏輯結(jié)構(gòu)示意圖。
樹的表示方法有多種,如樹形表示法、文氏圖表示法、凹入圖表示法和廣義表表示法。圖5.1所示為樹形表示法,圖5.2給出了用其他3種表示法對樹的表示。
圖5.2樹的3種表示方法
5.1.2樹的術(shù)語
1.結(jié)點
樹的結(jié)點就是構(gòu)成樹的數(shù)據(jù)元素,就是其他數(shù)據(jù)結(jié)構(gòu)中存儲的數(shù)據(jù)項,在樹形表示法中用圓圈表示。
2.結(jié)點的路徑
結(jié)點的路徑是指從根結(jié)點到該結(jié)點所經(jīng)過結(jié)點的順序排列。
3.路徑的長度
路徑的長度指的是路徑中包含的分支數(shù)。
4.結(jié)點的度
結(jié)點的度指的是結(jié)點擁有的子樹的數(shù)目。
5.樹的度
樹的度指的是樹中所有結(jié)點的度的最大值。
6.葉結(jié)點
葉結(jié)點是樹中度為0的結(jié)點,也叫終端結(jié)點。
7.分支結(jié)點
分支結(jié)點是樹中度不為0的結(jié)點,也叫非終端結(jié)點。
8.子結(jié)點
子結(jié)點是指結(jié)點的子樹的根結(jié)點,也叫孩子結(jié)點。
9.父結(jié)點
具有子結(jié)點的結(jié)點叫該子結(jié)點的父結(jié)點,也叫雙親結(jié)點。
10.子孫結(jié)點
子孫結(jié)點是指結(jié)點的子樹中的任意結(jié)點。
11.祖先結(jié)點
祖先結(jié)點是指結(jié)點的路徑中除自身之外的所有結(jié)點。
12.兄弟結(jié)點
兄弟結(jié)點是指和結(jié)點具有同一父結(jié)點的結(jié)點。
13.結(jié)點的層次
樹中根結(jié)點的層次為0,其他結(jié)點的層次是父結(jié)點的層次加1。
14.樹的深度
樹的深度是指樹中所有結(jié)點的層次數(shù)的最大值加1。
15.有序樹
有序樹是指樹的各結(jié)點的所有子樹具有次序關(guān)系,不可以改變位置。
16.無序樹
無序樹是指樹的各結(jié)點的所有子樹之間無次序關(guān)系,可以改變位置。
17.森林
森林是由多個互不相交的樹構(gòu)成的集合。給森林加上一個根結(jié)點就變成一棵樹,將樹的根結(jié)點刪除就變成森林。
5.2二叉樹
5.2.1二叉樹的基本概念
1.普通二叉樹
二叉樹是特殊的有序樹,它也是由n個結(jié)點構(gòu)成的有限集合。當(dāng)n=0時稱為空二叉樹。二叉樹的每個結(jié)點最多只有兩棵子樹,子樹也為二叉樹,互不相交且有左右之分,分別稱為左二叉樹和右二叉樹。
二叉樹也是遞歸定義的,在樹中定義的度、層次等術(shù)語同樣也適用于二叉樹。
2.滿二叉樹
滿二叉樹是特殊的二叉樹,它要求除葉結(jié)點外的其他結(jié)點都具有兩棵子樹,并且所有的葉結(jié)點都在同一層上,如圖5.3所示。
3.完全二叉樹
完全二叉樹是特殊的二叉樹,若完全二叉樹具有n個結(jié)點,它要求n個結(jié)點與滿二叉樹的前n個結(jié)點具有完全相同的邏輯結(jié)構(gòu),如圖5.4所示。