線性表的鏈?zhǔn)奖硎竞蛯?shí)現(xiàn)_第1頁(yè)
線性表的鏈?zhǔn)奖硎竞蛯?shí)現(xiàn)_第2頁(yè)
線性表的鏈?zhǔn)奖硎竞蛯?shí)現(xiàn)_第3頁(yè)
線性表的鏈?zhǔn)奖硎竞蛯?shí)現(xiàn)_第4頁(yè)
線性表的鏈?zhǔn)奖硎竞蛯?shí)現(xiàn)_第5頁(yè)
已閱讀5頁(yè),還剩41頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、1第第2 2章章 線性表線性表22.3 2.3 線性表的鏈?zhǔn)奖硎竞蛯?shí)現(xiàn)線性表的鏈?zhǔn)奖硎竞蛯?shí)現(xiàn)3 鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)特點(diǎn):鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)特點(diǎn):其結(jié)點(diǎn)在存儲(chǔ)器中的位置是隨意的,即邏輯上其結(jié)點(diǎn)在存儲(chǔ)器中的位置是隨意的,即邏輯上相鄰的數(shù)據(jù)元素在物理上不一定相鄰。相鄰的數(shù)據(jù)元素在物理上不一定相鄰。如何實(shí)現(xiàn)? 通過(guò)來(lái)實(shí)現(xiàn)!讓每個(gè)存儲(chǔ)結(jié)點(diǎn)都包含兩部分:讓每個(gè)存儲(chǔ)結(jié)點(diǎn)都包含兩部分:數(shù)據(jù)域數(shù)據(jù)域和和指針域指針域指針指針數(shù)據(jù)數(shù)據(jù)指針指針指針指針或或樣式:樣式:數(shù)據(jù)域:數(shù)據(jù)域:存儲(chǔ)存儲(chǔ)元素?cái)?shù)值數(shù)據(jù)元素?cái)?shù)值數(shù)據(jù)指針域:指針域:存儲(chǔ)直接后繼或存儲(chǔ)直接后繼或者直接前驅(qū)的存儲(chǔ)位置者直接前驅(qū)的存儲(chǔ)位置2.3.1 2.3.1 鏈表的表

2、示鏈表的表示4鏈表存放示意圖如下: a1heada2/an討論討論1 1:每個(gè)存儲(chǔ)結(jié)點(diǎn)都包含兩部分:數(shù)據(jù)域和每個(gè)存儲(chǔ)結(jié)點(diǎn)都包含兩部分:數(shù)據(jù)域和討論討論2 2:在單鏈表中,除了首元結(jié)點(diǎn)外,任一結(jié)點(diǎn)的在單鏈表中,除了首元結(jié)點(diǎn)外,任一結(jié)點(diǎn)的存儲(chǔ)位置由存儲(chǔ)位置由 指示。指示。 其直接前驅(qū)結(jié)點(diǎn)的鏈域的值其直接前驅(qū)結(jié)點(diǎn)的鏈域的值(2) (2) 與鏈?zhǔn)酱鎯?chǔ)有關(guān)的術(shù)語(yǔ)與鏈?zhǔn)酱鎯?chǔ)有關(guān)的術(shù)語(yǔ):1 1)結(jié)點(diǎn))結(jié)點(diǎn):數(shù)據(jù)元素的存儲(chǔ)映像。由數(shù)據(jù)域和指針域兩數(shù)據(jù)元素的存儲(chǔ)映像。由數(shù)據(jù)域和指針域兩部分組成;部分組成;2 2)鏈表)鏈表: n n 個(gè)結(jié)點(diǎn)由個(gè)結(jié)點(diǎn)由指針鏈指針鏈組成一個(gè)鏈表。它是線性組成一個(gè)鏈表。它是線性表的鏈

3、式存儲(chǔ)映像表的鏈?zhǔn)酱鎯?chǔ)映像,稱為線性表的鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)稱為線性表的鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)。只包含一個(gè)指針域的稱為單鏈表或線性鏈表只包含一個(gè)指針域的稱為單鏈表或線性鏈表指針域指針域53 3)頭指針、頭結(jié)點(diǎn)和首元結(jié)點(diǎn)的區(qū)別)頭指針、頭結(jié)點(diǎn)和首元結(jié)點(diǎn)的區(qū)別頭指針頭指針頭結(jié)點(diǎn)頭結(jié)點(diǎn)首元結(jié)點(diǎn)首元結(jié)點(diǎn)a1heada2infoan首元結(jié)點(diǎn)首元結(jié)點(diǎn)是指鏈表中存儲(chǔ)線性表第一個(gè)數(shù)據(jù)元素是指鏈表中存儲(chǔ)線性表第一個(gè)數(shù)據(jù)元素a a1 1的的結(jié)點(diǎn)。結(jié)點(diǎn)。頭結(jié)點(diǎn)頭結(jié)點(diǎn)是在鏈表的首元結(jié)點(diǎn)之前是在鏈表的首元結(jié)點(diǎn)之前附設(shè)附設(shè)的一個(gè)結(jié)點(diǎn);數(shù)的一個(gè)結(jié)點(diǎn);數(shù)據(jù)域內(nèi)只放空表標(biāo)志和表長(zhǎng)等信息,它不計(jì)入據(jù)域內(nèi)只放空表標(biāo)志和表長(zhǎng)等信息,它不計(jì)入表長(zhǎng)度。表

