歡迎來到裝配圖網(wǎng)! | 幫助中心 裝配圖網(wǎng)zhuangpeitu.com!
裝配圖網(wǎng)
ImageVerifierCode 換一換
首頁 裝配圖網(wǎng) > 資源分類 > PPT文檔下載  

《數(shù)據(jù)結(jié)構(gòu)嚴(yán)蔚敏》PPT課件

  • 資源ID:16519629       資源大?。?span id="1wyrw2e" class="font-tahoma">6.36MB        全文頁數(shù):815頁
  • 資源格式: PPT        下載積分:19.9積分
快捷下載 游客一鍵下載
會員登錄下載
微信登錄下載
三方登錄下載: 微信開放平臺登錄 支付寶登錄   QQ登錄   微博登錄  
二維碼
微信掃一掃登錄
下載資源需要19.9積分
郵箱/手機(jī):
溫馨提示:
用戶名和密碼都是您填寫的郵箱或者手機(jī)號,方便查詢和重復(fù)下載(系統(tǒng)自動生成)
支付方式: 支付寶    微信支付   
驗證碼:   換一換

 
賬號:
密碼:
驗證碼:   換一換
  忘記密碼?
    
友情提示
2、PDF文件下載后,可能會被瀏覽器默認(rèn)打開,此種情況可以點擊瀏覽器菜單,保存網(wǎng)頁到桌面,就可以正常下載了。
3、本站不支持迅雷下載,請使用電腦自帶的IE瀏覽器,或者360瀏覽器、谷歌瀏覽器下載即可。
4、本站資源下載后的文檔和圖紙-無水印,預(yù)覽文檔經(jīng)過壓縮,下載后原文更清晰。
5、試題試卷類文檔,如果標(biāo)題沒有明確說明有答案則都視為沒有答案,請知曉。

《數(shù)據(jù)結(jié)構(gòu)嚴(yán)蔚敏》PPT課件

