王道408数据结构——第五章 树与二叉树
文章目錄
- 一、樹的基本概念
- 樹的性質(zhì)
- 二、二叉樹
- 滿二叉樹
- 完全二叉樹
- 二叉排序樹
- 平衡二叉樹
- 二叉樹的性質(zhì)
- 完全二叉樹的性質(zhì)
- 三、二叉樹的儲(chǔ)存結(jié)構(gòu)
- 順序儲(chǔ)存
- 鏈?zhǔn)酱鎯?chǔ)
- 四、樹的儲(chǔ)存方式
- 雙親表示法
- 孩子表示法
- 孩子兄弟表示法(二叉樹表示法)
- 五、二叉樹的遍歷
- 先序遍歷(preOrder、NLR)
- 中序遍歷(inOrder、LNR)
- 后序遍歷(postOrder、LRN)
- 中序遍歷的非遞歸算法
- 先序遍歷的非遞歸算法
- 后序遍歷的非遞歸算法
- 層次遍歷
- 由遍歷序列構(gòu)造二叉樹
- 六、線索二叉樹
- 二叉線索化
- 遍歷線索二叉樹
- 七、森林
- 樹轉(zhuǎn)換為二叉樹
- 森林轉(zhuǎn)換為二叉樹
- 二叉樹轉(zhuǎn)換為森林
- 樹的遍歷
- 森林的遍歷
- 八、二叉排序樹(BST)
- BST的插入
- BST的刪除
- BST的查找
- BST與二分查找
- 九、平衡二叉樹
- 平衡二叉樹的插入
- 十、哈夫曼樹
- 構(gòu)造哈夫曼樹
- 哈夫曼編碼
一、樹的基本概念
樹的定義是遞歸的,樹本身也是一種遞歸的數(shù)據(jù)結(jié)構(gòu)。其作為一種邏輯結(jié)構(gòu),同時(shí)也是一種分層結(jié)構(gòu)。樹適合表示具有層次結(jié)構(gòu)的數(shù)據(jù)。
度:一個(gè)結(jié)點(diǎn)的的孩子個(gè)數(shù)
樹的度:樹中結(jié)點(diǎn)的最大度數(shù)
數(shù)中的分支是有向的,即從雙親指向孩子,所以數(shù)中的路徑只能是從上往下的。同一個(gè)雙親的孩子間不存在路徑。
樹的性質(zhì)
- 樹中結(jié)點(diǎn)等于所有結(jié)點(diǎn)的度數(shù)之和加1,即 總邊數(shù)+1=度數(shù)之和
- 度為 m 的樹中,第 i 層上至多有mi?1m^{i-1}mi?1個(gè)結(jié)點(diǎn)
- 高度為 h 的 m 叉樹至多有mh?1m?1\frac{m^h-1}{m-1}m?1mh?1?個(gè)結(jié)點(diǎn)
- 具有 n 個(gè)結(jié)點(diǎn)的 m 叉樹最小高度為?log?m(n(m?1)+1)?\lceil \log_m(n(m-1)+1)\rceil?logm?(n(m?1)+1)?
二、二叉樹
二叉樹是一種特殊的樹形結(jié)構(gòu),特點(diǎn)是每個(gè)結(jié)點(diǎn)至多只有兩棵子樹,但其度可以小于2;并且二叉樹的子樹有左右之分,即使樹中結(jié)點(diǎn)只有一棵子樹,也要區(qū)分其是左子樹還是右子樹。
滿二叉樹
高度為h,且含有2h?12^{h-1}2h?1個(gè)結(jié)點(diǎn)的二叉樹稱為滿二叉樹,即樹中每層都有最多的結(jié)點(diǎn)。
根結(jié)點(diǎn)從1開始編號(hào),若結(jié)點(diǎn)編號(hào)為 i,其雙親為?i/2?\lfloor i/2\rfloor?i/2? 其左孩子為2i,右孩子為2i+1。
完全二叉樹
性質(zhì):
- 若結(jié)點(diǎn)編號(hào) i≤?n/2?i \leq \lfloor n/2 \rfloori≤?n/2?,則結(jié)點(diǎn)為分支結(jié)點(diǎn),否則為葉子系結(jié)點(diǎn)。
- 葉子結(jié)點(diǎn)只可能在層次最大的兩層上出現(xiàn)。最有有一個(gè)度為1的結(jié)點(diǎn),且該結(jié)點(diǎn)只有左孩子。
- 若n為奇數(shù),則每個(gè)分支結(jié)點(diǎn)都有左右孩子
二叉排序樹
左子樹上所有結(jié)點(diǎn)的關(guān)鍵字都小于根結(jié)點(diǎn),右子樹上的所有結(jié)點(diǎn)關(guān)鍵字都大于根結(jié)點(diǎn)。
平衡二叉樹
樹上任一結(jié)點(diǎn)的左右子樹深度之差不超過1
二叉樹的性質(zhì)
- 非空二叉樹的葉子結(jié)點(diǎn)數(shù)等于度為2的結(jié)點(diǎn)數(shù)+1,即 n0=n2+1n_0=n_2+1n0?=n2?+1
- 非空二叉樹上第 k 層至多有2k?12^{k-1}2k?1個(gè)結(jié)點(diǎn)
- 高度為 h 的二叉樹至多有 2h?12^h-12h?1個(gè)結(jié)點(diǎn)
- 結(jié)點(diǎn)數(shù)為n的二叉樹有(2n)!n!(n+1)!\frac{(2n)!}{n!(n+1)!}n!(n+1)!(2n)!?種形態(tài)(卡特蘭數(shù))
完全二叉樹的性質(zhì)
- 結(jié)點(diǎn) i 的雙親編號(hào)為?i2?\lfloor \frac{i}{2} \rfloor?2i??,即當(dāng) i 為偶數(shù)時(shí)(左孩子),其雙親的編號(hào)為 i/2,當(dāng)i為奇數(shù)時(shí),其雙親編號(hào)為(i-1)/2。
- 推論:具有n個(gè)結(jié)點(diǎn)的完全二叉樹,編號(hào)最大的分支節(jié)點(diǎn)為?n2?\lfloor \frac{n}{2}\rfloor?2n??
- 結(jié)點(diǎn) i 所在層次為?log?2[i(2?1)+1]?=?log?2i?+1\lceil \log_2[i(2-1)+1]\rceil=\lfloor \log_2i\rfloor+1?log2?[i(2?1)+1]?=?log2?i?+1
三、二叉樹的儲(chǔ)存結(jié)構(gòu)
順序儲(chǔ)存
用一組地址連續(xù)的存儲(chǔ)單元依次自上而下、自左至右儲(chǔ)存完全二叉樹的結(jié)點(diǎn)元素。
對(duì)于一般的二叉樹,必須添加一些空結(jié)點(diǎn)。
鏈?zhǔn)酱鎯?chǔ)
在含有n個(gè)結(jié)點(diǎn)的二叉鏈表中,含有n+1個(gè)空鏈域
四、樹的儲(chǔ)存方式
雙親表示法
采用一組連續(xù)空間來儲(chǔ)存每個(gè)結(jié)點(diǎn),同時(shí)在每個(gè)結(jié)點(diǎn)中增設(shè)一個(gè)偽指針,指示其雙親結(jié)點(diǎn)在數(shù)組中的位置。根結(jié)點(diǎn)的下標(biāo)為0,其偽指針域?yàn)?1。
該存儲(chǔ)結(jié)構(gòu)可以很快得到每個(gè)結(jié)點(diǎn)的雙親位置,但求結(jié)點(diǎn)孩子時(shí)需要遍歷整個(gè)結(jié)構(gòu)。
孩子表示法
為每個(gè)結(jié)點(diǎn)創(chuàng)建一個(gè)鏈表,將該結(jié)點(diǎn)的孩子都用單鏈表接起來。再將所有結(jié)點(diǎn)順序存儲(chǔ)在一個(gè)數(shù)組中,數(shù)組中每個(gè)元素不但儲(chǔ)存結(jié)點(diǎn),還設(shè)置一個(gè)指針域,指向該結(jié)點(diǎn)的孩子鏈表。n個(gè)結(jié)點(diǎn)就有n個(gè)孩子鏈表(葉子結(jié)點(diǎn)的孩子鏈表為空表)。
這種方式尋找子女的操作非常直接,而尋找雙親的操作需要遍歷所有孩子鏈表。
孩子兄弟表示法(二叉樹表示法)
以二叉鏈表作為樹的存儲(chǔ)結(jié)構(gòu)。
二叉樹的左指針指向其第一個(gè)孩子,右指針指向其下一個(gè)兄弟。沿著右指針可以找到所有兄弟結(jié)點(diǎn)。
最大優(yōu)點(diǎn)是可以方便實(shí)現(xiàn)樹到二叉樹的轉(zhuǎn)換,易于找到結(jié)點(diǎn)的孩子。缺點(diǎn)是查找雙親結(jié)點(diǎn)比較麻煩,可以添加一個(gè)parent域指向父結(jié)點(diǎn)來解決。
五、二叉樹的遍歷
先序遍歷(preOrder、NLR)
void preOrder(BiTree T){if(T != NULL){visit(T);preOrder(T->lchild);preOrder(T->rchild);} }中序遍歷(inOrder、LNR)
void inOrder(BiTree T){if(T != NULL){inOrder(T->lchild);visit(T);inOrder(T->rchild);} }后序遍歷(postOrder、LRN)
無論哪種遍歷,訪問左右子樹的順序都是固定的,只是訪問根結(jié)點(diǎn)的順序不同。
每個(gè)結(jié)點(diǎn)都只訪問一次,時(shí)間復(fù)雜度均為O(n)。
遞歸工作棧的棧深恰為樹的高度。在最壞情況下,n個(gè)結(jié)點(diǎn)的樹高為n,空間復(fù)雜度為O(n)。
中序遍歷的非遞歸算法
關(guān)鍵是用棧記錄當(dāng)前結(jié)點(diǎn)的祖先
void inOrder(BiTree T){initStack(S);BiTree p = T; // 遍歷指針while( !isEmpty(S) || p ){if(p){push(S, p);p = p-> lchild; // 一路向左}else{ // 無法向左下繼續(xù)前進(jìn),訪問子樹根結(jié)點(diǎn),進(jìn)入根結(jié)點(diǎn)右子樹pop(S, p);visit(p);p = p->rchild;}} }先序遍歷的非遞歸算法
先序遍歷和中序遍歷的基本思想類似,只需把訪問結(jié)點(diǎn)操作放在入棧操作前
void inOrder(BiTree T){initStack(S);BiTree p = T;while( !isEmpty(S) || p ){if(p){visit(p);push(S, p);p = p-> lchild;}else{pop(S, p);p = p->rchild;}} }后序遍歷的非遞歸算法
從棧底結(jié)點(diǎn)再加上p結(jié)點(diǎn),剛好構(gòu)成從根結(jié)點(diǎn)到p結(jié)點(diǎn)的一條路徑。
層次遍歷
void leverOrder(BiTree T){initQueue(Q);BiTree p;enQueue(Q, T);while( !isEmpty(Q) ){deQueue(Q, p);visit(p);if(p->lchild != NULL)enQueue(Q, p->lchild);if(p->rchild != NULL)enQueue(Q, p->rchild);} }由遍歷序列構(gòu)造二叉樹
由二叉樹的先序序列和中序序列可以唯一確定一個(gè)二叉樹
在先序遍歷序列中,第一個(gè)結(jié)點(diǎn)一定是二叉樹的根結(jié)點(diǎn);而在中序遍歷中,根結(jié)點(diǎn)必然將中序序列分割成兩個(gè)子序列。
由二叉樹的后序序列和中序序列可以唯一確定一個(gè)二叉樹
后序序列的最后一個(gè)結(jié)點(diǎn)一定是二叉樹的根結(jié)點(diǎn)。
由二叉樹的層次遍歷和中序遍歷可以唯一確定一個(gè)二叉樹
六、線索二叉樹
增加兩個(gè)標(biāo)志域表示指針域是指向左(右)孩子還是指向前驅(qū)(后繼)。
以這種結(jié)點(diǎn)結(jié)構(gòu)構(gòu)成的二叉鏈表作為二叉樹的存儲(chǔ)結(jié)構(gòu),其中指示結(jié)點(diǎn)前驅(qū)及后繼信息的指針稱作線索。加上線索的二叉樹稱為線索二叉樹。
引入線索二叉樹能夠加快查找結(jié)點(diǎn)前驅(qū)和后繼的速度,像遍歷單鏈表那樣方便地遍歷二叉樹。
線索化的實(shí)質(zhì)就是遍歷一次二叉樹。
二叉線索化
使用指針pre指向剛剛訪問過的結(jié)點(diǎn),p指向正在訪問的結(jié)點(diǎn),即pre指向p的前驅(qū)。
在遍歷的過程中,檢查p的左指針是否為空,若為空就將其指向pre;同樣的檢查pre的右指針。
中序遍歷線索化代碼如下
為了方便,可以在二叉樹的線索鏈表上添加一個(gè)頭結(jié)點(diǎn),令其lchild域指向二叉樹的根結(jié)點(diǎn),其rchild域指向中序遍歷的最后一個(gè)結(jié)點(diǎn),再把中序遍歷的第一個(gè)結(jié)點(diǎn)的lchild域指向頭結(jié)點(diǎn)。這樣就為二叉樹建立了一個(gè)雙向線索鏈表。
建立先序線索二叉樹和后序線索二叉樹的代碼類似,只需變動(dòng)線索化改造的代碼段以及調(diào)用左右子樹遞歸函數(shù)的位置。
先序線索化與后序線索化最多有1個(gè)空指針域;中序線索化最多有2個(gè)空指針域。
遍歷線索二叉樹
中序線索二叉樹的結(jié)點(diǎn)隱含了線索二叉樹的前驅(qū)后繼信息,在對(duì)其進(jìn)行遍歷時(shí),只要先找到序列中的第一個(gè)結(jié)點(diǎn),然后依次找結(jié)點(diǎn)的后繼即可。
不含頭結(jié)點(diǎn)的中序線索二叉樹遍歷算法如下
對(duì)于先序線索二叉樹,如果有左孩子,則左孩子就是其直接后繼;如果無左孩子但是有右孩子,則右孩子就是其直接后繼;如果是葉結(jié)點(diǎn),其右鏈域指向了結(jié)點(diǎn)的后繼。
對(duì)于后繼線索二叉樹,其尋找后繼需要知道結(jié)點(diǎn)雙親,需采用帶標(biāo)志域的三叉鏈表作為存儲(chǔ)結(jié)構(gòu)。
七、森林
森林是m棵互不相交的樹的集合。只需把樹的根結(jié)點(diǎn)刪除就成了森林;反之,只要給m棵獨(dú)立的樹加上一個(gè)結(jié)點(diǎn),并把這m棵樹作為該結(jié)點(diǎn)的子樹,則森林就成了樹。
樹轉(zhuǎn)換為二叉樹
二叉樹和樹都可以用二叉鏈表作為存儲(chǔ)結(jié)構(gòu),給定一棵樹,可以找到唯一一棵二叉樹與之對(duì)應(yīng)。
對(duì)于一棵樹,每個(gè)結(jié)點(diǎn)左指針指向它的第一個(gè)孩子,右指針指向它在樹中的相鄰右兄弟。
這種規(guī)則下,根結(jié)點(diǎn)只有左孩子。
森林轉(zhuǎn)換為二叉樹
先將森林中的每一棵樹轉(zhuǎn)換為二叉樹,由于任何一棵樹對(duì)應(yīng)的二叉樹右子樹必空,只需把所有二叉樹的根結(jié)點(diǎn)用其右指針連接起來即可,即將所有樹的根結(jié)點(diǎn)視為兄弟結(jié)點(diǎn)。
二叉樹轉(zhuǎn)換為森林
若二叉樹非空,則二叉樹根的右子樹棵視為其余樹形成的二叉樹,將其與根斷開,以此類推,把所有子樹釋放。再將每棵二叉樹依次轉(zhuǎn)換成樹,就得到了原森林。
二叉樹轉(zhuǎn)換成樹或森林也是唯一的。
樹的遍歷
- 先根遍歷
若樹非空,先訪問根結(jié)點(diǎn),再依次遍歷根結(jié)點(diǎn)的每棵子樹。
先根遍歷的遍歷序列與對(duì)應(yīng)二叉樹的先序序列相同 - 后根遍歷(中根遍歷)
若樹非空,先依次遍歷根結(jié)點(diǎn)的每棵子樹,再訪問根結(jié)點(diǎn)。
后根遍歷的遍歷序列與對(duì)應(yīng)二叉樹的中序序列相同 - 層次遍歷
森林的遍歷
- 先序遍歷森林
若森林非空,按如下規(guī)則進(jìn)行遍歷:- 訪問森林中第一棵樹的根結(jié)點(diǎn)
- 先序遍歷第一棵樹中根結(jié)點(diǎn)的子樹森林
- 先序遍歷其余樹的森林
- 中序遍歷森林
若森林非空,按如下規(guī)則進(jìn)行遍歷 (實(shí)際上就是依次后根遍歷森林中的每一棵樹) :- 中序遍歷森林中第一棵樹的根結(jié)點(diǎn)的子樹森林
- 訪問第一棵樹的根結(jié)點(diǎn)
- 中序遍歷其余樹的森林
森林的先序遍歷和中序遍歷即為對(duì)應(yīng)二叉樹的先序和中序遍歷。
八、二叉排序樹(BST)
對(duì)于二叉排序樹(二叉查找樹),若左子樹非空,則左子樹的所有結(jié)點(diǎn)值均小于根結(jié)點(diǎn)的值,且也為一棵二叉排序樹;若右子樹非空,則右子樹的所有結(jié)點(diǎn)值均大于根結(jié)點(diǎn)的值,且也為一棵二叉排序樹。
二叉排序樹可以是空樹。
對(duì)二叉排序樹進(jìn)行中序遍歷,可以得到一個(gè)有序序列。
BST的插入
按照如下規(guī)則遞歸進(jìn)行:
插入的結(jié)點(diǎn)一定是一個(gè)新添加的葉結(jié)點(diǎn),且是查找失敗時(shí)路徑上訪問的最后一個(gè)結(jié)點(diǎn)的孩子。
若插入序列是有序的,則會(huì)形成一個(gè)傾斜的單支樹,導(dǎo)致二叉樹的性能顯著變壞。
BST的刪除
分為三種情況進(jìn)行:
BST的查找
從根結(jié)點(diǎn)開始,將給定值與根結(jié)點(diǎn)關(guān)鍵字比較:
二叉排序樹的查找效率,主要取決于樹的高度。若二叉樹左右子樹高度之差不超過1(平衡二叉樹),則平均查找長度為O(log?2n)O(\log_2n)O(log2?n),若二叉排序樹每個(gè)結(jié)點(diǎn)都只有一個(gè)結(jié)點(diǎn),平均查找長度為O(n)O(n)O(n)。
BST與二分查找
從查找過程看,二叉排序樹與二分查找十分相似,其平均時(shí)間性能差不多;但二分查找的判定樹唯一,二叉排序樹則不唯一。
從結(jié)構(gòu)的維護(hù)角度看,二叉排序樹無序移動(dòng)結(jié)點(diǎn),只需修改指針即可完成插入刪除操作,平均執(zhí)行時(shí)間是O(log?2n)O(\log_2n)O(log2?n);二分查找的對(duì)象是有序順序表,若插入刪除結(jié)點(diǎn),所花時(shí)間是O(n)O(n)O(n)。
若有序表是靜態(tài)查找表,宜采用順序表作為存儲(chǔ)結(jié)構(gòu),采用二分查找進(jìn)行查找操作。
若有序表是動(dòng)態(tài)查找表,宜采用二叉排序樹作為其邏輯結(jié)構(gòu)。
九、平衡二叉樹
為避免樹的高度增長過快,降低二叉排序樹的性能,規(guī)定插入和刪除二叉樹的結(jié)點(diǎn)時(shí),保證任意結(jié)點(diǎn)的左右子樹高度差不超過1。
以nhn_hnh?表示深度為h的平衡樹中含有的最少結(jié)點(diǎn)數(shù),有遞推公式nh=nh?1+nh?2+1n_h=n_{h-1}+n_{h-2}+1nh?=nh?1?+nh?2?+1,且n0=0n_0=0n0?=0,n1=1n_1=1n1?=1。
含有n個(gè)結(jié)點(diǎn)的平衡二叉樹最大深度為O(log?2n)O(\log_2n)O(log2?n),平均查找長度也為O(log?2n)O(\log_2n)O(log2?n)。
平衡因子:結(jié)點(diǎn)左右子樹的高度差,取值范圍為-1、0、1。
平衡二叉樹的插入
保持二叉樹平衡的基本思路:每當(dāng)插入或刪除一個(gè)結(jié)點(diǎn),檢查該結(jié)點(diǎn)到根結(jié)點(diǎn)路徑上的每個(gè)結(jié)點(diǎn)的平衡因子,調(diào)整不平衡的最小子樹的結(jié)構(gòu),在保持二叉排序樹特性的前提下,使之重新平衡。
對(duì)于一個(gè)新結(jié)點(diǎn),先按照普通二叉排序樹的規(guī)則進(jìn)行插入操作,再找到其最小不平衡樹,分情況進(jìn)行調(diào)整:
進(jìn)行一次向右的旋轉(zhuǎn)操作:將A的左孩子B向右上旋轉(zhuǎn),代替A成為根結(jié)點(diǎn);將A結(jié)點(diǎn)向右下旋轉(zhuǎn),成為B的右子樹的根結(jié)點(diǎn);而B的原右子樹則作為A的左子樹。
進(jìn)行一次向左的旋轉(zhuǎn)操作:將A 的右孩子B向左上旋轉(zhuǎn),代替A成為根結(jié)點(diǎn);將A結(jié)點(diǎn)向左下旋轉(zhuǎn)成為B的左子樹的根結(jié)點(diǎn);而B的原左子樹則成為A的右子樹。
進(jìn)行兩次旋轉(zhuǎn)操作,先左旋轉(zhuǎn)再右旋轉(zhuǎn):先將A結(jié)點(diǎn)的左孩子B的右子樹根結(jié)點(diǎn)C向左上旋轉(zhuǎn)提升到B結(jié)點(diǎn)的位置,此時(shí)問題轉(zhuǎn)化為情形1,只需將C結(jié)點(diǎn)再向右上旋轉(zhuǎn)提升到A結(jié)點(diǎn)的位置。
進(jìn)行兩次旋轉(zhuǎn)操作,先右旋轉(zhuǎn)再左旋轉(zhuǎn):先將A結(jié)點(diǎn)的右孩子B的左子樹根節(jié)點(diǎn)C向右上旋轉(zhuǎn)提升到B結(jié)點(diǎn)的位置,此時(shí)問題轉(zhuǎn)化為情景2,只需將C結(jié)點(diǎn)再向左上旋轉(zhuǎn)提升到A結(jié)點(diǎn)的位置。
十、哈夫曼樹
為樹中結(jié)點(diǎn)賦予一個(gè)數(shù)值,成為該結(jié)點(diǎn)的權(quán)。從根結(jié)點(diǎn)到任意結(jié)點(diǎn)的路徑長度lll(經(jīng)過的邊數(shù))與該節(jié)點(diǎn)上權(quán)值www的乘積稱為該結(jié)點(diǎn)的帶權(quán)路徑長度。樹中所有葉結(jié)點(diǎn)的帶權(quán)路徑長度之和稱為樹的帶權(quán)路徑長度。即WPL=∑i=1nwiliWPL=\sum_{i=1}^nw_il_iWPL=∑i=1n?wi?li?。
在含有n個(gè)帶權(quán)葉結(jié)點(diǎn)的二叉樹中,WPL最小的二叉樹稱為哈夫曼樹,也稱最優(yōu)二叉樹。
構(gòu)造哈夫曼樹
給定n個(gè)權(quán)值分別為w1,w2...wnw_1,w_2...w_nw1?,w2?...wn?的結(jié)點(diǎn),構(gòu)造算法如下:
從構(gòu)造過程可以看出哈夫曼樹具有如下特點(diǎn):
- 每個(gè)初始結(jié)點(diǎn)都稱為葉結(jié)點(diǎn),且權(quán)值越小的結(jié)點(diǎn)到根節(jié)點(diǎn)的路徑越長。
- 構(gòu)造過程新建了n-1個(gè)結(jié)點(diǎn),因此哈夫曼樹的總結(jié)點(diǎn)樹為2n-1。
- 哈夫曼樹中不存在度為1的結(jié)點(diǎn)。
哈夫曼編碼
若允許不同字符用不等長的二進(jìn)制位表示,稱這種編碼為可變長度編碼。
若任何一個(gè)編碼都不是其余編碼的前綴,則稱這種編碼為前綴編碼。
利用哈夫曼樹可以設(shè)計(jì)出總長度最短的二進(jìn)制前綴編碼。
總結(jié)
以上是生活随笔為你收集整理的王道408数据结构——第五章 树与二叉树的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 王道408数据结构——第四章 串(KMP
- 下一篇: 王道408数据结构——第六章 图