4、長(zhǎng)度。頭指針頭指針是指向鏈表中第一個(gè)結(jié)點(diǎn)(或?yàn)轭^結(jié)點(diǎn)、或?yàn)槭侵赶蜴湵碇械谝粋€(gè)結(jié)點(diǎn)(或?yàn)轭^結(jié)點(diǎn)、或?yàn)槭自Y(jié)點(diǎn))的指針;首元結(jié)點(diǎn))的指針;示意圖如下:示意圖如下:6討論討論2 2: 在鏈表中設(shè)置在鏈表中設(shè)置頭結(jié)點(diǎn)頭結(jié)點(diǎn)有什么好處?有什么好處?討論討論1 1: 如何表示如何表示空表空表?因?yàn)槿魏谓Y(jié)點(diǎn)都有前驅(qū)結(jié)點(diǎn),而在做插入和刪除操因?yàn)槿魏谓Y(jié)點(diǎn)都有前驅(qū)結(jié)點(diǎn),而在做插入和刪除操作時(shí),都需修改其前驅(qū)結(jié)點(diǎn)的指針域,作時(shí),都需修改其前驅(qū)結(jié)點(diǎn)的指針域,因此對(duì)首元結(jié)點(diǎn)因此對(duì)首元結(jié)點(diǎn)可以統(tǒng)一處理。即簡(jiǎn)化插入和刪除操作;可以統(tǒng)一處理。即簡(jiǎn)化插入和刪除操作;表頭指針是指向頭結(jié)點(diǎn)的非空指針,因此空表和非表頭指針是指向頭結(jié)

5、點(diǎn)的非空指針,因此空表和非空表的處理一樣??毡淼奶幚硪粯?。無(wú)頭結(jié)點(diǎn)時(shí),當(dāng)無(wú)頭結(jié)點(diǎn)時(shí),當(dāng)頭指針頭指針的值為的值為空空時(shí)表示空表;時(shí)表示空表;頭指針頭指針無(wú)頭結(jié)點(diǎn)無(wú)頭結(jié)點(diǎn)頭指針頭指針頭結(jié)點(diǎn)頭結(jié)點(diǎn)有頭結(jié)點(diǎn)有頭結(jié)點(diǎn)有頭結(jié)點(diǎn)時(shí),當(dāng)有頭結(jié)點(diǎn)時(shí),當(dāng)頭結(jié)點(diǎn)頭結(jié)點(diǎn)的的指針域?yàn)榭罩羔樣驗(yàn)榭諘r(shí)表示空表。時(shí)表示空表。7一個(gè)線性表的邏輯結(jié)構(gòu)為:一個(gè)線性表的邏輯結(jié)構(gòu)為:(ZHAO,QIAN,SUN,LI,ZHOU,WU,ZHENG,WANGZHAO,QIAN,SUN,LI,ZHOU,WU,ZHENG,WANG),其存),其存儲(chǔ)結(jié)構(gòu)用儲(chǔ)結(jié)構(gòu)用單鏈表單鏈表表示如下,表示如下,請(qǐng)問(wèn)其請(qǐng)問(wèn)其頭指針的值頭指針的值是多少?是多少?存

6、儲(chǔ)地址存儲(chǔ)地址數(shù)據(jù)域數(shù)據(jù)域指針域指針域1LI437QIAN1313SUN119WANGNULL25WU3731ZHAO737ZHENG1943ZHOU25答:答:頭指針頭指針是指向鏈表是指向鏈表中中第一個(gè)第一個(gè)結(jié)點(diǎn)的指針,結(jié)點(diǎn)的指針,因此關(guān)鍵是要尋找因此關(guān)鍵是要尋找第一第一個(gè)結(jié)點(diǎn)的地址。個(gè)結(jié)點(diǎn)的地址。7ZHAOH31稱:頭指針?lè)Q:頭指針H的值是的值是31(3 3)舉例)舉例例例1:8 現(xiàn)有一個(gè)具有五個(gè)元素的線性表現(xiàn)有一個(gè)具有五個(gè)元素的線性表L=23L=23,1717,4747,0505,3131,若它以鏈接方式存儲(chǔ)在下列若它以鏈接方式存儲(chǔ)在下列100100119119號(hào)地號(hào)地址址空間中,每個(gè)結(jié)

7、點(diǎn)由數(shù)據(jù)(占空間中,每個(gè)結(jié)點(diǎn)由數(shù)據(jù)(占2 2個(gè)字節(jié)個(gè)字節(jié))和指針)和指針(占(占2 2個(gè)字節(jié)個(gè)字節(jié))組成,如下圖所示。)組成,如下圖所示。其中指針其中指針X X,Y Y,Z Z的值分別為多少?該線性表的首結(jié)的值分別為多少?該線性表的首結(jié)點(diǎn)起始地址為多少?末結(jié)點(diǎn)的起始地址為多少?點(diǎn)起始地址為多少?末結(jié)點(diǎn)的起始地址為多少?答:答:X=X= Y= Y= Z= Z= , , 首址首址= = 末址末址= = 。例例2 2:9討論討論: : 鏈表的數(shù)據(jù)元素有鏈表的數(shù)據(jù)元素有兩個(gè)域兩個(gè)域,不再是簡(jiǎn)單數(shù)據(jù),不再是簡(jiǎn)單數(shù)據(jù)類型,編程時(shí)該如何表示?類型,編程時(shí)該如何表示?因每個(gè)結(jié)點(diǎn)至少有兩個(gè)分量,且數(shù)據(jù)類型通常不

