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 */
{
//估计此题比较繁琐,待更新
}