數(shù)據(jù)結(jié)構(gòu)目錄,第一章:緒論 第二章: 第三章: 第四章: 第五章: 第六章: 第七章: 第八章: 第九章: 第十章:排序,算法與數(shù)據(jù)結(jié)構(gòu),教材:數(shù)據(jù)結(jié)構(gòu)(C語言版)。嚴(yán)蔚敏,吳偉民 編 著。清華大學(xué)出版社。 參考文獻(xiàn): 1 數(shù)據(jù)結(jié)構(gòu) 。張選平,雷詠梅 編, 嚴(yán)蔚敏 審。 機(jī)械工業(yè)出版社。 2 數(shù)據(jù)結(jié)構(gòu)與算法分析。Clifford A. Shaffer著, 張 銘,劉曉丹 譯。電子工業(yè)出版社。 3 數(shù)據(jù)結(jié)構(gòu)習(xí)題與解析(C語實言版)。李春葆。 清華大學(xué)出版社。 4 數(shù)據(jù)結(jié)構(gòu)與算法。夏克儉 編著。國防工業(yè)出版社。,第1章 緒 論,目前,計算機(jī)已深入到社會生活的各個領(lǐng)域,其應(yīng)用已不再僅僅局限于科學(xué)計算,而更多的是用于控制,管理及數(shù)據(jù)處理等非數(shù)值計算領(lǐng)域。計算機(jī)是一門研究用計算機(jī)進(jìn)行信息表示和處理的科學(xué)。這里面涉及到兩個問題:信息的表示,信息的處理。 信息的表示和組織又直接關(guān)系到處理信息的程序的效率。隨著應(yīng)用問題的不斷復(fù)雜,導(dǎo)致信息量劇增與信息范圍的拓寬,使許多系統(tǒng)程序和應(yīng)用程序的規(guī)模很大,結(jié)構(gòu)又相當(dāng)復(fù)雜。因此,必須分析待處理問題中的對象的特征及各對象之間存在的關(guān)系,這就是數(shù)據(jù)結(jié)構(gòu)這門課所要研究的問題。,編寫解決實際問題的程序的一般過程: 如何用數(shù)據(jù)形式描述問題?即由問題抽象出一個適當(dāng)?shù)臄?shù)學(xué)模型; 問題所涉及的數(shù)據(jù)量大小及數(shù)據(jù)之間的關(guān)系; 如何在計算機(jī)中存儲數(shù)據(jù)及體現(xiàn)數(shù)據(jù)之間的關(guān)系? 處理問題時需要對數(shù)據(jù)作何種運算? 所編寫的程序的性能是否良好? 上面所列舉的問題基本上由數(shù)據(jù)結(jié)構(gòu)這門課程來回答。,計算機(jī)求解問題的一般步驟,1.1 數(shù)據(jù)結(jié)構(gòu)及其概念,算法與數(shù)據(jù)結(jié)構(gòu)是計算機(jī)科學(xué)中的一門綜合性專業(yè)基礎(chǔ)課。是介于數(shù)學(xué)、計算機(jī)硬件、計算機(jī)軟件三者之間的一門核心課程,不僅是一般程序設(shè)計的基礎(chǔ),而且是設(shè)計和實現(xiàn)編譯程序、操作系統(tǒng)、數(shù)據(jù)庫系統(tǒng)及其他系統(tǒng)程序和大型應(yīng)用程序的重要基礎(chǔ)。,1.1.1 數(shù)據(jù)結(jié)構(gòu)的例子,例1:電話號碼查詢系統(tǒng) 設(shè)有一個電話號碼薄,它記錄了N個人的名字和其相應(yīng)的電話號碼,假定按如下形式安排:(a1, b1),(a2, b2),(an, bn),其中ai, bi(i=1,2n) 分別表示某人的名字和電話號碼。 本問題是一種典型的表格問題。如表1-1,數(shù)據(jù)與數(shù)據(jù)成簡單的一對一的線性關(guān)系。,表1-1 線性表結(jié)構(gòu),例2:磁盤目錄文件系統(tǒng) 磁盤根目錄下有很多子目錄及文件,每個子目錄里又可以包含多個子目錄及文件,但每個子目錄只有一個父目錄,依此類推: 本問題是一種典型的樹型結(jié)構(gòu)問題,如圖1-1 ,數(shù)據(jù)與數(shù)據(jù)成一對多的關(guān)系,是一種典型的非線性關(guān)系結(jié)構(gòu)樹形結(jié)構(gòu)。,圖1-1 樹形結(jié)構(gòu),例3:交通網(wǎng)絡(luò)圖 從一個地方到另外一個地方可以有多條路徑。本問題是一種典型的網(wǎng)狀結(jié)構(gòu)問題,數(shù)據(jù)與數(shù)據(jù)成多對多的關(guān)系,是一種非線性關(guān)系結(jié)構(gòu)。,數(shù)據(jù)(Data) :是客觀事物的符號表示。在計算機(jī)科學(xué)中指的是所有能輸入到計算機(jī)中并被計算機(jī)程序處理的符號的總稱。 數(shù)據(jù)元素(Data Element) :是數(shù)據(jù)的基本單位,在程序中通常作為一個整體來進(jìn)行考慮和處理。 一個數(shù)據(jù)元素可由若干個數(shù)據(jù)項(Data Item)組成。數(shù)據(jù)項是數(shù)據(jù)的不可分割的最小單位。數(shù)據(jù)項是對客觀事物某一方面特性的數(shù)據(jù)描述。 數(shù)據(jù)對象(Data Object):是性質(zhì)相同的數(shù)據(jù)元素的集合,是數(shù)據(jù)的一個子集。如字符集合C=A,B,C, 。,1.1.2 基本概念和術(shù)語,數(shù)據(jù)結(jié)構(gòu)(Data Structure):是指相互之間具有(存在)一定聯(lián)系(關(guān)系)的數(shù)據(jù)元素的集合。元素之間的相互聯(lián)系(關(guān)系)稱為邏輯結(jié)構(gòu)。數(shù)據(jù)元素之間的邏輯結(jié)構(gòu)有四種基本類型,如圖1-3所示。 集合:結(jié)構(gòu)中的數(shù)據(jù)元素除了“同屬于一個集合”外,沒有其它關(guān)系。 線性結(jié)構(gòu):結(jié)構(gòu)中的數(shù)據(jù)元素之間存在一對一的關(guān)系。 樹型結(jié)構(gòu):結(jié)構(gòu)中的數(shù)據(jù)元素之間存在一對多的關(guān)系。 圖狀結(jié)構(gòu)或網(wǎng)狀結(jié)構(gòu):結(jié)構(gòu)中的數(shù)據(jù)元素之間存在多對多的關(guān)系。,數(shù)據(jù)結(jié)構(gòu)的形式定義是一個二元組: Data-Structure=(D,S) 其中:D是數(shù)據(jù)元素的有限集,S是D上關(guān)系的有限集。 例2:設(shè)數(shù)據(jù)邏輯結(jié)構(gòu)B=(K,R) K=k1, k2, , k9 R= , 畫出這邏輯結(jié)構(gòu)的圖示,并確定那些是起點,那些是終點,1.1.3 數(shù)據(jù)結(jié)構(gòu)的形式定義,圖1-3 四類基本結(jié)構(gòu)圖,1.1.4 數(shù)據(jù)結(jié)構(gòu)的存儲方式,數(shù)據(jù)元素之間的關(guān)系可以是元素之間代表某種含義的自然關(guān)系,也可以是為處理問題方便而人為定義的關(guān)系,這種自然或人為定義的 “關(guān)系”稱為數(shù)據(jù)元素之間的邏輯關(guān)系,相應(yīng)的結(jié)構(gòu)稱為邏輯結(jié)構(gòu)。,數(shù)據(jù)結(jié)構(gòu)在計算機(jī)內(nèi)存中的存儲包括數(shù)據(jù)元素的存儲和元素之間的關(guān)系的表示。 元素之間的關(guān)系在計算機(jī)中有兩種不同的表示方法:順序表示和非順序表示。由此得出兩種不同的存儲結(jié)構(gòu):順序存儲結(jié)構(gòu)和鏈?zhǔn)酱鎯Y(jié)構(gòu)。 順序存儲結(jié)構(gòu):用數(shù)據(jù)元素在存儲器中的相對位置來表示數(shù)據(jù)元素之間的邏輯結(jié)構(gòu)(關(guān)系)。,鏈?zhǔn)酱鎯Y(jié)構(gòu):在每一個數(shù)據(jù)元素中增加一個存放另一個元素地址的指針(pointer ),用該指針來表示數(shù)據(jù)元素之間的邏輯結(jié)構(gòu)(關(guān)系)。 例:設(shè)有數(shù)據(jù)集合A=3.0,2.3,5.0,-8.5,11.0 ,兩種不同的存儲結(jié)構(gòu)。 順序結(jié)構(gòu):數(shù)據(jù)元素存放的地址是連續(xù)的; 鏈?zhǔn)浇Y(jié)構(gòu):數(shù)據(jù)元素存放的地址是否連續(xù)沒有要求。 數(shù)據(jù)的邏輯結(jié)構(gòu)和物理結(jié)構(gòu)是密不可分的兩個方面,一個算法的設(shè)計取決于所選定的邏輯結(jié)構(gòu),而算法的實現(xiàn)依賴于所采用的存儲結(jié)構(gòu)。 在C語言中,用一維數(shù)組表示順序存儲結(jié)構(gòu);用結(jié)構(gòu)體類型表示鏈?zhǔn)酱鎯Y(jié)構(gòu)。,數(shù)據(jù)結(jié)構(gòu)的三個組成部分: 邏輯結(jié)構(gòu): 數(shù)據(jù)元素之間邏輯關(guān)系的描述 D_S=(D,S) 存儲結(jié)構(gòu): 數(shù)據(jù)元素在計算機(jī)中的存儲及其邏輯關(guān)系的表現(xiàn)稱為數(shù)據(jù)的存儲結(jié)構(gòu)或物理結(jié)構(gòu)。 數(shù)據(jù)操作: 對數(shù)據(jù)要進(jìn)行的運算。 本課程中將要討論的三種邏輯結(jié)構(gòu)及其采用的存儲結(jié)構(gòu)如圖1-4所示。,數(shù)據(jù)類型(Data Type):指的是一個值的集合和定義在該值集上的一組操作的總稱。 數(shù)據(jù)類型是和數(shù)據(jù)結(jié)構(gòu)密切相關(guān)的一個概念。 在C語言中數(shù)據(jù)類型有:基本類型和構(gòu)造類型。 數(shù)據(jù)結(jié)構(gòu)不同于數(shù)據(jù)類型,也不同于數(shù)據(jù)對象,它不僅要描述數(shù)據(jù)類型的數(shù)據(jù)對象,而且要描述數(shù)據(jù)對象各元素之間的相互關(guān)系。,1.1.5 數(shù)據(jù)類型,數(shù)據(jù)結(jié)構(gòu)的主要運算包括: 建立(Create)一個數(shù)據(jù)結(jié)構(gòu); 消除(Destroy)一個數(shù)據(jù)結(jié)構(gòu); 從一個數(shù)據(jù)結(jié)構(gòu)中刪除(Delete)一個數(shù)據(jù)元素; 把一個數(shù)據(jù)元素插入(Insert)到一個數(shù)據(jù)結(jié)構(gòu)中; 對一個數(shù)據(jù)結(jié)構(gòu)進(jìn)行訪問(Access); 對一個數(shù)據(jù)結(jié)構(gòu)(中的數(shù)據(jù)元素)進(jìn)行修改(Modify); 對一個數(shù)據(jù)結(jié)構(gòu)進(jìn)行排序(Sort); 對一個數(shù)據(jù)結(jié)構(gòu)進(jìn)行查找(Search)。,1.1.6 數(shù)據(jù)結(jié)構(gòu)的運算,抽象數(shù)據(jù)類型(Abstract Data Type ,簡稱ADT):是指一個數(shù)學(xué)模型以及定義在該模型上的一組操作。 ADT的定義僅是一組邏輯特性描述, 與其在計算機(jī)內(nèi)的表示和實現(xiàn)無關(guān)。因此,不論ADT的內(nèi)部結(jié)構(gòu)如何變化,只要其數(shù)學(xué)特性不變,都不影響其外部使用。 ADT的形式化定義是三元組:ADT=(D,S,P) 其中:D是數(shù)據(jù)對象,S是D上的關(guān)系集,P是對D的基本操作集。,1.2 抽象數(shù)據(jù)類型,ADT的一般定義形式是: ADT 數(shù)據(jù)對象: 數(shù)據(jù)關(guān)系: 基本操作: ADT 其中數(shù)據(jù)對象和數(shù)據(jù)關(guān)系的定義用偽碼描述。 基本操作的定義是: () 初始條件: 操作結(jié)果: ,初始條件:描述操作執(zhí)行之前數(shù)據(jù)結(jié)構(gòu)和參數(shù)應(yīng)滿足的條件;若不滿足,則操作失敗,返回相應(yīng)的出錯信息。 操作結(jié)果:描述操作正常完成之后,數(shù)據(jù)結(jié)構(gòu)的變化狀況和 應(yīng)返回的結(jié)果。,1.3.1 算法 算法(Algorithm):是對特定問題求解方法(步驟)的一種描述,是指令的有限序列,其中每一條指令表示一個或多個操作。 算法具有以下五個特性 有窮性: 一個算法必須總是在執(zhí)行有窮步之后結(jié)束,且每一步都在有窮時間內(nèi)完成。 確定性:算法中每一條指令必須有確切的含義。不存在二義性。且算法只有一個入口和一個出口。 可行性: 一個算法是能行的。即算法描述的操作都可以通過已經(jīng)實現(xiàn)的基本運算執(zhí)行有限次來實現(xiàn)。,1.3 算法分析初步, 輸入: 一個算法有零個或多個輸入,這些輸入取自于某個特定的對象集合。 輸出: 一個算法有一個或多個輸出,這些輸出是同輸入有著某些特定關(guān)系的量。 一個算法可以用多種方法描述,主要有:使用自然語言描述;使用形式語言描述;使用計算機(jī)程序設(shè)計語言描述。 算法和程序是兩個不同的概念。一個計算機(jī)程序是對一個算法使用某種程序設(shè)計語言的具體實現(xiàn)。算法必須可終止意味著不是所有的計算機(jī)程序都是算法。 在本門課程的學(xué)習(xí)、作業(yè)練習(xí)、上機(jī)實踐等環(huán)節(jié),算法都用C語言來描述。在上機(jī)實踐時,為了檢查算法是否正確,應(yīng)編寫成完整的C語言程序。,評價一個好的算法有以下幾個標(biāo)準(zhǔn) 正確性(Correctness ): 算法應(yīng)滿足具體問題的需求。 可讀性(Readability): 算法應(yīng)容易供人閱讀和交流。可讀性好的算法有助于對算法的理解和修改。 健壯性(Robustness): 算法應(yīng)具有容錯處理。當(dāng)輸入非法或錯誤數(shù)據(jù)時,算法應(yīng)能適當(dāng)?shù)刈鞒龇磻?yīng)或進(jìn)行處理,而不會產(chǎn)生莫名其妙的輸出結(jié)果。 通用性(Generality): 算法應(yīng)具有一般性 ,即算法的處理結(jié)果對于一般的數(shù)據(jù)集合都成立。,1.3.2 算法設(shè)計的要求,算法執(zhí)行時間需通過依據(jù)該算法編制的程序在計算機(jī)上運行所消耗的時間來度量。其方法通常有兩種: 事后統(tǒng)計:計算機(jī)內(nèi)部進(jìn)行執(zhí)行時間和實際占用空間的統(tǒng)計。 問題:必須先運行依據(jù)算法編制的程序;依賴軟硬件環(huán)境,容易掩蓋算法本身的優(yōu)劣;沒有實際價值。 事前分析:求出該算法的一個時間界限函數(shù)。,1.3.3 算法效率的度量, 效率與存儲量需求: 效率指的是算法執(zhí)行的時間;存儲量需求指算法執(zhí)行過程中所需要的最大存儲空間。一般地,這兩者與問題的規(guī)模有關(guān)。,與此相關(guān)的因素有: 依據(jù)算法選用何種策略; 問題的規(guī)模; 程序設(shè)計的語言; 編譯程序所產(chǎn)生的機(jī)器代碼的質(zhì)量; 機(jī)器執(zhí)行指令的速度; 撇開軟硬件等有關(guān)部門因素,可以認(rèn)為一個特定算法“運行工作量”的大小,只依賴于問題的規(guī)模(通常用n表示),或者說,它是問題規(guī)模的函數(shù)。,算法分析應(yīng)用舉例,算法中基本操作重復(fù)執(zhí)行的次數(shù)是問題規(guī)模n的某個函數(shù),其時間量度記作 T(n)=O(f(n),稱作算法的漸近時間復(fù)雜度(Asymptotic Time complexity),簡稱時間復(fù)雜度。 一般地,常用最深層循環(huán)內(nèi)的語句中的原操作的執(zhí)行頻度(重復(fù)執(zhí)行的次數(shù))來表示。 “O”的定義: 若f(n)是正整數(shù)n的一個函數(shù),則 O(f(n)表示 M0 ,使得當(dāng)n n0時,| f(n) | M | f(n0) | 。 表示時間復(fù)雜度的階有: O(1) :常量時間階 O (n):線性時間階 O(n) :對數(shù)時間階 O(nn) :線性對數(shù)時間階,O (nk): k2 ,k次方時間階 例 兩個n階方陣的乘法 for(i=1,i<=n; +i) for(j=1; j<=n; +j) cij=0 ; for(k=1; k<=n; +k) cij+=aik*bkj ; 由于是一個三重循環(huán),每個循環(huán)從1到n,則總次數(shù)為: nnn=n3時間復(fù)雜度為T(n)=O(n3) 例 +x; s=0 ; 將x自增看成是基本操作,則語句頻度為,即時間復(fù)雜度為(1) 。,如果將s=0也看成是基本操作,則語句頻度為,其時間復(fù)雜度仍為(1),即常量階。 例 for(i=1; i<=n; +i) +x; s+=x ; 語句頻度為:2n,其時間復(fù)雜度為:O(n) ,即為線性階。 例 for(i=1; i<=n; +i) for(j=1; j<=n; +j) +x; s+=x ; 語句頻度為:2n2 ,其時間復(fù)雜度為:O(n2) ,即為平方階。,定理:若A(n)=a m n m +a m-1 n m-1 +a1n+a0是一個m次多項式,則A(n)=O(n m) 例 for(i=2;i<=n;+i) for(j=2;j<=i-1;+j) +x; ai,j=x; 語句頻度為: 1+2+3+n-2=(1+n-2) (n-2)/2 =(n-1)(n-2)/2 =n2-3n+2 時間復(fù)雜度為O(n2),即此算法的時間復(fù)雜度為平方階。 一個算法時間為O(1)的算法,它的基本運算執(zhí)行的次數(shù)是固定的。因此,總的時間由一個常數(shù)(即零次多項式)來限界。而一個時間為O(n2)的算法則由一個二次多項式來限界。,以下六種計算算法時間的多項式是最常用的。其關(guān)系為: O(1)<O(n)<O(n)<O(nn)<O(n2)<O(n3) 指數(shù)時間的關(guān)系為: O(2n)<O(n!)<O(nn) 當(dāng)n取得很大時,指數(shù)時間算法和多項式時間算法在所需時間上非常懸殊。因此,只要有人能將現(xiàn)有指數(shù)時間算法中的任何一個算法化簡為多項式時間算法,那就取得了一個偉大的成就。 有的情況下,算法中基本操作重復(fù)執(zhí)行的次數(shù)還隨問題的輸入數(shù)據(jù)集不同而不同。,例1:素數(shù)的判斷算法。 Void prime( int n) /* n是一個正整數(shù) */ int i=2 ; while ( (n% i)!=0 嵌套的最深層語句是i+;其頻度由條件( (n% i)!=0 for (i=n-1; change=TURE; i1 最好情況:0次 最壞情況:1+2+3+n-1=n(n-1)/2 平均時間復(fù)雜度為: O(n2),1.3.4 算法的空間分析,空間復(fù)雜度(Space complexity) :是指算法編寫成程序后,在計算機(jī)中運行時所需存儲空間大小的度量。記作: S(n)=O(f(n) 其中: n為問題的規(guī)模(或大小) 該存儲空間一般包括三個方面: 指令常數(shù)變量所占用的存儲空間; 輸入數(shù)據(jù)所占用的存儲空間; 輔助(存儲)空間。 一般地,算法的空間復(fù)雜度指的是輔助空間。 一維數(shù)組an: 空間復(fù)雜度 O(n) 二維數(shù)組anm: 空間復(fù)雜度 O(n*m),習(xí) 題 一,1 簡要回答術(shù)語:數(shù)據(jù),數(shù)據(jù)元素,數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)類型。 2 數(shù)據(jù)的邏輯結(jié)構(gòu)?數(shù)據(jù)的物理結(jié)構(gòu)?邏輯結(jié)構(gòu)與物理結(jié)構(gòu)的區(qū)別和聯(lián)系是什么? 3 數(shù)據(jù)結(jié)構(gòu)的主要運算包括哪些? 4 算法分析的目的是什么?算法分析的主要方面是什么? 5 分析以下程序段的時間復(fù)雜度,請說明分析的理由或原因。,第2章 線性表,線性結(jié)構(gòu)是最常用、最簡單的一種數(shù)據(jù)結(jié)構(gòu)。而線性表是一種典型的線性結(jié)構(gòu)。其基本特點是線性表中的數(shù)據(jù)元素是有序且是有限的。在這種結(jié)構(gòu)中: 存在一個唯一的被稱為“第一個”的數(shù)據(jù)元素; 存在一個唯一的被稱為“最后一個”的數(shù)據(jù)元素; 除第一個元素外,每個元素均有唯一一個直接前驅(qū); 除最后一個元素外,每個元素均有唯一一個直接后繼。,2.1 線性表的邏輯結(jié)構(gòu),線性表(Linear List) :是由n(n0)個數(shù)據(jù)元素(結(jié)點)a1,a2, an組成的有限序列。該序列中的所有結(jié)點具有相同的數(shù)據(jù)類型。其中數(shù)據(jù)元素的個數(shù)n稱為線性表的長度。 當(dāng)n=0時,稱為空表。 當(dāng)n0時,將非空的線性表記作: (a1,a2,an) a1稱為線性表的第一個(首)結(jié)點,an稱為線性表的最后一個(尾)結(jié)點。,2.1.1 線性表的定義,a1,a2,ai-1都是ai(2in)的前驅(qū),其中ai-1是ai的直接前驅(qū); ai+1,ai+2,an都是ai(1i n-1)的后繼,其中ai+1是ai的直接后繼。,2.1.2 線性表的邏輯結(jié)構(gòu),線性表中的數(shù)據(jù)元素ai所代表的具體含義隨具體應(yīng)用的不同而不同,在線性表的定義中,只不過是一個抽象的表示符號。 線性表中的結(jié)點可以是單值元素(每個元素只有一個數(shù)據(jù)項) 。 例1: 26個英文字母組成的字母表: (A,B,C、Z),例2 : 某校從1978年到1983年各種型號的計算機(jī)擁有量的變化情況:(6,17,28,50,92,188) 例3 : 一副撲克的點數(shù) (2,3,4,J,Q,K,A) 線性表中的結(jié)點可以是記錄型元素,每個元素含有多個數(shù)據(jù)項 ,每個項稱為結(jié)點的一個域 。每個元素有一個可以唯一標(biāo)識每個結(jié)點的數(shù)據(jù)項組,稱為關(guān)鍵字。 例4 : 某校2001級同學(xué)的基本情況:(2001414101,張里戶,男,06/24/1983), (2001414102,張化司,男,08/12/1984) , (2001414102,李利辣,女,08/12/1984) 若線性表中的結(jié)點是按值(或按關(guān)鍵字值)由小到大(或由大到小)排列的,稱線性表是有序的。,2.1.3 線性表的抽象數(shù)據(jù)類型定義,ADT List 數(shù)據(jù)對象:D = ai | aiElemSet, i=1,2,n, n0 數(shù)據(jù)關(guān)系:R = | ai-1, aiD, i=2,3,n 基本操作: InitList( 數(shù)據(jù)元素之間的關(guān)系是以元素在計算機(jī)內(nèi)“物理位置相鄰”來體現(xiàn)。 設(shè)有非空的線性表:(a1,a2,an) 。順序存儲如圖2-1所示。,2.2.1 線性表的順序存儲結(jié)構(gòu),在具體的機(jī)器環(huán)境下:設(shè)線性表的每個元素需占用l個存儲單元,以所占的第一個單元的存儲地址作為數(shù)據(jù)元素的存儲位置。則線性表中第i+1個數(shù)據(jù)元素的存儲位置LOC(ai+1)和第i個數(shù)據(jù)元素的存儲位置LOC(ai)之間滿足下列關(guān)系: LOC(ai+1)=LOC(ai)+l 線性表的第i個數(shù)據(jù)元素ai的存儲位置為: LOC(ai)=LOC(a1)+(i-1)*l,在高級語言(如C語言)環(huán)境下:數(shù)組具有隨機(jī)存取的特性,因此,借助數(shù)組來描述順序表。除了用數(shù)組來存儲線性表的元素之外,順序表還應(yīng)該有表示線性表的長度屬性,所以用結(jié)構(gòu)類型來定義順序表類型。 #define OK 1 #define ERROR -1 #define MAX_SIZE 100 typedef int Status ; typedef int ElemType ; typedef struct sqlist ElemType Elem_arrayMAX_SIZE ; int length ; SqList ;,2.2.2 順序表的基本操作,順序存儲結(jié)構(gòu)中,很容易實現(xiàn)線性表的一些操作:初始化、賦值、查找、修改、插入、刪除、求長度等。 以下將對幾種主要的操作進(jìn)行討論。 1 順序線性表初始化 Status Init_SqList( SqList *L ) L-elem_array=( ElemType * )malloc(MAX_SIZE*sizeof( ElemType ) ) ; if ( !L - elem_array ) return ERROR ; else L-length= 0 ; return OK ; ,2 順序線性表的插入 在線性表 L= (a1,a i-1,ai, ai+1,an) 中的第i(1in)個位置上插入一個新結(jié)點e,使其成為線性表: L=(a1,a i-1,e,ai,ai+1,an) 實現(xiàn)步驟 (1) 將線性表L中的第i個至第n個結(jié)點后移一個位置。 (2) 將結(jié)點e插入到結(jié)點ai-1之后。 (3) 線性表長度加1。,算法描述 Status Insert_SqList(Sqlist *L,int i ,ElemType e) int j ; if ( iL-length-1) return ERROR ; if (L-length=MAX_SIZE) printf(“線性表溢出!n”); return ERROR ; for ( j=L-length1; j=i-1; -j ) L-Elem_arrayj+1=L-Elem_arrayj; /* i-1位置以后的所有結(jié)點后移 */ L-Elem_arrayi-1=e; /* 在i-1位置插入結(jié)點 */ L-length+ ; return OK ; ,時間復(fù)雜度分析 在線性表L中的第i個元素之前插入新結(jié)點,其時間主要耗費在表中結(jié)點的移動操作上,因此,可用結(jié)點的移動來估計算法的時間復(fù)雜度。 設(shè)在線性表L中的第i個元素之前插入結(jié)點的概率為Pi,不失一般性,設(shè)各個位置插入是等概率,則Pi=1/(n+1),而插入時移動結(jié)點的次數(shù)為n-i+1。 總的平均移動次數(shù): Einsert=pi*(n-i+1) (1in) Einsert=n/2 。 即在順序表上做插入運算,平均要移動表上一半結(jié)點。當(dāng)表長n較大時,算法的效率相當(dāng)?shù)汀R虼怂惴ǖ钠骄鶗r間復(fù)雜度為O(n)。,3 順序線性表的刪除 在線性表 L=(a1,a i-1,ai, ai+1,an) 中刪除結(jié)點ai(1in),使其成為線性表: L= (a1,ai-1,ai+1,an) 實現(xiàn)步驟 (1) 將線性表L中的第i+1個至第n個結(jié)點依此向前移動一個位置。 (2) 線性表長度減1。 算法描述 ElemType Delete_SqList(Sqlist *L,int i) int k ; ElemType x ;,if (L-length=0) printf(“線性表L為空!n”); return ERROR; else if ( iL-length ) printf(“要刪除的數(shù)據(jù)元素不存在!n”) ; return ERROR ; else x=L-Elem_arrayi-1 ; /*保存結(jié)點的值*/ for ( k=i ; klength ; k+) L-Elem_arrayk-1=L-Elem_arrayk; /* i位置以后的所有結(jié)點前移 */ L-length-; return (x); ,時間復(fù)雜度分析 刪除線性表L中的第i個元素,其時間主要耗費在表中結(jié)點的移動操作上,因此,可用結(jié)點的移動來估計算法的時間復(fù)雜度。 設(shè)在線性表L中刪除第i個元素的概率為Pi,不失一般性,設(shè)刪除各個位置是等概率,則Pi=1/n,而刪除時移動結(jié)點的次數(shù)為n-i。 則總的平均移動次數(shù): Edelete=pi*(n-i) (1in) Edelete=(n-1)/2 。 即在順序表上做刪除運算,平均要移動表上一半結(jié)點。當(dāng)表長n較大時,算法的效率相當(dāng)?shù)汀R虼怂惴ǖ钠骄鶗r間復(fù)雜度為O(n)。,4 順序線性表的查找定位刪除 在線性表 L= (a1,a2,an) 中刪除值為x的第一個結(jié)點。 實現(xiàn)步驟 (1) 在線性表L查找值為x的第一個數(shù)據(jù)元素。 (2) 將從找到的位置至最后一個結(jié)點依次向前移動一個位置。 (3) 線性表長度減1。 算法描述 Status Locate_Delete_SqList(Sqlist *L,ElemType x) /* 刪除線性表L中值為x的第一個結(jié)點 */ int i=0 , k ;,while (ilength) /*查找值為x的第一個結(jié)點*/ if (L-Elem_arrayi!=x ) i+ ; else for ( k=i+1; klength; k+) L-Elem_arrayk-1=L-Elem_arrayk; L-length-; break ; if (iL-length) printf(“要刪除的數(shù)據(jù)元素不存在!n”) ; return ERROR ; return OK; ,時間復(fù)雜度分析 時間主要耗費在數(shù)據(jù)元素的比較和移動操作上。 首先,在線性表L中查找值為x的結(jié)點是否存在; 其次,若值為x的結(jié)點存在,且在線性表L中的位置為i ,則在線性表L中刪除第i個元素。 設(shè)在線性表L刪除數(shù)據(jù)元素概率為Pi,不失一般性,設(shè)各個位置是等概率,則Pi=1/n。 比較的平均次數(shù): Ecompare=pi*i (1in) Ecompare=(n+1)/2 。 刪除時平均移動次數(shù):Edelete=pi*(n-i) (1in) Edelete=(n-1)/2 。 平均時間復(fù)雜度:Ecompare+Edelete=n ,即為O(n),2.3 線性表的鏈?zhǔn)酱鎯?2.3.1 線性表的鏈?zhǔn)酱鎯Y(jié)構(gòu),鏈?zhǔn)酱鎯?:用一組任意的存儲單元存儲線性表中的數(shù)據(jù)元素。用這種方法存儲的線性表簡稱線性鏈表。 存儲鏈表中結(jié)點的一組任意的存儲單元可以是連續(xù)的,也可以是不連續(xù)的,甚至是零散分布在內(nèi)存中的任意位置上的。 鏈表中結(jié)點的邏輯順序和物理順序不一定相同。,為了正確表示結(jié)點間的邏輯關(guān)系,在存儲每個結(jié)點值的同時,還必須存儲指示其直接后繼結(jié)點的地址(或位置),稱為指針(pointer)或鏈(link),這兩部分組成了鏈表中的結(jié)點結(jié)構(gòu),如圖2-2所示。 鏈表是通過每個結(jié)點的指針域?qū)⒕€性表的n個結(jié)點按其邏輯次序鏈接在一起的。 每一個結(jié)只包含一個指針域的鏈表,稱為單鏈表。 為操作方便,總是在鏈表的第一個結(jié)點之前附設(shè)一個頭結(jié)點(頭指針)head指向第一個結(jié)點。頭結(jié)點的數(shù)據(jù)域可以不存儲任何信息(或鏈表長度等信息)。,單鏈表是由表頭唯一確定,因此單鏈表可以用頭指針的名字來命名。 例1、線性表L=(bat,cat,eat,fat,hat) 其帶頭結(jié)點的單鏈表的邏輯狀態(tài)和物理存儲方式如圖2-3所示。,1 結(jié)點的描述與實現(xiàn) C語言中用帶指針的結(jié)構(gòu)體類型來描述 typedef struct Lnode ElemType data; /*數(shù)據(jù)域,保存結(jié)點的值 */ struct Lnode *next; /*指針域*/ LNode; /*結(jié)點的類型 */ 2 結(jié)點的實現(xiàn) 結(jié)點是通過動態(tài)分配和釋放來的實現(xiàn),即需要時分配,不需要時釋放。實現(xiàn)時是分別使用C語言提供的標(biāo)準(zhǔn)函數(shù):malloc() ,realloc(),sizeof() ,free() 。,動態(tài)分配 p=(LNode*)malloc(sizeof(LNode); 函數(shù)malloc分配了一個類型為LNode的結(jié)點變量的空間,并將其首地址放入指針變量p中。 動態(tài)釋放 free(p) ; 系統(tǒng)回收由指針變量p所指向的內(nèi)存區(qū)。P必須是最近一次調(diào)用malloc函數(shù)時的返回值。 3 最常用的基本操作及其示意圖, 結(jié)點的賦值 LNode *p; p=(LNode*)malloc(sizeof(LNode); p-data=20; p-next=NULL ;, 常見的指針操作,2.3.2 單線性鏈?zhǔn)降幕静僮?1 建立單鏈表 假設(shè)線性表中結(jié)點的數(shù)據(jù)類型是整型,以32767作為結(jié)束標(biāo)志。動態(tài)地建立單鏈表的常用方法有如下兩種:頭插入法,尾插入法。 頭插入法建表 從一個空表開始,重復(fù)讀入數(shù)據(jù),生成新結(jié)點,將讀入數(shù)據(jù)存放到新結(jié)點的數(shù)據(jù)域中,然后將新結(jié)點插入到當(dāng)前鏈表的表頭上,直到讀入結(jié)束標(biāo)志為止。即每次插入的結(jié)點都作為鏈表的第一個結(jié)點。,算法描述 LNode *create_LinkList(void) /* 頭插入法創(chuàng)建單鏈表,鏈表的頭結(jié)點head作為返回值 */ int data ; LNode *head, *p; head= (LNode *) malloc( sizeof(LNode); head-next=NULL; /* 創(chuàng)建鏈表的表頭結(jié)點head */ while (1) scanf(“%d”, /* 數(shù)據(jù)域賦值 */,pnext=headnext ; headnext=p ; /* 鉤鏈,新創(chuàng)建的結(jié)點總是作為第一個結(jié)點 */ return (head); (2) 尾插入法建表 頭插入法建立鏈表雖然算法簡單,但生成的鏈表中結(jié)點的次序和輸入的順序相反。若希望二者次序一致,可采用尾插法建表。該方法是將新結(jié)點插入到當(dāng)前鏈表的表尾,使其成為當(dāng)前鏈表的尾結(jié)點。,算法描述 LNode *create_LinkList(void) /* 尾插入法創(chuàng)建單鏈表,鏈表的頭結(jié)點head作為返回值 */ int data ; LNode *head, *p, *q; head=p=(LNode *)malloc(sizeof(LNode); p-next=NULL; /* 創(chuàng)建單鏈表的表頭結(jié)點head */ while (1) scanf(“%d”,/*鉤鏈,新創(chuàng)建的結(jié)點總是作為最后一個結(jié)點*/ return (head); 無論是哪種插入方法,如果要插入建立的單線性鏈表的結(jié)點是n個,算法的時間復(fù)雜度均為O(n)。 對于單鏈表,無論是哪種操作,只要涉及到鉤鏈(或重新鉤鏈),如果沒有明確給出直接后繼,鉤鏈(或重新鉤鏈)的次序必須是“先右后左”。,2 單鏈表的查找 (1) 按序號查找 取單鏈表中的第i個元素。 對于單鏈表,不能象順序表中那樣直接按序號i訪問結(jié)點,而只能從鏈表的頭結(jié)點出發(fā),沿鏈域next逐個結(jié)點往下搜索,直到搜索到第i個結(jié)點為止。因此,鏈表不是隨機(jī)存取結(jié)構(gòu)。 設(shè)單鏈表的長度為n,要查找表中第i個結(jié)點,僅當(dāng)1in時,i的值是合法的。,算法描述 ElemType Get_Elem(LNode *L , int i) int j ; LNode *p; p=L-next; j=1; /* 使p指向第一個結(jié)點 */ while (p!=NULL i1,n:i-1次;in:n次。 時間復(fù)雜度: O(n)。,(2) 按值查找 按值查找是在鏈表中,查找是否有結(jié)點值等于給定值key的結(jié)點? 若有,則返回首次找到的值為key的結(jié)點的存儲位置;否則返回NULL。查找時從開始結(jié)點出發(fā),沿鏈表逐個將結(jié)點的值和給定值key作比較。,算法描述 LNode *Locate_Node(LNode *L,int key) /* 在以L為頭結(jié)點的單鏈表中查找值為key的第一個結(jié)點 */ LNode *p=Lnext; while ( p!=NULL 算法的執(zhí)行與形參key有關(guān),平均時間復(fù)雜度為O(n)。,3 單鏈表的插入 插入運算是將值為e的新結(jié)點插入到表的第i個結(jié)點的位置上,即插入到ai-1與ai之間。因此,必須首先找到ai-1所在的結(jié)點p,然后生成一個數(shù)據(jù)域為e的新結(jié)點q,q結(jié)點作為p的直接后繼結(jié)點。 算法描述 void Insert_LNode(LNode *L,int i,ElemType e) /* 在以L為頭結(jié)點的單鏈表的第i個位置插入值為e的結(jié)點 */ int j=0; LNode *p,*q; p=Lnext ; while ( p!=NULL ,if (j!=i-1) printf(“i太大或i為0!n ”); else q=(LNode *)malloc(sizeof(LNode); qdata=e; qnext=pnext; pnext=q; 設(shè)鏈表的長度為n,合法的插入位置是1in。算法的時間主要耗費移動指針p上,故時間復(fù)雜度亦為O(n)。,4 單鏈表的刪除 按序號刪除 刪除單鏈表中的第i個結(jié)點。 為了刪除第i個結(jié)點ai,必須找到結(jié)點的存儲地址。該存儲地址是在其直接前趨結(jié)點ai-1的next域中,因此,必須首先找到ai-1的存儲位置p,然后令pnext指向ai的直接后繼結(jié)點,即把a(bǔ)i從鏈上摘下。最后釋放結(jié)點ai的空間,將其歸還給“存儲池”。 設(shè)單鏈表長度為n,則刪去第i個結(jié)點僅當(dāng)1in時是合法的。則當(dāng)i=n+1時,雖然被刪結(jié)點不存在,但其前趨結(jié)點卻存在,是終端結(jié)點。故判斷條件之一是pnext!=NULL。顯然此算法的時間復(fù)雜度也是O(n)。,算法描述 void Delete_LinkList(LNode *L, int i) /* 刪除以L為頭結(jié)點的單鏈表中的第i個結(jié)點 */ int j=1; LNode *p,*q; p=L; q=L-next; while ( p-next!=NULL , 按值刪除 刪除單鏈表中值為key的第一個結(jié)點。 與按值查找相類似,首先要查找值為key的結(jié)點是否存在? 若存在,則刪除;否則返回NULL。,算法描述 void Delete_LinkList(LNode *L,int key) /* 刪除以L為頭結(jié)點的單鏈表中值為key的第一個結(jié)點 */ LNode *p=L, *q=Lnext; while ( q!=NULL ,算法的執(zhí)行與形參key有關(guān),平均時間復(fù)雜度為O(n)。 從上面的討論可以看出,鏈表上實現(xiàn)插入和刪除運算,無需移動結(jié)點,僅需修改指針。解決了順序表的插入或刪除操作需要移動大量元素的問題。 變形之一: 刪除單鏈表中值為key的所有結(jié)點。 與按值查找相類似,但比前面的算法更簡單。 基本思想:從單鏈表的第一個結(jié)點開始,對每個結(jié)點進(jìn)行檢查,若結(jié)點的值為key,則刪除之,然后檢查下一個結(jié)點,直到所有的結(jié)點都檢查。,算法描述 void Delete_LinkList_Node(LNode *L,int key) /* 刪除以L為頭結(jié)點的單鏈表中值為key的第一個結(jié)點 */ LNode *p=L, *q=Lnext; while ( q!=NULL) if (qdata=key) p-next=q-next; free(q); q=p-next; else p=q; q=qnext; ,變形之二: 刪除單鏈表中所有值重復(fù)的結(jié)點,使得所有結(jié)點的值都不相同。 與按值查找相類似,但比前面的算法更復(fù)雜。 基本思想:從單鏈表的第一個結(jié)點開始,對每個結(jié)點進(jìn)行檢查:檢查鏈表中該結(jié)點的所有后繼結(jié)點,只要有值和該結(jié)點的值相同,則刪除之;然后檢查下一個結(jié)點,直到所有的結(jié)點都檢查。,算法描述 void Delete_Node_value(LNode *L) /* 刪除以L為頭結(jié)點的單鏈表中所有值相同的結(jié)點 */ LNode *p=L-next, *q, *ptr; while ( p!=NULL) /* 檢查鏈表中所有結(jié)點 */ *q=p, *ptr=pnext; /* 檢查結(jié)點p的所有后繼結(jié)點ptr */ while (ptr!=NULL) if (ptrdata=p-data) q-next=ptr-next; free(ptr); ptr=q-next; else q=ptr; ptr=ptrnext; ,p=p-next ; ,5 單鏈表的合并 設(shè)有兩個有序的單鏈表,它們的頭指針分別是La 、 Lb,將它們合并為以Lc為頭指針的有序鏈表。合并前的示意圖如圖2-4所示。,合并了值為-7,-2的結(jié)點后示意圖如圖2-5所示。,算法說明 算法中pa ,pb分別是待考察的兩個鏈表的當(dāng)前結(jié)點,pc是合并過程中合并的鏈表的最后一個結(jié)點。,算法描述 LNode *Merge_LinkList(LNode *La, LNode *Lb) /* 合并以La, Lb為頭結(jié)點的兩個有序單鏈表 */ LNode *Lc, *pa , *pb , *pc, *ptr ; Lc=La ; pc=La ; pa=La-next ; pb=Lb-next ; while (pa!=NULL /* 將pa所指的結(jié)點合并,pa指向下一個結(jié)點 */,if (pa-data=pb-data) pc-next=pa ; pc=pa ; pa=pa-next ; ptr=pb ; pb=pb-next ; free(ptr) ; /* 將pa所指的結(jié)點合并,pb所指結(jié)點刪除 */ if (pa!=NULL) pc-next=pa ; else pc-next=pb ; /*將剩余的結(jié)點鏈上*/ free(Lb) ; return(Lc) ; 算法分析 若La ,Lb兩個鏈表的長度分別是m,n,則鏈表合并的時間復(fù)雜度為O(m+n) 。,2.3.3 循環(huán)鏈表,循環(huán)鏈表(Circular Linked List):是一種頭尾相接的鏈表。其特點是最后一個結(jié)點的指針域指向鏈表的頭結(jié)點,整個鏈表的指針域鏈接成一個環(huán)。 從循環(huán)鏈表的任意一個結(jié)點出發(fā)都可以找到鏈表中的其它結(jié)點,使得表處理更加方便靈活。 圖2-6是帶頭結(jié)點的單循環(huán)鏈表的示意圖。,空表,循環(huán)鏈表的操作 對于單循環(huán)鏈表,除鏈表的合并外,其它的操作和單線性鏈表基本上一致,僅僅需要在單線性鏈表操作算法基礎(chǔ)上作以下簡單修改: 判斷是否是空鏈表:head-next=head ; 判斷是否是表尾結(jié)點:p-next=head ;,2.4 雙向鏈表,雙向鏈表(Double Linked List) :指的是構(gòu)成鏈表的每個結(jié)點中設(shè)立兩個指針域:一個指向其直接前趨的指針域prior,一個指向其直接后繼的指針域next。這樣形成的鏈表中有兩個方向不同的鏈,故稱為雙向鏈表。 和單鏈表類似,雙向鏈表一般增加頭指針也能使雙鏈表上的某些運算變得方便。 將頭結(jié)點和尾結(jié)點鏈接起來也能構(gòu)成循環(huán)鏈表,并稱之為雙向循環(huán)鏈表。 雙向鏈表是為了克服單鏈表的單向性的缺陷而引入的。,1 雙向鏈表的結(jié)點及其類型定義 雙向鏈表的結(jié)點的類型定義如下。其結(jié)點形式如圖2-7所示,帶頭結(jié)點的雙向鏈表的形式如圖2-8所示。 typedef struct Dulnode ElemType data ; struct Dulnode *prior , *next ; DulNode ;,雙向鏈表結(jié)構(gòu)具有對稱性,設(shè)p指向雙向鏈表中的某一結(jié)點,則其對稱性可用下式描述: (p-prior)-next=p=(p-next)-prior ; 結(jié)點p的存儲位置存放在其直接前趨結(jié)點p-prior的直接后繼指針域中,同時也存放在其直接后繼結(jié)點p-next的直接前趨指針域中。 2 雙向鏈表的基本操作 (1) 雙向鏈表的插入 將值為e的結(jié)點插入雙向鏈表中。插入前后鏈表的變化如圖2-9所示。, 插入時僅僅指出直接前驅(qū)結(jié)點,鉤鏈時必須注意先后次序是: “先右后左” 。部分語句組如下: S=(DulNode *)malloc(sizeof(DulNode); S-data=e; S-next=p-next; p-next-prior=S; p-next=S; S-prior=p; /* 鉤鏈次序非常重要 */ 插入時同時指出直接前驅(qū)結(jié)點p和直接后繼結(jié)點q,鉤鏈時無須注意先后次序。部分語句組如下: S=(DulNode *)malloc(sizeof(DulNode); S-data=e; p-next=S; S-next=q; S-prior=p; q-prior=S;,(2) 雙向鏈表的結(jié)點刪除 設(shè)要刪除的結(jié)點為p ,刪除時可以不引入新的輔助指針變量,可以直接先斷鏈,再釋放結(jié)點。部分語句組如下: p-prior-next=p-next; p-next-prior=p-prior; free(p); 注意: 與單鏈表的插入和刪除操作不同的是,在雙向鏈表中插入和刪除必須同時修改兩個方向上的指針域的指向。,2.5 一元多項式的表示和相加,1 一元多項式的表示 一元多項式 p(x)=p0+p1x+p2x2+ +pnxn ,由n+1個系數(shù)唯一確定。則在計算機(jī)中可用線性表(p0 ,p1 ,p2 , ,pn )表示。既然是線性表,就可以用順序表和鏈表來實現(xiàn)。兩種不同實現(xiàn)方式的元素類型定義如下:,(1) 順序存儲表示的類型 typedef struct float coef; /*系數(shù)部分*/ int expn; /*指數(shù)部分*/ ElemType ;,(2) 鏈?zhǔn)酱鎯Ρ硎镜念愋?typedef struct ploy float coef ; /*系數(shù)部分*/ int expn ; /*指數(shù)部分*/ struct ploy *next ; Ploy ;,2 一元多項式的相加 不失一般性,設(shè)有兩個一元多項式: P(x)=p0+p1x+p2x2+ +pnxn , Q(x)=q0+q1x+q2x2+ +qmxm (m<n) R(x)=P(x)+ Q(x) R(x)由線性表R(p0+q0) ,(p1+q1) ,(p2+q2) , ,(pm+qm) , , pn)唯一表示。, 順序存儲表示的相加 線性表的定義 typedef struct ElemType aMAX_SIZE ; int length ; Sqlist ; 用順序表示的相加非常簡單。訪問第5項可直接訪問:L.a4.coef , L.a4.expn (2) 鏈?zhǔn)酱鎯Ρ硎镜南嗉?當(dāng)采用鏈?zhǔn)酱鎯Ρ硎緯r,根據(jù)結(jié)點類型定義,凡是系數(shù)為0的項不在鏈表中出現(xiàn),從而可以大大減少鏈表的長度。,一元多項式相加的實質(zhì)是: 指數(shù)不同: 是鏈表的合并。 指數(shù)相同: 系數(shù)相加,和為0,去掉結(jié)點,和不為0,修改結(jié)點的系數(shù)域。 算法之一: 就在原來兩個多項式鏈表的基礎(chǔ)上進(jìn)行相加,相加后原來兩個多項式鏈表就不在存在。當(dāng)然再要對原來兩個多項式進(jìn)行其它操作就不允許了。,算法描述 Ploy *add_ploy(ploy *La, ploy *Lb) /* 將以La ,Lb為頭指針表示的一元多項式相加 */ ploy *Lc , *pc , *pa , *pb ,*ptr ; float x ; Lc=pc=La ; pa=La-next ; pb=Lb-next ; while (pa!=NULL /* 將pb所指的結(jié)點合并,pb指向下一個結(jié)點 */,else x=pa-coef+pb-coef ; if (abs(x)next ; free(ptr) ; ptr=pb ; pb=pb-next ; free(ptr) ; else /* 如果系數(shù)和不為0,修改其中一個結(jié)點的系數(shù)域,刪除另一個結(jié)點 */ pc-next=pa ; pa-coef=x ; pc=pa ; pa=pa-next ; ptr=pb ; pb=pb-next ; free(pb) ; , /* end of while */ if (pa=NULL) pc-next=pb ; else pc-next=pa ; return (Lc) ; ,算法之二: 對兩個多項式鏈表進(jìn)行相加,生成一個新的相加后的結(jié)果多項式鏈表,原來兩個多項式鏈表依然存在,不發(fā)生任何改變,如果要再對原來兩個多項式進(jìn)行其它操作也不影響。,算法描述 Ploy *add_ploy(ploy *La, ploy *Lb) /* 將以La ,Lb為頭指針表示的一元多項式相加,生成一個新的結(jié)果多項式 */ ploy *Lc , *pc , *pa , *pb , *p ; float x ; Lc=pc=(ploy *)malloc(sizeof(ploy) ; pa=La-next ; pb=Lb-next ; while (pa!=NULL,/* 生成一個新的結(jié)果結(jié)點并賦值 */ pc-next=p ; pc=p ; pa=pa-next ; /* 生成的結(jié)點插入到結(jié)果鏈表的最后,pa指向下一個結(jié)點 */ if (pa-expnpb-expn) p=(ploy *)malloc(sizeof(ploy) ; p-coef=pb-coef ; p-expn=pb-expn ; p-next=NULL ; /* 生成一個新的結(jié)果結(jié)點并賦值 */ pc-next=p ; pc=p ; pb=pb-next ; /* 生成的結(jié)點插入到結(jié)果鏈表的最后,pb指向下一個結(jié)點 */,if (pa-expn=pb-expn) x=pa-coef+pb-coef ; if (abs(x)next ; pb=pb-next ; else /* 若系數(shù)和不為0,生成的結(jié)點插入到結(jié)果鏈表的最后, pa, pb分別直接后繼結(jié)點 */ p=(ploy *)malloc(sizeof(ploy) ; p-coef=x ; p-expn=pb-expn ; p-next=NULL ; /* 生成一個新的結(jié)果結(jié)點并賦值 */ pc-next=p ; pc=p ; pa=pa-next ; pb=pb-next ;, /* end of while */ if (pb!=NULL) while(pb!=NULL) p=(ploy *)malloc(sizeof(ploy) ; p-coef=pb-coef ; p-expn=pb-expn ; p-next=NULL ; /* 生成一個新的結(jié)果結(jié)點并賦值 */ pc-next=p ; pc=p ; pb=pb-next ; ,if (pa!=NULL) while(pa!=NULL) p=(ploy *)malloc(sizeof(ploy) ; p-coef=pb-coef ; p-expn=pa-expn ; p-next=NULL ; /* 生成一個新的結(jié)果結(jié)點并賦值 */ pc-next=p ; pc=p ; pa=pa-next ; return (Lc) ; ,習(xí) 題 二,1 簡述下列術(shù)語:線性表,順序表,鏈表。 2 何時選用順序表,何時選用鏈表作為線性表的存儲結(jié)構(gòu)合適?各自的主要優(yōu)缺點是什么? 3 在順序表中插入和刪除一個結(jié)點平均需要移動多少個結(jié)點?具體的移動次數(shù)取決于哪兩個因素? 4 鏈表所表示的元素是否有序?如有序,則有序性體現(xiàn)于何處?鏈表所表示的元素是否一定要在物理上是相鄰的?有序表的有序性又如何理解? 5 設(shè)順序表L是遞增有序表,試寫一算法,將x插入到L中并使L仍是遞增有序表。,6 寫一求單鏈表的結(jié)點數(shù)目ListLength(L)的算法。 7 寫一算法將單鏈表中值重復(fù)的結(jié)點刪除,使所得的結(jié)果鏈表中所有結(jié)點的值均不相同。 8 寫一算法從一給定的向量A刪除值在x到y(tǒng)(xy)之間的所有元素(注意:x和y是給定的參數(shù),可以和表中的元素相同,也可以不同)。 9 設(shè)A和B是兩個按元素值遞增有序的單鏈表,寫一算法將A和B歸并為按按元素值遞減有序的單鏈表C,試分析算法的時間復(fù)雜度。,第3章 棧和隊列,棧和隊列是兩種應(yīng)用非常廣泛的數(shù)據(jù)結(jié)構(gòu),它們都來自線性表數(shù)據(jù)結(jié)構(gòu),都是“操作受限”的線性表。 棧在計算機(jī)的實現(xiàn)有多種方式: 硬堆棧:利用CPU中的某些寄存器組或類似的硬件或使用內(nèi)存的特殊區(qū)域來實現(xiàn)。這類堆棧容量有限,但速度很快; 軟堆棧:這類堆棧主要在內(nèi)存中實現(xiàn)。堆棧容量可以達(dá)到很大。在實現(xiàn)方式上,又有動態(tài)方式和靜態(tài)方式兩種。 本章將討論棧和隊列的基本概念、存儲結(jié)構(gòu)、基本操作以及這些操作的具體實現(xiàn)。,3.1 棧,3.1.1 棧的基本概念,1 棧的概念 棧(Stack):是限制在表的一端進(jìn)行插入和刪除操作的線性表。又稱為后進(jìn)先出LIFO (Last In First Out)或先進(jìn)后出FILO (First In Last Out)線性表。 棧頂(Top):允許進(jìn)行插入、刪除操作的一端,又稱為表尾。用棧頂指針(top)來指示棧頂元素。 棧底(Bottom):是固定端,又稱為表頭。 空棧:當(dāng)表中沒有元素時稱為空棧。,設(shè)棧S=(a1,a2,an),則a1稱為棧底元素,an為棧頂元素,如圖3-1所示。 棧中元素按a1,a2,an的次序進(jìn)棧,退棧的第一個元素應(yīng)為棧頂元素。即棧的修改是按后進(jìn)先出的原則進(jìn)行的。,2 棧的抽象數(shù)據(jù)類型定義 ADT Stack 數(shù)據(jù)對象:D = ai|aiElemSet, i=1,2,n,n0 數(shù)據(jù)關(guān)系:R =|ai-1,aiD, i=2,3,n 基本操作:初始化、進(jìn)棧、出棧、取棧頂元素等 ADT Stack,棧的順序存儲結(jié)構(gòu)簡稱為順序棧,和線性表相類似,用一維數(shù)組來存儲棧。根據(jù)數(shù)組是否可以根據(jù)需要增大,又可分為靜態(tài)順序棧和動態(tài)順序棧。 靜態(tài)順序棧實現(xiàn)簡單,但不能根據(jù)需要增大棧的存儲空間; 動態(tài)順序??梢愿鶕?jù)需要增大棧的存儲空間,但實現(xiàn)稍為復(fù)雜。,3.1.2 棧的順序存儲表示,采用動態(tài)一維數(shù)組來存儲棧。所謂動態(tài),指的是棧的大小可以根據(jù)需要增加。 用bottom表示棧底指針,棧底固定不變的;棧頂則隨著進(jìn)棧和退棧操作而變化。用top(稱為棧頂指針)指示當(dāng)前棧頂位置

注意事項

本文(《數(shù)據(jù)結(jié)構(gòu)嚴(yán)蔚敏》PPT課件)為本站會員(san****019)主動上傳,裝配圖網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對上載內(nèi)容本身不做任何修改或編輯。 若此文所含內(nèi)容侵犯了您的版權(quán)或隱私,請立即通知裝配圖網(wǎng)(點擊聯(lián)系客服),我們立即給予刪除!

溫馨提示:如果因為網(wǎng)速或其他原因下載失敗請重新下載,重復(fù)下載不扣分。




關(guān)于我們 - 網(wǎng)站聲明 - 網(wǎng)站地圖 - 資源地圖 - 友情鏈接 - 網(wǎng)站客服 - 聯(lián)系我們

copyright@ 2023-2025  zhuangpeitu.com 裝配圖網(wǎng)版權(quán)所有   聯(lián)系電話:18123376007

備案號:ICP2024067431-1 川公網(wǎng)安備51140202000466號


本站為文檔C2C交易模式,即用戶上傳的文檔直接被用戶下載,本站只是中間服務(wù)平臺,本站所有文檔下載所得的收益歸上傳人(含作者)所有。裝配圖網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對上載內(nèi)容本身不做任何修改或編輯。若文檔所含內(nèi)容侵犯了您的版權(quán)或隱私,請立即通知裝配圖網(wǎng),我們立即給予刪除!