8、因每個(gè)結(jié)點(diǎn)至少有兩個(gè)分量,且數(shù)據(jù)類型通常不一致,所以要采用一致,所以要采用結(jié)構(gòu)結(jié)構(gòu)數(shù)據(jù)類型。數(shù)據(jù)類型。答:答:設(shè)每個(gè)結(jié)點(diǎn)用變量設(shè)每個(gè)結(jié)點(diǎn)用變量表示,表示,其指針用其指針用 表示,兩個(gè)分量分表示,兩個(gè)分量分別用別用和和表示,這兩表示,這兩個(gè)分量如何賦值?個(gè)分量如何賦值?p方式方式1: 直接表示為直接表示為 node.data;node.next=方式方式2:p指向結(jié)點(diǎn)首地址指向結(jié)點(diǎn)首地址 p-data=; p-next= ; 方式方式3:p指向結(jié)點(diǎn)首地址指向結(jié)點(diǎn)首地址 (*p).data=; (*p).next10單鏈表的抽象數(shù)據(jù)類型描述如下單鏈表的抽象數(shù)據(jù)類型描述如下(參見(jiàn)教材(參見(jiàn)教材P28

9、P28):typedef struct LNode ElemType data; /數(shù)據(jù)域 struct LNode *next; /指針域LNode, *LinkList; / *LinkList為L(zhǎng)node類型的指針Q1Q1:第一行的第一行的LNodeLNode 與最后一行的與最后一行的LNodeLNode是不是一回事?是不是一回事?A1A1:不是。前者不是。前者LNodeLNode是結(jié)構(gòu)名,后者是結(jié)構(gòu)名,后者LNodeLNode是對(duì)整個(gè)是對(duì)整個(gè)structstruct類型的一種類型的一種“縮寫縮寫”,是一種,是一種“新定義名新定義名”,它只,它只是對(duì)現(xiàn)有類型名的補(bǔ)充,而不是取代。是對(duì)現(xiàn)有

10、類型名的補(bǔ)充,而不是取代。這就是我們?cè)趶?fù)習(xí)這就是我們?cè)趶?fù)習(xí)c語(yǔ)言時(shí)講的語(yǔ)言時(shí)講的自引用結(jié)構(gòu)自引用結(jié)構(gòu)11Q2Q2: 那為何兩處要同名那為何兩處要同名( (LNodeLNode和和LNodeLNode)?太不嚴(yán)謹(jǐn))?太不嚴(yán)謹(jǐn)了吧?了吧?A2A2:同名是為了表述起來(lái)方便。因?yàn)槊枋龅膶?duì)象相同,同名是為了表述起來(lái)方便。因?yàn)槊枋龅膶?duì)象相同,方便閱讀和理解。方便閱讀和理解。Q3Q3:結(jié)構(gòu)體中間的那個(gè):結(jié)構(gòu)體中間的那個(gè)structstruct LNodeLNode是何意?是何意?A3A3:在:在“縮寫縮寫” LNodeLNode還沒(méi)出現(xiàn)之前,只能用原始的還沒(méi)出現(xiàn)之前,只能用原始的struct LNodest

