版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
全國高等教育自學考試指定教材
計算機及應用專業(yè)(本科段)數據結構與算法第四章數組、廣義表和串學習目標掌握數組、廣義表和串的基本概念掌握數組按行主序及按列主序的存儲方式及二維數組地址計算方法掌握特殊矩陣的存儲方式及相應的地址計算方法理解廣義表的概念,掌握廣義表的表示及基本運算了解模式匹配概念,掌握串的模式匹配算法本章主要內容數組及廣義表12串第一節(jié)
數組及廣義表數組是程序設計語言中的重要語法成分,很多語言都定義了數組類型以C語言為例,它定義了一維數組,數組元素還可以是數組,由此得到數組的數組,即多維數組一般地將n(n≥2)維數組看作是n-1維數組的數組從數據結構的角度來理解,一維數組可以作為線性表的存儲結構,數組中保存的各元素可以組成一個線性表多維數組在系統內部都對應一個隱含的一維數組,所以多維數組也是一種線性表例如二維數組就是以一維數組為元素的線性表數組的每個元素都是形如(index,value)的二元對,index是數組下標,也稱為索引,value是對應于該下標的數值任何兩個元素的index值都不相同數組的基本操作Create(); //創(chuàng)建一個空的數組Store(index,value);//添加數據(index,value)//同時刪除有相同index值的數據對(若存在)Retrieve(index);//返回下標為index的value值例4-1用數組表示一個星期每天的最高溫度hightem={(星期日,30),(星期一,28),(星期二,29),(星期三,32),(星期四,28),(星期五,30),(星期六,31)}數組上的操作Store(星期一,29);Retrieve(星期五);也可以約定使用0到6來分別表示星期日到星期六,此時,數組hightem可表示為hightem={(0,30),(1,28),(2,29),(3,32),(4,28),(5,30),(6,31)}數組的順序存儲方式數組的順序存儲有兩種形式。以二維數組為例,它的元素可以按行排列,也可以按列排列所謂按行排列,就是先排數組的第一行,緊隨其后排第二行,依此類推所謂按列排列,就是先排數組的第一列,緊隨其后排第二列,依此類推最終都是將數組中的全部元素排列成一個序列C語言中多維數組下標的形式:[i1][i2][i3]…[ik]ij(1≤j≤k)為非負整數聲明值為整型類型的k維數組DkArrayintDkArray[u1][u2][u3]…[uk];每一維的下標取值范圍是:0≤ij<uj(1≤j≤k)數組最多可容納n=u1
u2
u3
…
uk個整數所需要的內存空間sizeof(DkArray)=n
sizeof(int)個字節(jié)若開始地址為start,則占用的空間將延伸至start+sizeof(DkArray)-1。intD2Array[3][6];對應一個3行6列的矩陣通常int占4個字節(jié)數組D2Array中含有18個元素共占用18
4=76個字節(jié)編號對上述的下標表格按行自上而下、同一行中自左至右進行連續(xù)編號,從0開始按行優(yōu)先把二維數組中的下標映射到0到n-1之間的某個整數的方式稱為行主序,也稱為行主映射按列優(yōu)先,對下標表格從第一列開始,從上到下進行連續(xù)編號,直到最后一列映射函數行主序所對應的映射函數為 map(i1,i2)=i1
u2+i2
其中u2是數組的列數列主序所對應的映射函數為 map(i1,i2)=i2
u1+i1
其中u1是數組的行數例4-3二維數組A[10][5]采用行主序方式存儲,每個數據元素占4個存儲單元,若A[0][4]的存儲地址是1000,則A[8][4]的存儲地址是多少?解:給定的數組A是10行5列,需要從A[0][4]的存儲地址反推出數組A的首地址,然后再計算A[8][4]的存儲地址行主序所對應的映射函數為map(i1,i2)=i1
u2+i2本題中:u2=5,map(0,4)=4每個元素占4個存儲單元 A[0][0]的存儲地址=1000-4
4=984根據計算公式,A[8][4]的映射編號是 map(8,4)=8
5+4=44存儲地址為984+44
4=1160換一種計算方法A[0][4]和A[8][4]之間的元素個數是 8
5=40A[0][4]與A[8][4]之間的偏移量 =40
4A[8][4]的存儲地址 =A[0][4]的存儲地址+ A[0][4]與A[8][4]之間的偏移量 =1000+160=1160示例三維數組D3Array[3][2][4]按行主序下標排列的形式對于三維數組ThrDimenArray[u1][u2][u3],其行主序的映射函數應為 map(i1,i2,i3)=i1
u2
u3+i2
u3+i3排列規(guī)律所有第一維值為i1的元素都排在第一維值大于i1的元素之前。第一維值相同的元素數目為u2
u3。因此第一維值小于i1的元素數目為i1
u2
u3,第一維值等于i1且第二維值小于i2的元素數目為i2
u3,第一維值等于i1第二維值等于i2且第三維值小于i3的元素數目為i3矩陣的壓縮存儲對稱矩陣和三角矩陣從節(jié)省存儲空間的角度考慮,對稱矩陣和上(下)三角矩陣,都可以只保存矩陣中約一半的元素,從而可以節(jié)省差不多一半的存儲空間這樣的存儲形式稱為壓縮存儲壓縮存儲對于對稱矩陣,因為對角線以上及以下的元素對稱相等,所以只需要保存其中的一半及對角線上的元素即可對于上三角矩陣或下三角矩陣,僅保存上三角部分或下三角部分的元素,另外一半的零元素不再保存若矩陣有n行n列,則這三種形式下需要保存的元素個數為n
(n+1)/2三角部分
例4-4設有一個10行10列的下三角矩陣A,采用行優(yōu)先壓縮存儲方式,保存A中第一個元素a00的地址是100,保存a11的地址是108,則保存元素a44的地址是()A.115B.156C.160D.212答案為B稀疏矩陣稀疏矩陣該矩陣只有10個非零元素,每個非零元素用一個三元組表示三元組表三元組表應是一個有序序列,通常按行主序次序排列,即先按行的大小排列,同一行的三元組再按列的大小排列對應前例的三元組表i0012234455j1200521405v891-3121624615-7稀疏矩陣的存儲結構typedefstruct{ inti,j; //存儲非零元素的下標
ELEMTypev; //存儲非零元素的值}triTerm;typedefstruct{ introws,cols; //矩陣的行數、列數 intterms; //非零元素個數
triTermtri[maxSize]; //三元組表}SparseMatrix;輸入三元組生成三元組表的程序矩陣轉置矩陣轉置即是行、列互換,i行的元素放置到i列,這也意味著,j列的元素放置在j行。如果矩陣是n
m的,則轉置后得到的矩陣是m
n的很容易想到,將三元組表中的每個三元組項的i與j互換,即可得到轉置后矩陣的三元組表但是這樣轉換后得到的三元組表不再按行主序排列,不便于后續(xù)操作的實現所以要實現的矩陣轉置程序,必須得到一個按行主序排列的三元組表思路可以像readSparseMatrix函數那樣處理,讀入原矩陣的一個三元組,插入到目標矩陣的三元組表中可以使用一個臨時計數數組,記錄原矩陣的每個三元組在目標矩陣的三元組表中的插入位置,以輔助完成轉置操作,由此避免了三元組的移動,高效率地實現轉置操作不失一般性,設原矩陣A的行數是rows,列數是cols。則轉置后矩陣B的行數是cols,列數是rows。三元組的個數沒有改變A中處于0列的元素,將是B中處于0行的元素。所以B的三元組表中的最前面的元素,是A中列值為0的元素。接下來是A中列值為1的元素,依此類推,最后是A中列值為cols-1的元素。使用臨時數組ColSize來保存統計結果前例中的矩陣,臨時數組ColSize內容在B的三元組表中,為各行元素預留位置01234532201201234567890行元素1行元素2行元素4行元素5行元素對于A的三元組(0,1,8)和(4,1,24),轉置后分別為(1,0,8)和(1,4,24),它們應該保存在上述第二部分,即位置3和位置4中故由ColSize數組中的元素值,從前向后依次相加,得到RowNext的值012345603577810轉置算法數組的應用走迷宮是實驗心理學中的一個經典問題不失一般性,使用一個m行n列的矩陣maze表示迷宮,讓機器人R尋找從maze[0][0](左上角,入口)到maze[m-1][n-1](右下角,迷宮的唯一出口)間的可行路徑任一時刻,R在迷宮中的位置用行、列號[i][j]來表示,這時它有4個方向可以進行試探,即從圖上看是上、下、左、右設下一位置是[g][h],顯然[g][h]的值與走的方向有關若從[i][j]向右走一步,則g=i;h=j+1若向上走一步,則g=i-1;h=j當R走到迷宮邊緣時,可以試探的方向不足4個,需要進行邊界的判斷為了避免過多的邊界條件判斷,可以把原來表示迷宮的矩陣maze擴大一圈,變成m+2行n+2列,并且令表示邊緣的這些矩陣元素全為1編寫計算機程序求解迷宮問題,一般采用一步一探查并加回溯的方法。稱R所在的位置為當前位置,當R走到一個位置時,除了進入當前位置的方向外,可以在其他3個方向進行探查,選擇可行并尚未走過的方向走一步,所處的新位置變?yōu)楫斍拔恢茫⒃俅翁讲橄乱粋€可行位置;當3個方向都走不通時,只能沿來路退到前一個位置再選擇其他方向,這一步驟稱為回溯。回溯后的位置又變?yōu)楫斍拔恢迷谔讲榈倪^程中,因為有回溯,所以可能會走到原來已走過的位置,為避免重復并找出確定的可行路徑,需要一個棧記錄已走過的每一步的位置及方向,另外還需要設置一個與原來迷宮矩陣同樣大小的標志矩陣mark,以對走過的位置進行標記mark矩陣的初值全為0,當R走到maze[i][j]位置時,則置mark[i][j]為1R走迷宮的步驟令R處在迷宮入口,此為當前位置在當前位置上,依右、下、左、上的順序探查前進方向向可以進入的方向前進,即目標位置的maze和mark值全為0。前進一步后,目標位置為當前位置,將mark矩陣的當前位置標記為1,并且將前一位置的位置值及進入當前位置的方向入棧重復步驟②和③若找不到前進通路,則從原路后退一步(退棧),改變探測方向,再重復步驟②、③,以尋找另一條新的通路重復步驟②~⑤,直到走出迷宮或宣布迷宮無通路為止走步時相鄰兩個位置之間行、列值的關系若向右走,則行值不變,列值加1若向下走,則行值加1,列值不變若向左走,則行值不變,列值減1若向上走,則行值減1,列值不變將這4組值定義在move矩陣中列號0、1、2、3分別對應著方向右,下,左,上行號0和1分別對應著位置坐標i和j走迷宮算法走迷宮算法廣義表廣義表是線性表的推廣,也稱為列表是由n(n≥0)個表元素組成的有限序列 LS=(a0,a1,…,an-1)LS是廣義表的名稱n是表的長度當n=0時稱為空表ai(0≤i≤n-1)的類型可以不完全一致,既可以是單個元素(稱為原子),也可以是廣義表(稱為子表)原子不可再分第一個元素a0稱為LS的表頭(Head),其余元素組成的表(a1,a2,…,an-1)稱為LS的表尾(Tail)廣義表中括號的最大嵌套層數定義為表的深度空表的深度為1,原子的深度為0其他情況,可以遞歸求解廣義表的深度=max{各子表的深度}+1例4-5A=()A是空表,長度為0,深度為1B=(())B的長度為1,深度為2C=(6,2)C的長度為2,深度為1,兩個元素都是原子D=('a',(5,3,'x’))D的長度為2,深度為2,含一個原子及一個子表例4-5E=(C,D,A)E的長度為3,深度為3,含3個子表F=(C)F的長度為1,深度為2,含1個子表G=(4,G)G的長度為2,深度為∞,遞歸表各表的表頭和表尾示例Head(B)=(),Tail(B)=()Head(C)=6,Tail(C)=(2)Head(D)='a',Tail(D)=((5,3,'x'))Head(E)=C,Tail(E)=(D,A)Head(F)=C,Tail(F)=()Head(G)=4,Tail(G)=(G)空表沒有定義表頭和表尾,所以不能求表A的表頭和表尾表E的表頭是表C第二節(jié)
串串(String)也稱為字符串,是由零個或多個字符組成的有限序列記為:s="a0a1…an-1",(n≥0),其中,s是串名,使用雙引號括起來的字符序列是串的值串中的每個符號ai(0≤i≤n-1)可以是字母、數字或其他字符,其在串中的次序定義為該符號的位置位置從0開始串中字符個數n稱為串的長度n=0時稱為空串串s中任意個連續(xù)字符組成的子序列稱為串s的子串,相應地s稱為主串子串在主串中首次出現時子串首字符對應于主串的符號位置,定義為子串在主串中的位置設有串s1="Thisisastring",s2="is"s1為主串,s2是s1的子串s2在s1中的位置為2空串是任意串的子串任意串是其自身的子串串的模式匹配在主串中尋找子串(第一個字符)在主串中的位置,稱為串的模式匹配子串又稱為模式,主串稱為目標樸素的模式匹配算法(B-F算法)設主串T="aaaaab",模式串P="aab",采用B-F算法的匹配過程在每趟匹配中,主串與模式串的字符之間的比較次數有3次,共4趟,所以共進行了12次比較主串aaaaab
模式串aab
第1趟
aab
第2趟
aab
第3趟
aab第4趟樸素的模式匹配算法簡單,但時間效率不高設主串長度為n,模式串長度為m。如果每次都是比較到模式串最后一個字符時才出現失配,且主串的最后m個字符與模式串匹配成功,這就出現了最壞情況此時,每一趟都進行了m次比較,共比較了n-m+1趟,故總比較次數將達到(n-m+1)
m算法的最壞情況時間復雜度為O(n
m)改進的模式匹配算法(KMP算法)設主串T="b0b1b2…bm-1…bn-1",模式串P="p0p1p2…pm-1",進行第一趟匹配時,T與P的對應字符進行比較主串Tb0b1b2…bm-1…bn-1模式串Pp0p1p2…pm-1匹配過程中,若某一趟比較時出現失配,模式串P需要整體右移,那么P右移的位數應該是多少呢模式串P的首字符p0對應于主串的字符bs,且前j(j≥0)對字符都匹配成功,第j+1對字符匹配不成功則有bsbs+1bs+2…bs+j-1=p0p1p2…pj-1如果下一趟比較時模式串P與主串T匹配,也就是P與主串中從bs+1開始的子串匹配,則必須滿足p0p1p2…pj-1…pm-1=bs+1bs+2bs+3…bs+j…bs+m若知道p0p1…pj-2
p1p2…pj-1,則立刻可以斷定p0p1…pj-2
bs+1bs+2…bs+j-1,即下一趟必不匹配同樣地,若p0p1…pj-3
p2p3…pj-1,則再下一趟也不匹配,因為p0p1…pj-3
bs+2bs+3…bs+j-1如果找到一個k值,滿足p0p1…pk+1
pj-k-2pj-k-1…pj-1但p0p1…pk=pj-k-1pj-k…pj-1則有p0p1…pk=bs+j-k-1bs+j-k…bs+j-1那么,下一趟可以直接用pk+1與bs+j進行比較如何確定k值呢對于不同的失配位置j,k的取值是不同的,它僅依賴于模式串P本身前j個字符的構成,而與主串無關設模式串P=p0p1…pm-2pm-1,定義特征向量next
從特征向量next的定義可知,next(0)=-1,next(1)=0。對于j≥2,要去查看模式串前j個字符組成的子串p0p1…pj-2pj-1的前綴和后綴,找到相等的兩個,next值是相等的前綴后綴的長度模式串Pp0p1…pkpk+1…pj-k-1pj-k…pj-1
…==
=模式串P
p0p1…pkp0p1...pj-2pj-1的前綴和后綴也可能有重疊例4-9設模式串p="abaabcac",求它的特征向量。next(0)=-1,next(1)=0j=2時,p0p1="ab",next(2)=0j=3時,p0p1p2="aba",p0=p2,k=0,next(3)=1j=4時,p0p1p2p3="abaa",p0=p3,k=0,next(4)=1j=5時,p0p1p2p3p4="abaab",p0p1=p3p4,k=1,next(5)=2j=6時,p0p1p2p3p4p5="abaabc",沒有相等的子串,next(6)=0j=7時,p0p1p2p3p4p5p6="abaabca",p0=p6,k=0,next(7)=1得到特征向量j01234567Pabaabcacnext(j)-10011201例4-10設模式串P="abaabcac",主串T="abaaababaabcac“第1趟失配時,失配位置值是4,next(4)=1,即將模式串的位置1對齊主串中的當前位置主串中是字符a,模式串中是字符b,仍失配,失配位置值是1,next(1)=0,即將模式串的位置0對齊主串中的當前位置主串abaaababaabcac
jnext(j)模式abaabcac
第1趟41
abaabcac
第2趟10
abaabcac
第3趟31
abaabcac第4趟
再次失配時的位置是3,此位置主串中是字符b,模式串中是字符a。next(3)=1,即讓模式串的位置1對齊主串中的當前位置主串abaaababaabcac
jnext(j)模式abaabcac
第1趟41
abaabcac
第2趟10
abaabcac
第3趟31
abaabcac第4趟
匹配過程中,模式串右移3次,且右移時可以移多位主串的匹配位置始終不回退若每趟第一對字符不匹配,則共比較n-m+1趟,總比較次數最壞達(n-m)+m=n。若每趟第m對字符不匹配,則總比較次數最壞亦達到n分析示例中的向右移位第一趟失配時,模式串中位置4的字符b與主串中位置4的字符a不匹配,根據next值,模式串中位置1的字符對應到主串的當前位置,并進行比較。實際上,模式串位置1的字符仍是b,所以還是失配的。再次根據next值,繼續(xù)右移模式串改進next值的計算,當模式串中失配位置的字符與要移到的目標位置的字符相等時,使用目標位置的next值來替代。由此,省略掉中間這一步的右移例4-11設模式串p="abaabcac",求它的改進特征向量。j01234567Pabaabcacnext(j)-10-1102-11例4-12設模式串P="abaabcac",主串T="abaaababaabcac"匹配過程如下主串abaaababaabcac
jnext(j)模式abaabcac
第一趟40
abaabcac
第二趟31
abaabcac第三趟
求改進的特征向量ThankYou!全國高等教育自學考試指定教材
計算機及應用專業(yè)(本科段)數據結構與算法第五章樹與二叉樹學習目標理解樹及二叉樹的基本概念,掌握二叉樹的基本性質掌握樹及二叉樹的存儲方式能夠實現樹及二叉樹的基本操作及遍歷算法掌握堆的概念及基本操作的實現。理解優(yōu)先隊列的概念理解遞歸的概念,能夠實現遞歸程序掌握樹、森林與二叉樹之間的相互轉換掌握哈夫曼樹及哈夫曼編碼的概念,能夠構造哈夫曼樹并設計哈夫曼編碼本章主要內容樹的基本概念12二叉樹的操作3二叉樹樹和森林5哈夫曼樹及哈夫曼編碼6堆及優(yōu)先隊列4第一節(jié)樹的基本概念樹是一種層次結構,是一種非線性結構日常生活中,經常會遇到具有層次關系的示例家族中部分成員的輩份關系樹的定義定義5-1一棵樹(tree)T是由一個或一個以上的結點組成的有限集,其中有一個特定的結點R稱為樹T的根結點。在集合中除根結點R外,其余的結點可劃分為k(k≥0)個不相交的子集T1,T2,…,Tk,其中每個子集都是樹,并且其相應的根結點R1,R2,…,Rk是R的孩子結點,R稱為Ri(1≤i≤k)的雙親結點,Ri(1≤i≤k)互稱為兄弟結點。子集Ti
(1≤i≤k)稱為根R的子樹(subtree)樹的結點集合至少包含一個結點只含有一個結點的樹是只有根結點的樹,也就是單結點樹對于多結點的樹,必須有一個結點是根結點之間通過邊來連接,邊也稱為分支。含n個結點的樹有且僅有n-1條邊,這是樹的重要特性之一根結點的各子樹之間不會有重疊樹是一種層次結構,也是遞歸形式的含有A,B,C,D,E,F,G,H,I,J共10個結點的樹TA為根結點,{B,E,F},{C,G}和{D,H,I,J}構成根結點A的三棵子樹,B,C,D分別是這三棵子樹的根樹中每個結點擁有的子樹的個數稱為結點的度結點的度即為其子結點的個數樹中結點的度的最大值稱為樹的度度為0的結點稱為葉結點,或終端結點度不為0的結點稱為分支結點如果樹中每個結點的孩子結點之間規(guī)定了次序,則樹稱為有序樹具有同一雙親結點的結點是兄弟結點從任一結點到根結點之間所經過的所有結點稱為該結點的祖先結點以任一結點為根的子樹中的所有結點稱為該結點的后代將線性結構中的前驅和后繼概念引申至樹中,將某結點的雙親結點看作是它的前驅,它的孩子結點看作是它的后繼除根結點外,每個結點均只有一個前驅結點根的前驅結點個數為0,除葉結點外,每個結點都有若干個后繼結點葉結點的后繼結點個數為0樹中每個元素的前驅的個數不會多于1個,后繼的個數可以是任意個樹是一種層次結構,設根為0層,根的孩子結點為1層,依此類推一般地,若某個結點位于i(i≥0)層,則它的孩子結點位于i+1層樹中結點的最大層數定義為樹的深度最大層數加1為樹的高度樹中從某一結點出發(fā),到達另一個結點之間所經過的邊組成一條路徑路徑中所含的邊數為路徑長度雖然樹的路徑定義中并沒有限制路徑的方向,但路徑通常是沿一個方向延伸的,即從某一結點向根的方向延伸,或是從某一結點向葉結點方向延伸通常,以組成路徑的結點序列來表示該條路徑m(m≥0)棵互不相交的樹構成森林對樹中每個結點來說,其子樹的集合即為森林第二節(jié)二叉樹定義5-2二叉樹(binarytree)是結點的一個有限集合,這個集合或者為空,或者是由一個根結點以及兩棵互不相交的、分別稱為這個根的左子樹和右子樹的二叉樹組成。左子樹和右子樹的根分別稱為此二叉樹根結點的左孩子結點和右孩子結點二叉樹的左子樹和右子樹都可以存在或者為空,不同的存在狀態(tài)可以組合出5種基本形態(tài)一棵高度為h的二叉樹若有2h-1個結點,則二叉樹稱為滿二叉樹從形式上來看,滿二叉樹中除葉結點外,每個結點都有兩個孩子結點,即除最后一層外,每一層的結點都是“滿”的滿二叉樹中的n個結點進行連續(xù)編號,從編號為0的結點開始,由連續(xù)編號的任意多個結點組成的二叉樹稱為完全二叉樹特殊二叉樹滿二叉樹和完全二叉樹完全二叉樹的特性
二叉樹的性質性質1在二叉樹的i層上最多有2i個結點(i≥0)證明:使用數學歸納法證明
歸納基礎:
對于非空的二叉樹T,根在0層,本層只有20=1個結點,結論成立
歸納假設:
設二叉樹T中i-1層最多有2i-1個結點,考慮i層,由于i層的結點均為i-1層結點的孩子結點,而二叉樹中每個結點最多有兩個孩子結點,故i層最多有2
2i-1=2i個結點
根據歸納法原理,性質1得證
性質3對任何非空二叉樹T,設n0是葉結點的個數,n2是度為2的結點的個數,則有n0=n2+1證明:設二叉樹T中度為1的結點個數為n1,則T中結點總數n為 n=n0+n1+n2 n-1=2
n2+1
n1+0
n0
將上兩式聯立求解,得到 n0=n2+1
例5-3一棵二叉樹共有20個結點,其中葉結點為5個,則度為l的結點個數是()。A.11B.9C.6D.4答案為A二叉樹的存儲——順序存儲結構對于完全二叉樹,各層自上至下,同層間自左至右,將結點依次存入數組從前至后的各個元素中。按照前面使用過的編號方法,一般來講,編號為i的結點存放在數組中下標為i的位置使用這樣的存儲規(guī)則可以很方便地找到二叉樹中的相關結點,即若知道二叉樹某一結點保存在數組中下標i的位置,則可以很方便地求出它的雙親結點(若存在)和左、右孩子結點(若存在)在數組中的位置對于一般的二叉樹,順序存儲的思想是,針對二叉樹中的每個位置,不論這個位置有沒有結點,都在數組中預留保存空間。采用這種存儲方式保存完全二叉樹時,既不浪費空間,又便于有關操作的實現例5-4設高度為k(k≥1)的二叉樹T采用順序存儲結構保存在數組B[2k-1]中,在沒有保存T中元素的數組位置中,保存一個區(qū)別于T中元素的特殊標記。B中保存的特殊標記個數最多為()。A.k-1B.2k-1C.2k-k-1D.2k-1答案為C鏈式存儲結構定義一個結點結構:它含有兩個指針域,一個指針用來指向該結點左孩子所在的結點,稱為左孩子指針,簡稱為左指針;另一個指針用來指向該結點右孩子所在的結點,稱為右孩子指針,簡稱為右指針。此外,還定義一個用來保存結點中數據的數據域二叉鏈表表示二叉樹結點類的定義及二叉樹的定義二叉鏈表中結點類的定義及二叉樹的定義typedefintELEMType;typedefstructBNode //二叉樹結點{ ELEMTypedata; //數據域 structBNode*left,*right;
//指向左孩子、右孩子的指針}BinTNode;typedefBinTNode*BTree; //二叉樹二叉鏈表中到底有多少空指針域呢設二叉樹中有n個結點,每個結點都含有兩個指針域,則二叉鏈表中共有2
n個指針域已知含n個結點的樹中僅含有n-1個分支,即只有n-1個指針域不為空,則其余的n+1個指針域均為空可以看出,二叉鏈表中有超過一半的指針域都是空的,這些都是結構性開銷第三節(jié)二叉樹的操作二叉樹的生成按照二叉樹的順序存儲方式,將二叉樹各結點值保存在一維數組中,然后建立二叉鏈表如要建立如下的二叉鏈表輸入的數組是inta[]={0,1,2,3,4,NA,5,NA,NA,NA,NA,NA,NA,6};函數CreateBinaryTree遞歸處理二叉鏈表的生成調用它的主程序中先創(chuàng)建一個根結點,其中保存數組首元素的值,該結點作為參數傳遞給函數CreateBinaryTree。這個結點的位置是下標0,將這個位置值也作為參數傳給函數CreateBinaryTree主程序中BTreeroot;root=(BTree)malloc(sizeof(BinTNode));root->data=a[0];root->left=NULL;root->right=NULL;調用函數CreateBinaryTree。參數0是起始位置CreateBinaryTree(0,n,a,root);生成二叉鏈表如果下標i處的結點有左孩子,則其應該保存在下標2
i+1處如果有右孩子,則應該保存在下標2
i+2處故在函數內,判斷數組中位置2
i+1及位置2
i+2處是否保存了元素值如果確實有值,則分配空間創(chuàng)建結點且保存數組中相應位置的元素值,并讓下標i處結點的相應指針指向新創(chuàng)建的結點然后再以2
i+1或2
i+2為參數值,遞歸調用函數,去處理2
i+1或2
i+2位置處結點的左孩子和右孩子如果數組中數據的存儲是正確的,則能正確建立二叉鏈表。如果位置2
i+1或位置2
i+2處沒有保存元素值,則遞歸結束二叉樹的遍歷對非空的二叉樹的遍歷可以相應地分解為三項“子任務”訪問根結點遍歷左子樹(即依相應的規(guī)律訪問左子樹中的全部結點)遍歷右子樹(即依相應的規(guī)律訪問右子樹中的全部結點)常規(guī)的3種遍歷算法分別是先序遍歷、中序遍歷和后序遍歷。這3種遍歷也分別稱為先根遍歷、中根遍歷和后根遍歷先序遍歷算法若二叉樹為空,則返回;否則依次執(zhí)行以下操作(1)訪問根結點(2)先序遍歷左子樹(3)先序遍歷右子樹中序遍歷算法若二叉樹為空,則返回;否則依次執(zhí)行以下操作(1)中序遍歷左子樹(2)訪問根結點(3)中序遍歷右子樹后序遍歷算法若二叉樹為空,則返回;否則依次執(zhí)行以下操作(1)后序遍歷左子樹(2)后序遍歷右子樹(3)訪問根結點先序遍歷過程中序遍歷過程后序遍歷過程例5-6寫出其先序、中序及后序遍歷序列先序遍歷序列為A,B,D,G,H,J,K,E中序遍歷序列為G,D,J,H,K,B,E,A后序遍歷序列為G,J,K,H,D,E,B,A先序遍歷算法先序遍歷算法中序遍歷算法中序遍歷算法后序遍歷算法后序遍歷算法給出二叉樹的先序遍歷序列和中序遍歷序列,能唯一確定該二叉樹給出二叉樹的后序遍歷序列和中序遍歷序列,能唯一確定該二叉樹例5-7設二叉樹T的先序遍歷序列是A,B,D,G,H,J,K,E,中序遍歷序列是G,D,J,H,K,B,E,A,畫出二叉樹T由先序遍歷序列可知,T的根是A在中序遍歷序列中查找A的位置,位于A前面的是其左子樹的中序遍歷序列,位于A后面的是其右子樹的中序遍歷序列從而將原問題的求解(對整棵樹的還原)分解為兩個更小問題的求解(對兩棵子樹的還原)例5-8統計以二叉鏈表表示的二叉樹T中葉結點的個數T中葉結點的個數等于根左子樹中葉結點的個數加上根右子樹中葉結點的個數。所以如果遞歸調用已經得到了兩棵子樹中葉結點的個數,那么將結果相加即求解例5-9編寫程序,返回二叉樹T的高度仍是使用遞歸的思想去編寫程序。如果左子樹的高度和右子樹的高度都已經知道,則二叉樹T的高度就可求得,樹的高度是兩棵子樹中較高者的高度再加1層序遍歷所謂按層遍歷,即是從根結點開始逐層向下遍歷,直到最后一層對于同一層的結點,由左到右遍歷各結點同一層中的結點相繼被訪問,同時,它們之間的相對次序也決定著它們孩子結點的相對次序。即同一層中的結點u和結點v,若先遍歷u再遍歷v,則u的孩子結點的遍歷也早于v的孩子結點的遍歷按層進行遍歷先訪問最上面一層即0層中的元素,輸出1然后依次訪問1的子結點2和3再繼續(xù)訪問2的子結點和3的子結點依此類推,得到的層序遍歷結果是:1,2,3,4,5,6,7層序遍歷算法二叉樹層序遍歷的算法遍歷的非遞歸實現仍然將一棵二叉樹分為三部分:根、左子樹和右子樹。從根開始遍歷二叉樹時,根的左子樹和右子樹的遍歷不能同時進行,只能先遍歷一棵子樹,同時保存二叉樹中尚不能遍歷部分的信息,留待一棵子樹處理完畢后再處理分析二叉樹的遍歷過程可知,使用棧來保存相關信息先序遍歷算法在進入左子樹進行處理之前,需要在棧中保存右子樹的相關信息,以便當左子樹處理完畢,能夠根據保存的線索找到右子樹的根。所以,棧中保存右子樹的根即可程序中序遍歷算法中序遍歷時,先進行左子樹的遍歷,然后遍歷根,再遍歷右子樹。所以棧中保存根的信息,遍歷完左子樹后,從棧中找到根,訪問根,同時也能容易地找到右子樹程序后序遍歷算法類似于中序遍歷過程,在進入左子樹遍歷之前,需要先保存根的信息。當左子樹遍歷結束,從棧中找到根,但此時因為右子樹尚未遍歷,所以根并不能從棧中彈出,仍需要保存在棧中,只有當右子樹也遍歷結束后,才能訪問根棧中保存的結點需要入棧兩次出棧兩次。為了能有所區(qū)別,二叉樹結點入棧時,附帶一個標記位flag。第一次出棧時,并不訪問結點。第二次出棧時才訪問它將二叉樹結點和標記組合在一起,定義新的棧的類型,專用于非遞歸實現二叉樹的后序遍歷過程typedefstruct SNode //進棧帶標記結點{ BinTNode
btreeNode; //二叉樹結點
intflag; //標記}StackTNode; typedefstruct{ //用于后序遍歷的棧
StackTNodeelement[maxSize]; inttop; //棧頂位置}SeqBTreeStackforPostT;程序二叉樹的應用可以使用二叉樹來表示一個表達式,這樣的二叉樹稱為表達式樹2*y*(a+3*y)-b畫出表達式樹先根據運算符的優(yōu)先級對表達式加括號去掉最外層括號。中間的運算符為根,前后兩部分分別對應于左子樹和右子樹對左子樹遞歸執(zhí)行步驟②對右子樹遞歸執(zhí)行步驟②當遇到空串時,遞歸結束例5-12已知算術表達式的中綴形式為A+B*C-D/E,后綴形式為ABC*+DE/-,其前綴形式為()A.-A+B*C/DEB.-A+B*CD/EC.-+*ABC/DED.-+A*BC/DE答案:D
第四節(jié)堆及優(yōu)先隊列前一種關系表明,任何一個分支結點的值都不大于它子結點的值,所以樹根結點的值是全部結點中的最小值。這樣的堆稱為最小堆或小根堆后一種關系表明,任何一個分支結點的值都不小于它子結點的值,故樹根結點的值是全部結點中的最大值。這樣的堆稱為最大堆或大根堆樹根結點稱為堆頂堆的定義中還隱含了遞歸的含義,當用完全二叉樹的形式表示堆時,樹中的任意一棵子樹都可以構成堆,并且保持與原來同樣的性質最大堆中任何結點的子樹仍是最大堆最小堆中任何結點的子樹仍是最小堆最小堆和最大堆堆的類型定義#defineHeapSize30 //堆的容量typedefintELEMType; //元素類型typedefstructHeap{
ELEMTypeheap[HeapSize]; //存放元素的數組 intn; //堆中當前元素個數};堆的基本操作intcreatHeap(maxHeap*H,ELEMType
arr[],intn); //創(chuàng)建堆intinsertHeap(maxHeap*H,ELEMTypex); //在堆中插入元素xintdeleteHeap(maxHeap*H,ELEMType*x); //刪除堆頂元素intisHeapEmpty(maxHeap*H); //如果堆為空,則返回1,否則返回0intisHeapFull(maxHeap*H); //如果堆為滿,則返回1,否則返回0最大堆的類型定義#defineHeapSize30 //堆的容量typedefintELEMType; //元素類型typedefstructmaxHeap{
ELEMTypeheap[HeapSize]; //存放元素的數組 intn; //堆中當前元素個數};判空、判滿創(chuàng)建最大堆向最大堆中插入新元素刪除堆頂元素例5-1370,13,65,24,56,48,92,86,將其建成最大堆例5-14在最大堆中插入新元素40例5-15刪除最大堆的堆頂優(yōu)先隊列一些應用中,各元素本身還被賦予一個優(yōu)先值,可以用一個非負整數表示優(yōu)先值。優(yōu)先值也稱為優(yōu)先權。具有優(yōu)先值的各元素保存在一個結構中,這個結構稱為優(yōu)先隊列。輸出時,選擇最優(yōu)先的元素輸出。“最優(yōu)先”取決于優(yōu)先值的定義,可以是優(yōu)先值最小,也可以是優(yōu)先值最大。第五節(jié)樹和森林樹的存儲結構父結點表示法孩子結點表示法孩子-兄弟表示法父結點表示法樹中每個結點至少含兩個域,一個域用來保存結點本身的值,另一個域用來保存結點之父結點的相關信息孩子結點表示法父結點-孩子結點表示法孩子-兄弟表示法為樹中的每個結點定義一個存儲結點,其中有左、右兩個指針域,左指針域指向這個結點的第一個孩子結點,右指針域指向這個結點的下一個兄弟結點樹、森林與二叉樹的轉換樹和二叉樹都可以用二叉鏈表作為存儲結構同一個二叉鏈表,若按樹的存儲含義來解釋,可以還原為樹。若按二叉樹的存儲含義來解釋,可以還原為二叉樹正是因為這一點,可以在樹與二叉樹之間建立一種對應關系轉換規(guī)則規(guī)則1:將森林轉換成二叉樹設F={T1,T2,…,Tm}是森林,則可按如下規(guī)則將森林F轉換為一棵二叉樹B=(root,LB,RB)(1)若F為空(m=0),則B為空樹(2)若F非空(m>0),則森林中T1的根作為二叉樹B的根root;T1中各子樹組成的森林F1={T11,T12,…,T1s}轉換成的二叉樹作為B的左子樹BL;森林F’={T2,T3,…,Tm}轉換成的二叉樹作為B的右子樹BR森林轉換為二叉樹轉換規(guī)則規(guī)則2:將二叉樹還原為森林設B=(root,BL,BR)是一棵二叉樹,則可按如下規(guī)則轉換成森林F={T1,T2,…,Tm}(1)若B為空,則F為空(2
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年大學生社會實踐總結參考(三篇)
- 2024年場地租賃合同經典版(三篇)
- 2024年小學教師德育工作總結(三篇)
- 2024年工程施工承包合同常用版(二篇)
- 2024年小學數學教研組計劃(三篇)
- 2024年婦幼健康教育工作計劃模版(二篇)
- 2024年大學四年學習計劃范本(二篇)
- 2024年工廠臨時工勞動合同標準范本(二篇)
- 2024年醫(yī)院財務工作計劃范本(二篇)
- 2024年安全隱患排查與整改制度模版(二篇)
- 新《固廢法》解讀(專業(yè)版)
- 領導及上下級關系處理講義
- Catia百格線生成宏
- 業(yè)務流程繪制方法IDEF和IDEFPPT課件
- 鍋爐安全基礎知識
- 幼兒園科學教育論文范文
- 駕校質量信譽考核制度
- 用電檢查工作流程圖
- 電動葫蘆的設計計算電動起重機械畢業(yè)設計論文
- (完整版)學校安辦主任安全工作職責
- PCR儀使用手冊
評論
0/150
提交評論