6.33③ 假定用兩個一維數組L[1..n]和R[1..n]作為
有n個結點的二叉樹的存儲結構, L[i]和R[i]分別指
示結點i的左孩子和右孩子,0表示空。試寫一個算法
判別結點u是否為結點v的子孫。
要求實現以下函數:
Status Dencendant(Array1D L,Array1D R,int n,int u,int v);
/* If node ‘u’ is the dencendant of node ‘v’, */
/* then return ‘TRUE’ else return ‘FALSE’. */
/* L[i] is the left child of the i_th node, */
/* R[i] is the right child of the i_th node */
/* in the Binary Tree which has n nodes. */
一維數組類型Array1D的定義:
typedef int Array1D[MAXSIZE];
/* If node 'u' is the dencendant of node 'v', */
/* then return 'TRUE' else return 'FALSE'. */
/* L[i] is the left child of the i_th node, */
/* R[i] is the right child of the i_th node */
/* in the Binary Tree which has n nodes. */
{
int flag = 0 ;
if ( !v ) {
return FALSE ;
}
else {
if (L [v ] ==u ) {
return TRUE ;
}
else {
flag + =Dencendant (L,R,n,u,L [v ] ) ;
}
if (R [v ] ==u ) {
return TRUE ;
}
else {
flag + =Dencendant (L,R,n,u,R [v ] ) ;
}
if (flag ) {
return TRUE ;
}
return FALSE ;
}
}
6.34③ 假定用兩個一維數組L[1..n]和R[1..n]作為
有n個結點的二叉樹的存儲結構, L[i]和R[i]分別指
示結點i的左孩子和右孩子,0表示空。試寫一個算法,
先由L和R建立一維數組T[1..n],使T中第i(i=1,2,…,
n)個分量指示結點i的雙親,然后判別結點u是否為結
點v的子孫。
要求實現以下函數:
Status Dencend(Array1D L, Array1D R, int n, int u, int v, Array1D T);
/******************************************************************/
一維數組類型Array1D的定義:
typedef int Array1D[MAXSIZE];
/******************************************************************/
{
int i,val ;
for (i = 1 ;i <=n ; ++i ) { //初始化數組T
T [i ] = 0 ;
}
for (i = 1 ;i <=n ; ++i ) { //建立數組T
T [L [i ] ] =i ;
T [R [i ] ] =i ;
}
val =T [u ] ;
while (val ! = 0 ) {
if (val ==v ) {
return TRUE ;
}
val =T [val ] ;
}
return FALSE ;
}
6.36③ 若已知兩棵二叉樹B1和B2皆為空,或者皆
不空且B1的左、右子樹和B2的左、右子樹分別相似,
則稱二叉樹B1和B2相似。試編寫算法,判別給定兩
棵二叉樹是否相似。
要求實現下列函數:
Status Similar(BiTree t1, BiTree t2);
/* 判斷兩棵二叉樹是否相似的遞歸算法 */
二叉鏈表類型定義:
typedef struct BiTNode {
TElemType data;
BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
/* 判斷兩棵二叉樹是否相似的遞歸算法 */
{
if ( !t1 &&!t2 ) { //如果兩棵樹同為空
return TRUE ;
}
else if (t1 &&t2 ) { //如果兩棵樹同為非空,則返回各個子樹的比較結果
return Similar (t1 - >lchild,t2 - >lchild ) &&Similar (t1 - >rchild,t2 - >rchild ) ;
}
else { //當兩棵樹存在不相似的時候時,即一棵為空,一棵非空
return FALSE ;
}
}
6.37③ 試直接利用棧的基本操作寫出先序遍歷的非遞歸
形式的算法(提示:不必按3.3.2節介紹的從遞歸到非遞歸
的方法而直接寫出非遞歸算法)。
要求實現下列函數:
void PreOrder(BiTree bt, void (*visit)(TElemType));
/* 使用棧,非遞歸先序遍歷二叉樹bt, */
/* 對每個結點的元素域data調用函數visit */
二叉鏈表類型定義:
typedef struct BiTNode {
TElemType data;
BiTNode *lchild,*rchild;
} BiTNode, *BiTree;
可用棧類型Stack的相關定義:
typedef BiTree SElemType; // 棧的元素類型
Status InitStack(Stack &S);
Status StackEmpty(Stack S);
Status Push(Stack &S, SElemType e);
Status Pop(Stack &S, SElemType &e);
Status GetTop(Stack S, SElemType &e);
/* 使用棧,非遞歸先序遍歷二叉樹bt, */
/* 對每個結點的元素域data調用函數visit */
{
//基本思路:根據工作棧原理,模擬遞歸的效果~
if (bt ) { //判斷樹空
SElemType p =bt ;
Stack S ;
InitStack (S ) ;
while ( !StackEmpty (S ) ||p ) {
while (p ) { //先序訪問根節點、遍歷左節點
visit (p - >data ) ;
Push (S,p ) ;
p =p - >lchild ;
}
if ( !StackEmpty (S ) ) { //遍歷右節點,不小心寫成while,錯了幾次~~
Pop (S,p ) ;
p =p - >rchild ;
}
}
}
}
6.38④ 同6.37題條件,寫出后序遍歷的非遞歸算法
(提示:為分辨后序遍歷時兩次進棧的不同返回點,
需在指針進棧時同時將一個標志進棧)。
要求實現下列函數:
void PostOrder(BiTree bt, void (*visit)(TElemType));
/* 使用棧,非遞歸后序遍歷二叉樹bt, */
/* 對每個結點的元素域data調用函數visit */
二叉鏈表類型定義:
typedef struct BiTNode {
TElemType data;
BiTNode *lchild,*rchild;
} BiTNode, *BiTree;
可用棧類型Stack的相關定義:
typedef struct {
BiTNode *ptr; // 二叉樹結點的指針類型
int tag; // 0..1
} SElemType; // 棧的元素類型
Status InitStack(Stack &S);
Status StackEmpty(Stack S);
Status Push(Stack &S, SElemType e);
Status Pop(Stack &S, SElemType &e);
Status GetTop(Stack S, SElemType &e);
/* 使用棧,非遞歸后序遍歷二叉樹bt, */
/* 對每個結點的元素域data調用函數visit */
{
Stack S ;
InitStack (S ) ;
SElemType e ;
BiTree p =bt ;
int tag = 0 ;
if (bt ) {
e. tag = 0 ;
while ( !StackEmpty (S ) ||p ==bt ) {
while (p &&!tag ) {
e. ptr =p ;
if (p - >lchild ) { //如果存在左子樹
p =p - >lchild ;
e. tag = 0 ;
}
else { //否則為右子樹
p =p - >rchild ;
e. tag = 1 ;
}
Push (S,e ) ;
} //while
GetTop (S,e ) ;
if ( !StackEmpty (S ) &&e. tag ) {
Pop (S,e ) ; //葉子結點出棧
p =e. ptr ;
visit (p - >data ) ; //輸出該結點
}
if ( !StackEmpty (S ) ) {
Pop (S,e ) ; //得到上一層結點
p =e. ptr ;
if (e. tag ) { //右子樹已經入棧
visit (p - >data ) ;
p = NULL ;
}
else { //右子樹沒入過棧
if (p - >rchild ) {
p =p - >rchild ;
tag = 0 ;
e. tag = 1 ;
Push (S,e ) ;
}
else { //沒有右子樹
visit (p - >data ) ;
p = NULL ;
}
}
}
else { //棧空則,p為NULL
p = NULL ;
}
} //while
} //if
}
6.41③ 編寫遞歸算法,在二叉樹中求位於先序序列中
第k個位置的結點的值。
要求實現下列函數:
TElemType PreOrder(BiTree bt, int k);
/* bt is the root node of a binary linked list, */
/* Preorder travel it and find the node whose */
/* position number is k, and return its value. */
/* if can’t found it, then return ‘#’. */
二叉鏈表類型定義:
typedef struct BiTNode {
TElemType data;
BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
if (bt ) {
if ( 1 ==count ) {
e =bt - >data ;
return 0 ;
}
else {
if (bt - >lchild ) {
--count ;
Get (bt - >lchild,count,e ) ;
}
if (bt - >rchild ) {
--count ;
Get (bt - >rchild,count,e ) ;
}
}
}
}
//沒想到可以自己添加函數~~方便很多
TElemType PreOrder (BiTree bt, int k )
/* bt is the root node of a binary linked list, */
/* Preorder travel it and find the node whose */
/* position number is k, and return its value. */
/* if can't found it, then return '#'. */
{
TElemType e ;
e = '#' ;
Get (bt,k,e ) ;
return e ;
}
6.42③ 編寫遞歸算法,計算二叉樹中葉子結點的數目。
要求實現下列函數:
void Leaves(BiTree bt, int &x);
/* Count the leaf node of the BiTree */
/* whose root node is bt to x. */
二叉鏈表類型定義:
typedef struct BiTNode {
TElemType data;
BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
/* Count the leaf node of the BiTree */
/* whose root node is bt to x. */
//題目並沒有說x初始化為0,害人不淺啊~~
{
int l1,l2 ;
if (bt ) {
if ( !bt - >lchild &&!bt - >rchild ) {
++x ;
}
else {
Leaves (bt - >lchild,x ) ;
Leaves (bt - >rchild,x ) ;
}
}
}
6.43③ 編寫遞歸算法,將二叉樹中所有結點的
左、右子樹相互交換。
要求實現下列函數:
void Exchange(BiTree &bt);
/* Exchange the left and right leaves of */
/* bitree whose root node is bt */
二叉鏈表類型定義:
typedef struct BiTNode {
TElemType data;
BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
/* Exchange the left and right leaves of */
/* bitree whose root node is bt */
{
BiTree temp ;
if (bt ) {
Exchange (bt - >lchild ) ;
Exchange (bt - >rchild ) ;
temp =bt - >lchild ;
bt - >lchild =bt - >rchild ;
bt - >rchild =temp ;
}
}
6.44④ 編寫遞歸算法:求二叉樹中以元素值
為x的結點為根的子樹的深度。
要求實現下列函數:
int Depthx(BiTree T, TElemType x);
/* 求二叉樹中以值為x的結點為根的子樹深度 */
二叉鏈表類型定義:
typedef struct BiTNode {
TElemType data;
BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
int l1,l2 ;
if ( !T ) {
return 0 ;
}
else {
l1 =Depth (T - >lchild ) + 1 ;
l2 =Depth (T - >rchild ) + 1 ;
return (l1 >l2 ) ?l1 :l2 ;
}
}
int Findx (BiTree T,BiTree &p,TElemType x ) {
if (T ) {
if (T - >data ==x ) {
p =T ;
return 0 ;
}
else {
Findx (T - >lchild,p,x ) ;
Findx (T - >rchild,p,x ) ;
}
}
}
int Depthx (BiTree T, TElemType x )
/* 求二叉樹中以值為x的結點為根的子樹深度 */
{
BiTree p = NULL ;
Findx (T,p,x ) ;
return Depth (p ) ;
}
6.46③ 編寫復制一棵二叉樹的非遞歸算法。
要求實現下列函數:
void CopyBiTree(BiTree T, BiTree &TT);
/* 基於層次遍歷的非遞歸復制二叉鏈表 */
二叉鏈表類型定義:
typedef char TElemType; // 設二叉樹的元素為char類型
typedef struct BiTNode {
TElemType data;
BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
可用隊列類型Queue的相關定義:
typedef BiTree QElemType; // 設隊列元素為二叉樹的指針類型
Status InitQueue(Queue &Q);
Status EnQueue(Queue &Q, QElemType e);
Status DeQueue(Queue &Q, QElemType &e);
Status GetHead(Queue Q, QElemType &e);
Status QueueEmpty(Queue Q);
/* 基於層次遍歷的非遞歸復制二叉鏈表 */
//基本思想:用兩個隊列來同步操作!
{
BiTree p,p2 ;
Queue Q,Q2 ;
if ( !T ) {
TT = NULL ;
return ;
}
TT = (BiTree ) malloc ( sizeof (BiTNode ) ) ;
InitQueue (Q ) ;
InitQueue (Q2 ) ;
EnQueue (Q,T ) ;
EnQueue (Q2,TT ) ;
while ( !QueueEmpty (Q ) ) {
DeQueue (Q,p ) ;
DeQueue (Q2,p2 ) ;
p2 - >data =p - >data ;
if (p - >lchild ) {
EnQueue (Q,p - >lchild ) ;
p2 - >lchild = (BiTree ) malloc ( sizeof (BiTNode ) ) ;
if ( !p2 - >lchild ) {
exit (OVERFLOW ) ;
}
EnQueue (Q2,p2 - >lchild ) ;
}
else {
p2 - >lchild = NULL ;
}
if (p - >rchild ) {
EnQueue (Q,p - >rchild ) ;
p2 - >rchild = (BiTree ) malloc ( sizeof (BiTNode ) ) ;
if ( !p2 - >rchild ) {
exit (OVERFLOW ) ;
}
EnQueue (Q2,p2 - >rchild ) ;
}
else {
p2 - >rchild = NULL ;
}
}
}
6.47④ 編寫按層次順序(同一層自左至右)遍歷二叉樹的算法。
要求實現下列函數:
void LevelOrder(BiTree bt, char *ss);
/* travel BiTree bt by level, Return result by ss. */
二叉鏈表類型定義:
typedef char TElemType; // 設二叉樹的元素為char類型
typedef struct BiTNode {
TElemType data;
BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
可用隊列類型Queue的相關定義:
typedef BiTree QElemType; // 設隊列元素為二叉樹的指針類型
Status InitQueue(Queue &Q);
Status EnQueue(Queue &Q, QElemType e);
Status DeQueue(Queue &Q, QElemType &e);
Status GetHead(Queue Q, QElemType &e);
Status QueueEmpty(Queue Q);
提示:可將遍歷元素的值(字符)依次置入ss,並最后以’\0′結尾。
也可以用下列字符串函數產生ss:
int sprintf(char *buffer, char *format [, argument, ...]);
char *strcat(char *dest, char *src);
/* travel BiTree bt by level, Return result by ss. */
{
int i = 0 ;
Queue Q ;
BiTree p ;
InitQueue (Q ) ;
if (bt ) {
EnQueue (Q,bt ) ;
while ( !QueueEmpty (Q ) ) {
DeQueue (Q,p ) ;
ss [i ++ ] =p - >data ;
if (p - >lchild ) {
EnQueue (Q,p - >lchild ) ;
}
if (p - >rchild ) {
EnQueue (Q,p - >rchild ) ;
}
}
ss [i ] = '\0' ;
}
}
6.49④ 編寫算法判別給定二叉樹是否為完全二叉樹。
要求實現下列函數:
Status CompleteBiTree(BiTree bt);
/* judge if the binary tree whose root is bt */
/* is a complete tree. */
二叉鏈表類型定義:
typedef struct BiTNode {
TElemType data;
BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
可用隊列類型Queue的相關定義:
typedef BiTree QElemType; // 設隊列元素為二叉樹的指針類型
Status InitQueue(Queue &Q);
Status EnQueue(Queue &Q, QElemType e);
Status DeQueue(Queue &Q, QElemType &e);
Status GetHead(Queue Q, QElemType &e);
Status QueueEmpty(Queue Q);
/* judge if the binary tree whose root is bt */
/* is a complete tree. */
/*基本思路
使用一個棧記錄按層次遍歷結果,當該結點非NULL時,左右子樹入棧
因此,如果該樹為完全二叉樹時棧內容為XXXX##(X表示非空),##之間不可能有非空結點
如果非完全二叉樹則內容可能為XXX#XX##也就是在NULL結點間仍有非空結點
只要非空結點與空結點分布情況即可求解
*/
{
int flag = 0,top = 0 ;
BiTree stack [ 100 ] ;
Queue Q ;
BiTree p ;
InitQueue (Q ) ;
if (bt ) {
EnQueue (Q,bt ) ;
while ( !QueueEmpty (Q ) ) {
DeQueue (Q,p ) ;
if (p ) {
EnQueue (Q,p - >lchild ) ;
EnQueue (Q,p - >rchild ) ;
stack [top ++ ] =p - >lchild ;
stack [top ++ ] =p - >rchild ;
}
} //while
while (top ) {
if (flag ) {
if (stack [ --top ] == NULL ) { //在非NULL結點前仍有NULL結點
return FALSE ;
}
}
else {
if (stack [ --top ] ! = NULL ) { //遇到第一個非NULL結點
flag = 1 ;
}
}
}
} //if
return TRUE ;
}
6.65④ 已知一棵二叉樹的前序序列和中序序列分別
存於兩個一維數組中,試編寫算法建立該二叉樹的二
叉鏈表。
要求實現以下函數:
void BuildBiTree(BiTree &bt, int ps, char *pre,
int is, char *ino, int n);
/* 當前要建立的子樹bt的元素總數為n,*/
/* 元素在前序序列pre的起始位置為ps,*/
/* 元素在中序序列ino的起始位置為is */
二叉鏈表類型定義:
typedef char TElemType;
typedef struct BiTNode {
TElemType data;
BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
int is, char *ino, int n )
/* 當前要建立的子樹bt的元素總數為n,*/
/* 元素在前序序列pre的起始位置為ps,*/
/* 元素在中序序列ino的起始位置為is */
{
//估計此題比較繁瑣,待更新
}