11、ruct LNode來(lái)進(jìn)行變量說(shuō)明。此處說(shuō)明了指針?lè)至縼?lái)進(jìn)行變量說(shuō)明。此處說(shuō)明了指針?lè)至康臄?shù)據(jù)類型是的數(shù)據(jù)類型是struct LNodestruct LNode。返返 回回122.3.2 2.3.2 鏈表的實(shí)現(xiàn)鏈表的實(shí)現(xiàn)13(1 1) 單鏈表的存取單鏈表的存取思路:思路:要存取第要存取第i i個(gè)數(shù)據(jù)元素,必須從頭指針起一直找到個(gè)數(shù)據(jù)元素,必須從頭指針起一直找到該結(jié)點(diǎn)的指針該結(jié)點(diǎn)的指針p p,然后才能執(zhí)行,然后才能執(zhí)行 p-data=new_value p-data=new_value 。訪問(wèn)第訪問(wèn)第i i個(gè)數(shù)據(jù)元素的操作函數(shù)可寫為:個(gè)數(shù)據(jù)元素的操作函數(shù)可寫為:Status GetElem_L(

12、LinkList L, int i, ElemType e)p=L-next; j=1; /帶頭結(jié)點(diǎn)的鏈表while(p&jnext; +j;if ( !p ji ) return ERROR; /i不合法p-data =e; /若是讀取則為:e=p-data; return OK;/ GetElem_L缺點(diǎn):缺點(diǎn):想尋找單鏈表中第想尋找單鏈表中第i i個(gè)元素,只能從頭指針開(kāi)個(gè)元素,只能從頭指針開(kāi)始逐一查詢(始逐一查詢(順藤摸瓜順藤摸瓜),無(wú)法隨機(jī)存?。?,無(wú)法隨機(jī)存取 。14在鏈表中第在鏈表中第i i個(gè)位置前插入一個(gè)元素個(gè)位置前插入一個(gè)元素x 的示意圖如下:的示意圖如下:X Xsai-

13、1aip鏈表插入的核心語(yǔ)句:鏈表插入的核心語(yǔ)句:p-nexts-nextX 結(jié)點(diǎn)的生成方式:結(jié)點(diǎn)的生成方式:s=(Lnode*)malloc(m);s-data= x ;s-next= ?aiai-1pX X (2 2) 單鏈表的插入單鏈表的插入(重點(diǎn))重點(diǎn))15 Status ListInsert_L(LinkList L, int i, ElemType e) / LinstInsert_L算法的時(shí)間復(fù)雜度為算法的時(shí)間復(fù)雜度為: :O(ListLength(L)p = L; j = 0;while (p & j next; +j; / 尋找第 i-1 個(gè)結(jié)點(diǎn)if (!p | j i

14、-1) return ERROR; /i不合法 s = (LinkList)malloc(sizeof(LNode) s-data = e; s-next = p-next; p-next = s; / / 插入插入return OK;16在鏈表中刪除某元素在鏈表中刪除某元素ai的示意圖如下:的示意圖如下:ai+1 ai-1 aip刪除動(dòng)作的核心語(yǔ)句(要借助輔助指針變量刪除動(dòng)作的核心語(yǔ)句(要借助輔助指針變量q q):):q = p-next; /首先保存首先保存a ai i的指針,靠它才能找到的指針,靠它才能找到a ai+1i+1 p-next(p-next) - nextq(3 3) 單鏈表

15、的刪除單鏈表的刪除(重點(diǎn))重點(diǎn))p-next=q-next;/將將a ai-1i-1與與a ai+1i+1兩結(jié)點(diǎn)相連兩結(jié)點(diǎn)相連, ,淘汰淘汰a ai i結(jié)點(diǎn)結(jié)點(diǎn)free(q); 17 Status ListDelete_L(LinkList L, int i, ElemType &e) / 刪除以 L 為頭指針(帶頭結(jié)點(diǎn))的單鏈表中第 i 個(gè)結(jié)點(diǎn) / ListDelete_L算法的時(shí)間復(fù)雜度為算法的時(shí)間復(fù)雜度為: :O(ListLength(L)p = L; j = 0;while (p-next & j next; +j; / 尋找第 i 個(gè)結(jié)點(diǎn),并令 p 指向其前趨if (

16、!(p-next) | j i-1) return ERROR; / 刪除位置不合理q = p-next; p-next = q-next; /刪除并釋放結(jié)點(diǎn) e = q-data; free(q);return OK;18空間效率分析空間效率分析鏈表中每個(gè)結(jié)點(diǎn)都要增加一個(gè)指針空間,相當(dāng)于總鏈表中每個(gè)結(jié)點(diǎn)都要增加一個(gè)指針空間,相當(dāng)于總共增加了共增加了n n 個(gè)整型變量,空間復(fù)雜度為個(gè)整型變量,空間復(fù)雜度為 O(n)O(n)。在在n n個(gè)結(jié)點(diǎn)的單鏈表中要?jiǎng)h除已知結(jié)點(diǎn)個(gè)結(jié)點(diǎn)的單鏈表中要?jiǎng)h除已知結(jié)點(diǎn)* *P P,需找到它,需找到它的的 ,其時(shí)間復(fù)雜度,其時(shí)間復(fù)雜度 。 O(n)O(n)練習(xí):練習(xí):1

17、9操作步驟:操作步驟:一、建立一個(gè)一、建立一個(gè)“空表空表”;二、輸入數(shù)據(jù)元素二、輸入數(shù)據(jù)元素a an n, 建立結(jié)點(diǎn)并插入;建立結(jié)點(diǎn)并插入;三、輸入數(shù)據(jù)元素三、輸入數(shù)據(jù)元素a an-1n-1, 建立結(jié)點(diǎn)并插入表頭;建立結(jié)點(diǎn)并插入表頭;ananan-1四、依次類推,直至輸入四、依次類推,直至輸入a a1 1為止為止。(4 4)單鏈表的建立)單鏈表的建立例如:例如:頭插法頭插法輸入輸入 n n 個(gè)數(shù)據(jù)元素的值,建立帶頭結(jié)個(gè)數(shù)據(jù)元素的值,建立帶頭結(jié)點(diǎn)的單鏈表。點(diǎn)的單鏈表。鏈表是一個(gè)動(dòng)態(tài)的結(jié)構(gòu),它不需要預(yù)先分配空間,因鏈表是一個(gè)動(dòng)態(tài)的結(jié)構(gòu),它不需要預(yù)先分配空間,因此生成鏈表的過(guò)程是一個(gè)結(jié)點(diǎn)此生成鏈表的

18、過(guò)程是一個(gè)結(jié)點(diǎn)“逐個(gè)插入逐個(gè)插入” ” 的過(guò)程。的過(guò)程。頭插法建表頭插法建表該方法從一個(gè)空表開(kāi)始,重復(fù)讀入數(shù)據(jù),生成新結(jié)該方法從一個(gè)空表開(kāi)始,重復(fù)讀入數(shù)據(jù),生成新結(jié)點(diǎn),將讀入數(shù)據(jù)存放到新結(jié)點(diǎn)的數(shù)據(jù)域中,然后點(diǎn),將讀入數(shù)據(jù)存放到新結(jié)點(diǎn)的數(shù)據(jù)域中,然后將將新結(jié)點(diǎn)插入到當(dāng)前鏈表的表頭上新結(jié)點(diǎn)插入到當(dāng)前鏈表的表頭上,直到讀入結(jié)束標(biāo),直到讀入結(jié)束標(biāo)志為止。志為止。執(zhí) 行 的 語(yǔ) 句 組 為 :s next L next; L next s;L(a) 建空表c1ss 指向新申請(qǐng)的結(jié)點(diǎn)s data c1(b) 申請(qǐng)新結(jié)點(diǎn)并賦值Lci 1s(c) 插入第一個(gè)結(jié)點(diǎn)Lc2c1cic1s(d) 插入第i個(gè)元素21v

19、oid CreateList_L(LinkList &L, int n) / 頭插法建立帶頭結(jié)點(diǎn)的單鏈表 / CreateList_L算法的時(shí)間復(fù)雜度算法的時(shí)間復(fù)雜度為:O(Listlength(L)L = (LinkList) malloc (sizeof (LNode);L-next = NULL; / 先建立一個(gè)帶頭結(jié)點(diǎn)的單鏈表for (i = n; i 0; -i) s = (LinkList) malloc (sizeof (LNode); scanf(&s-data); / 輸入元素值 s-next = L-next; L-next = s; / 插入尾插法建表尾插

20、法建表該方法是將新結(jié)點(diǎn)插入到當(dāng)前鏈表的表尾上,為此該方法是將新結(jié)點(diǎn)插入到當(dāng)前鏈表的表尾上,為此必須必須增加一個(gè)尾指針增加一個(gè)尾指針r,使其始終指向當(dāng)前鏈表的尾,使其始終指向當(dāng)前鏈表的尾結(jié)點(diǎn)結(jié)點(diǎn)rs;r始終指向單鏈表的表尾L(a) 建空表c1ss 指向新申請(qǐng)的結(jié)點(diǎn)空間sdatac1(b) 申請(qǐng)新結(jié)點(diǎn)并賦值Lc1s(c) 插入第一個(gè)結(jié)點(diǎn)Lc2c1rrr nexts;(d) 插入第二個(gè)結(jié)點(diǎn)sr尾插法尾插法建表建表 void CreateList_L(LinkList &L, int n) tail = L = (LinkList) malloc( sizeof (LNode) );/尾指針初

21、始化為表頭指針尾指針初始化為表頭指針 L-next = NULL; for( i=n; i0; -i) s = (LinkList) malloc( sizeof (LNode) ); scanf( &s-data); s-next = NULL; tail-next = s; tail = s; 24算法要求:算法要求:已知:已知:線性表線性表 A A和和B B,分別由單鏈表分別由單鏈表 LaLa和和Lb Lb 存儲(chǔ)存儲(chǔ),其中,其中數(shù)據(jù)元素按值非遞減有序排列(即已經(jīng)有序);數(shù)據(jù)元素按值非遞減有序排列(即已經(jīng)有序);要求:要求:將將A A和和B B歸并為一個(gè)新的線性表歸并為一個(gè)新的線性

22、表C , CC , C的數(shù)據(jù)元素仍的數(shù)據(jù)元素仍按值非遞減排列。設(shè)線性表按值非遞減排列。設(shè)線性表C C由單鏈表由單鏈表 Lc Lc 存儲(chǔ)。存儲(chǔ)。假設(shè):假設(shè):A=A=(3 3,5 5,8 8,1111),),B=B=(2 2,6 6,8 8,9 9,1111)預(yù)測(cè):預(yù)測(cè):合并后的合并后的C =C =(2, 3, 5, 6, 8, 8, 9, 112, 3, 5, 6, 8, 8, 9, 11,1111)例例1 1:兩個(gè)鏈表的歸并(教材:兩個(gè)鏈表的歸并(教材P31P31例)例)算法設(shè)計(jì):算法設(shè)計(jì):算法主要包括搜索、比較、插入三個(gè)操作:算法主要包括搜索、比較、插入三個(gè)操作:搜索:搜索:需要設(shè)立三個(gè)指針

23、來(lái)指向需要設(shè)立三個(gè)指針來(lái)指向La La 、LbLb和和LcLc鏈表;鏈表;請(qǐng)將該例子和請(qǐng)將該例子和ch2-1的的ppt的第的第18頁(yè)進(jìn)行比較!頁(yè)進(jìn)行比較!25La3 5 8 11 Lb2 6 8 119 PaPbPaPbPaPa、PbPb用于搜索用于搜索LaLa和和LbLb, PcPc指向新鏈表當(dāng)前結(jié)點(diǎn)。指向新鏈表當(dāng)前結(jié)點(diǎn)。歸并過(guò)程示意如下:歸并過(guò)程示意如下:Lc=LaPbPaPaPb比較:比較:比較比較LaLa和和LbLb表中結(jié)點(diǎn)數(shù)據(jù)的大??;表中結(jié)點(diǎn)數(shù)據(jù)的大??;插入:插入:將將LaLa和和LbLb表中數(shù)據(jù)較小的結(jié)點(diǎn)插入新鏈表表中數(shù)據(jù)較小的結(jié)點(diǎn)插入新鏈表Lc Lc 。請(qǐng)注意鏈表的特點(diǎn),僅改變指

24、針便可實(shí)現(xiàn)請(qǐng)注意鏈表的特點(diǎn),僅改變指針便可實(shí)現(xiàn)數(shù)據(jù)的移動(dòng)數(shù)據(jù)的移動(dòng), ,即即“數(shù)據(jù)不動(dòng),指針動(dòng)數(shù)據(jù)不動(dòng),指針動(dòng)”26 void MergeList_L(LinkList &La,LinkList &Lb,LinkList &Lc)/已知單鏈線性表La和Lb的元素按值非遞減排列。歸并為L(zhǎng)c后也按值非遞減排列。 free(Lb); /釋放Lb的頭結(jié)點(diǎn) /MergeList_L pc-next = pa pa: pb ; /插入非空表的剩余段 while(pa&pb) /將pa 、pb結(jié)點(diǎn)按大小依次插入Lc中 if (pa-datadata) pc-next=pa;

25、pc=pa; pa=pa-next; else pc-next=pb; pc=pb; pb=pb-next pa=LaLa-next; pb=LbLb-next; Lc=pc=La; /有頭結(jié)點(diǎn)思考:思考:重復(fù)的數(shù)據(jù)元素不需要插入,怎么修改?重復(fù)的數(shù)據(jù)元素不需要插入,怎么修改?練習(xí):練習(xí):已知已知L是帶頭結(jié)點(diǎn)的非空單鏈表,指針是帶頭結(jié)點(diǎn)的非空單鏈表,指針p所指的所指的結(jié)點(diǎn)既不是第一個(gè)結(jié)點(diǎn),也不是最后一個(gè)結(jié)點(diǎn)結(jié)點(diǎn)既不是第一個(gè)結(jié)點(diǎn),也不是最后一個(gè)結(jié)點(diǎn)l 刪除刪除*p結(jié)點(diǎn)的直接后繼結(jié)點(diǎn)的語(yǔ)句序列結(jié)點(diǎn)的直接后繼結(jié)點(diǎn)的語(yǔ)句序列 q = p-next; p-next = q-next; free(q);l

26、 刪除刪除*p結(jié)點(diǎn)的直接前驅(qū)結(jié)點(diǎn)的語(yǔ)句序列結(jié)點(diǎn)的直接前驅(qū)結(jié)點(diǎn)的語(yǔ)句序列 q = L; while( q-next-next != p) q = q-next; s = q-next;/s即所要找到的即所要找到的p的前驅(qū)的前驅(qū) q-next = p;/鏈接鏈接 free(s);l 刪除刪除*p結(jié)點(diǎn)的語(yǔ)句序列結(jié)點(diǎn)的語(yǔ)句序列 q = L; while( q-next != p) q = q-next; q-next = p-next; free(p);l 刪除首元結(jié)點(diǎn)的語(yǔ)句序列刪除首元結(jié)點(diǎn)的語(yǔ)句序列 q = L-next; L-next = q-next; free(q);l 刪除最后一個(gè)結(jié)點(diǎn)的語(yǔ)句

27、序列刪除最后一個(gè)結(jié)點(diǎn)的語(yǔ)句序列 while(p-next-next != NULL) p = p-next; q = p-next; p-next = NULL; free(q);29用上述定義的單鏈表實(shí)現(xiàn)線性表的操作時(shí),存在的用上述定義的單鏈表實(shí)現(xiàn)線性表的操作時(shí),存在的問(wèn)題問(wèn)題:改進(jìn)鏈表的設(shè)置:改進(jìn)鏈表的設(shè)置:1 1單鏈表的表長(zhǎng)是一個(gè)隱含的值;單鏈表的表長(zhǎng)是一個(gè)隱含的值; 1. 1. 增加增加“表長(zhǎng)表長(zhǎng)”、“表尾指針表尾指針” 和和 “當(dāng)前位置的指當(dāng)前位置的指針針” 三個(gè)數(shù)據(jù)域;三個(gè)數(shù)據(jù)域; 2. 2. 將基本操作中的將基本操作中的“位序位序 i i ”改變?yōu)楦淖優(yōu)椤爸羔樦羔?p p ”。2

28、 2在單鏈表的最后一個(gè)元素之后插入元素時(shí),需遍在單鏈表的最后一個(gè)元素之后插入元素時(shí),需遍歷整個(gè)鏈表;歷整個(gè)鏈表;3 3在鏈表中,元素的在鏈表中,元素的“位序位序”概念淡化,結(jié)點(diǎn)的概念淡化,結(jié)點(diǎn)的“位位置置”概念加強(qiáng)。概念加強(qiáng)。返返 回回30typedef struct LNode /結(jié)點(diǎn)類型 Elemtype data; struct LNode *next; *Link, *Positiontypedef struct /鏈表類型 Link head, tail; /分別指向鏈表頭尾結(jié)點(diǎn) int len; /鏈表中元素個(gè)數(shù)(長(zhǎng)度) Linklist;2.3.3 2.3.3 一個(gè)帶頭結(jié)點(diǎn)的線性

29、鏈表類型定義如下:一個(gè)帶頭結(jié)點(diǎn)的線性鏈表類型定義如下:(用類(用類C C語(yǔ)言,見(jiàn)語(yǔ)言,見(jiàn)P37P37):):結(jié)點(diǎn)的結(jié)點(diǎn)的結(jié)構(gòu)結(jié)構(gòu)表結(jié)構(gòu)表結(jié)構(gòu)基本操作(略)基本操作(略)返返 回回31 最后一個(gè)結(jié)點(diǎn)的指針域的指針又指回第一個(gè)結(jié)點(diǎn)的最后一個(gè)結(jié)點(diǎn)的指針域的指針又指回第一個(gè)結(jié)點(diǎn)的鏈表。從表中任一結(jié)點(diǎn)出發(fā)均可找到表中其它結(jié)點(diǎn)鏈表。從表中任一結(jié)點(diǎn)出發(fā)均可找到表中其它結(jié)點(diǎn) a1 a2 . an 1. 1. 循環(huán)鏈表循環(huán)鏈表 和單鏈表的差別僅在于,判別鏈表中最后一個(gè)結(jié)和單鏈表的差別僅在于,判別鏈表中最后一個(gè)結(jié)點(diǎn)的條件不再是點(diǎn)的條件不再是“后繼是否為空后繼是否為空”,而是,而是“后繼是后繼是否為頭結(jié)點(diǎn)否為頭結(jié)點(diǎn)

30、”即即p-next?=headhead2.3.4 2.3.4 其它形式的鏈表其它形式的鏈表32單鏈表中查找只能從前往后,而不能從后往前查。為了單鏈表中查找只能從前往后,而不能從后往前查。為了查找方便,提高查找速度,可以在結(jié)點(diǎn)上增加一個(gè)指針查找方便,提高查找速度,可以在結(jié)點(diǎn)上增加一個(gè)指針域,用來(lái)存結(jié)點(diǎn)的直接前驅(qū),這樣的鏈表稱為域,用來(lái)存結(jié)點(diǎn)的直接前驅(qū),這樣的鏈表稱為雙向鏈表雙向鏈表。其其結(jié)點(diǎn)的結(jié)構(gòu)結(jié)點(diǎn)的結(jié)構(gòu)為:為:typedef struct DuLNode ElemType data; /數(shù)據(jù)域 struct DuLNode *prior; /前驅(qū)指針域 struct DuLNode *nex

31、t; /后繼指針域 DuLNode , *DuLinkList ; 雙向鏈表類型的定義如下:雙向鏈表類型的定義如下:2.3.4 2.3.4 其它形式的鏈表其它形式的鏈表2. 2. 雙向鏈表雙向鏈表設(shè)指針p指向某一結(jié)點(diǎn),則雙向鏈表結(jié)構(gòu)的對(duì)稱性雙向鏈表結(jié)構(gòu)的對(duì)稱性描述如下描述如下: (pprior)next = p = (pnext)prior,即結(jié)點(diǎn)*p的存儲(chǔ)位置既存放在其前趨結(jié)點(diǎn)*(pprior)的直接后繼指針域中,也存放在它的后繼結(jié)點(diǎn)*(pnext)的直接前趨指針域中ai-1aiai+1p343.3.雙向循環(huán)鏈雙向循環(huán)鏈表表空表空表非空表非空表 a1 a2 . anhead-prior=he

32、ad-next=headhead35雙向鏈表插入操作(重點(diǎn)):雙向鏈表插入操作(重點(diǎn)):設(shè)設(shè)p p已指向第已指向第 i 元素,請(qǐng)?jiān)诘谠?,?qǐng)?jiān)诘?i 元素元素前前插插入元素入元素x ai-1的后繼從的后繼從 ai ( ( 指針是指針是p)變?yōu)樽優(yōu)?x(指針是指針是s) : s-next = p ; p-prior-next = s ; ai 的前驅(qū)從的前驅(qū)從 ai-1 ( 指針是指針是p-prior)變?yōu)樽優(yōu)?x ( 指針是指針是s); s-prior = p -prior ; p-prior = s ; 注意:要修改注意:要修改雙向指針!雙向指針!x sai-1 ai p指針域的變化指針域的

33、變化:void dinsertbefor(DuLNode *p,ElemType x)DuLNode *s=malloc(sizeof(DuLNode);sdata=x;snext=p; ppriornext=s;sprior=pprior; pprior=s; 問(wèn):(問(wèn):(1) (2) (3),(4)位置是否可交換?)位置是否可交換?原則是什么?原則是什么?改成如下代碼試試:改成如下代碼試試:sprior=pprior;snext=p;ppriornext=s;pprior=s;改成如下代碼試試:改成如下代碼試試:snext=p;sprior=pprior;pprior=s;ppriorne

34、xt=s;37指針域的變化:指針域的變化: ai-1的后繼由的后繼由 ai 變?yōu)樽優(yōu)?ai+1( (指針指針 p -next );); p -prior-next = p-next ; ai+1 的前驅(qū)由的前驅(qū)由 ai 變?yōu)樽優(yōu)閍i-1 (指針指針 p - prior ); p-next-prior = p -prior ; ai-1 ai+1 ai p雙向鏈表刪除操作:雙向鏈表刪除操作:設(shè)設(shè)p指向第指向第i個(gè)元素個(gè)元素, ,刪除第刪除第i個(gè)元素個(gè)元素注意:要注意:要修改雙向修改雙向指針!指針!void ddeletenode(dlistnode *p)ppriornext=pnext; pn

35、extprior=pprior;free(p);39動(dòng)態(tài)鏈表樣式:動(dòng)態(tài)鏈表樣式:靜態(tài)鏈表樣式:靜態(tài)鏈表樣式:指針指針數(shù)據(jù)指針指針數(shù)據(jù)指針指針數(shù)據(jù)指示指示數(shù)據(jù)指示指示數(shù)據(jù)指示指示數(shù)據(jù)指示指示數(shù)據(jù)指示指示數(shù)據(jù)數(shù)組中每個(gè)元數(shù)組中每個(gè)元素都至少有兩素都至少有兩個(gè)分量,屬于個(gè)分量,屬于結(jié)構(gòu)型數(shù)組結(jié)構(gòu)型數(shù)組。常用于無(wú)指針常用于無(wú)指針類型的高級(jí)語(yǔ)類型的高級(jí)語(yǔ)言中。言中。用一片連續(xù)空間(一維數(shù)組)實(shí)現(xiàn)鏈?zhǔn)酱鎯?chǔ),這種用一片連續(xù)空間(一維數(shù)組)實(shí)現(xiàn)鏈?zhǔn)酱鎯?chǔ),這種方式稱為方式稱為靜態(tài)鏈表靜態(tài)鏈表。具體實(shí)現(xiàn)方法:具體實(shí)現(xiàn)方法:定義一個(gè)結(jié)構(gòu)型數(shù)組(每個(gè)元素都含定義一個(gè)結(jié)構(gòu)型數(shù)組(每個(gè)元素都含有有數(shù)據(jù)域數(shù)據(jù)域和和指示域指

36、示域),就可以完全描述鏈表,),就可以完全描述鏈表,指示域指示域就相當(dāng)于動(dòng)態(tài)鏈表中的指針就相當(dāng)于動(dòng)態(tài)鏈表中的指針, ,指示結(jié)點(diǎn)在數(shù)組中的相指示結(jié)點(diǎn)在數(shù)組中的相對(duì)位置。對(duì)位置。4.4.靜態(tài)鏈表(自學(xué))靜態(tài)鏈表(自學(xué))40 靜態(tài)單鏈表的類型定義如下:靜態(tài)單鏈表的類型定義如下:#define MAXSIZE 1000 /預(yù)分配鏈表的最大長(zhǎng)度 typedef struct ElemType data ; /數(shù)據(jù)域 int cur ; /指示域 component ,SLinkListMAXSIZE; /這是一維結(jié)構(gòu)型數(shù)組前例前例1 1:一:一線性表線性表 S S = ( ZHAO, QIAN, SUN

37、, LI, ZHOU, = ( ZHAO, QIAN, SUN, LI, ZHOU, WU )WU ),用靜態(tài)鏈表如何表示?,用靜態(tài)鏈表如何表示?說(shuō)明說(shuō)明1 1:假設(shè)假設(shè)S S為為SLinkListSLinkList型變量,則型變量,則SMAXSIZESMAXSIZE 為一為一個(gè)靜態(tài)鏈表;個(gè)靜態(tài)鏈表;S0.curS0.cur則表示第則表示第1 1個(gè)結(jié)點(diǎn)在數(shù)組中的位置。個(gè)結(jié)點(diǎn)在數(shù)組中的位置。41說(shuō)明說(shuō)明2 2:如果數(shù)組的第如果數(shù)組的第i i個(gè)分量表示鏈表的第個(gè)分量表示鏈表的第k k個(gè)結(jié)點(diǎn),個(gè)結(jié)點(diǎn),則:則:Si.dataSi.data表示第表示第k k個(gè)結(jié)點(diǎn)的數(shù)據(jù);個(gè)結(jié)點(diǎn)的數(shù)據(jù); Si.curSi

38、.cur 表示第表示第k+1k+1個(gè)結(jié)點(diǎn)個(gè)結(jié)點(diǎn)( (即即k k的直接后繼的直接后繼) )的位置。的位置。data1 1ZHAO3LI5QIAN6WU0ZHOU4SUN2curi說(shuō)明說(shuō)明3 3:靜態(tài)鏈表的插入與刪除靜態(tài)鏈表的插入與刪除操作與普通鏈表一樣,不需要移操作與普通鏈表一樣,不需要移動(dòng)元素,只需修改指示器就可以動(dòng)元素,只需修改指示器就可以了。了。例如:在線性表例如:在線性表 S = ( ZHAO, S = ( ZHAO, QIAN, SUN, LI, ZHOU, WU )QIAN, SUN, LI, ZHOU, WU )的的QIAN, SUNQIAN, SUN之間之間LIULIU,可以這樣

39、實(shí)現(xiàn):可以這樣實(shí)現(xiàn):42Step1:Step1:將將QIANQIAN的指示器原內(nèi)容備份到臨時(shí)變量的指示器原內(nèi)容備份到臨時(shí)變量temptemp:temp = S3.cur;Step2:Step2:將將QIANQIAN的指示器換為新元的指示器換為新元素素LIULIU的位置:的位置:Step3:Step3:將將LIULIU的指示器變?yōu)楹蟮闹甘酒髯優(yōu)楹罄^繼SUNSUN的位置:的位置:data2SUN4ZHOU0WU6QIAN5LI3ZHAO1 1curi data cur 0 6 1 2 2 a 3 3 b 4 4 c 5 5 d 0 6 7 7 0 li = si.cur; 指針后移操作指針后移操作lMalloc: i = s0.cur; 第一個(gè)可用結(jié)點(diǎn)位置第一個(gè)可用結(jié)點(diǎn)位置 if(s0.cur) s0.cur = si.cur;lF

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論