数据结构第三版第七章作业参考答案
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
void Ctree(BTNode *&t,ElemType A[],int i)
{ if (i>=MaxSize || A[i]==' ')
//若 i 无效或 A[i]为无效结点
t=NULL;
else
{
t=(BTNode *)malloc(sizeof(BTNode));
t->data=A[i-1];
BTNode *b;
CreateBTNode(b,"A(B(D(,G)),C(E,F))");
printf("b:");DispBTNode(b);printf("\n"); if
(commparent(b,e,e1,e2))
printf("%c †%c …%c 的Š‹Œ
\n",e,e1,e2);
f(b,t){t=NULL
f(b,t){|}~结点 b
€ t;
f(b->lchild,t1);f(b->rchild,t2);
t->lchild=t2;t->rchild=t1
若 b=NULL 其他情况
对应的算法如下:
BTNode *Swap(BTNode *b) { BTNode *t,*t1,*t2;
flag=0;
//t 指e右子树 //h置vofg的ij
}
} } while (top!=-1); return 0;
//栈不空时wx //其他情况时yz 0
}
7.8 假设二叉树采用二叉链存储结构,设计一个算法把树 b 的左、右子树
进行交换。要 求不破坏原二叉树。
解:交换二叉树的左、右子树的递归模型如下:
程序执行结果如下:
7.9 假设二叉树采用二叉链存储结构,设计一个算法判断一棵二叉树是否
是对称同构。 所谓对称同构是指其左右子树的结构是对称的。
解:判断二叉树是否对称同构的递归模型如下:
f(b)=true f(b)=false f(b)=f(b->lchild) & f(b->rchild)
若 b=NULL 或 b->lchild ƒ b->rchild 均为 NULL 若 b->lchild ƒ b->rchild „p一为 NULL 其他情况
if (b==NULL) t=NULL;
else { t=(BTNode *)malloc(sizeof(BTNode));
t->data=b->data; t1=Swap(b->lchild); t2=Swap(b->rchild); t->lchild=t2; t->பைடு நூலகம்child=t1; } return t; }
}
7.7 假设二叉树采用二叉链存储结构,t 指向根结点,p 所指结点为任一给 定的结点,设 计一个算法,输出从根结点到p 所指结点之间路径。
解:本题可以采用《教程》中例 7.8 的方法(只需对该算法作简单修改即
可
)
。
这
里
介
绍另一种方法,即非递归后序遍历树t(参见《教程》7.4.3 小节后序遍历非
递
归
} int Symmtree(BTNode *b) //判断二叉树 b †‡ˆ‰ { if (b==NULL)
return 1; else
return Symm(b->lchild,b->rchild); }
7.10 假设二叉树采用二叉链存储结构且所有结点的值不同,其中有包含值 为e、e1和e2 的结点,设计一个算法判断e是否为e1和e2的共同祖先。
//栈指针置初值
do { while (t)
//将 t 的所有左结点进栈
{ top++;
St[top]=t;
t=t->lchild;
} p=NULL; flag=1; while (top!=-1 && flag)
//p 指e当前结点的前一个已fg
的
结
点
//h置 t 的fgij为已fg过
{ t=St[top]; if (t->rchild==p) { if (t==s)
//|}一个~结点
或者设计成如下算法:
void Swap1(BTNode *b,BTNode *&b1)
{
if (b==NULL)
b1=NULL;
else
{ b1=(BTNode *)malloc(sizeof(BTNode));
b1->data=b->data;
Swap1(b->lchild,b1->rchild);
Swap1(b->rchild,b1->lchild);
}
}
//|}一个~结点
设计如下主函数:
void main() { BTNode *b,*b1;
CreateBTNode(b,"A(B(D(,G)),C(E,F))"); printf(" ‚前的二叉树:");DispBTNode(b);printf("\n"); b1=Swap(b); printf(" ‚后的二叉树:");DispBTNode(b1);printf("\n"); }
算
法
的
第
二
种方法),当后序遍历访问到s 所指结点时,此时栈St 中所有结点均为 p 所
指
结
点
的
祖
先
,
由这些祖先便构成了一条从根结点到p 所指结点之间的路径。对应的算法如
下:
int Path(BTNode *t,BTNode *s)
{ BTNode *St[MaxSize];
BTNode *p; int i,flag,top=-1;
当 t==NULL
f(t,A,i):由*t 结点 data 域值建立 A[i]元素; 其他情况
f(t->lchild,A,2*i);
f(t->rchild,A,2*i+1)
调用方式为:f(t,A,1)(A 的下标从 1 开始)。对应的算法
如下: void Ctree(BTNode *t,char A[],int i) { if (t!=NULL)
{ A[i]=t->data;
Ctree(t->lchild,A,2*i); Ctree(t->rchild,A,2*i+1); } else A[i]=' '; }
7.6 假设二叉树以二叉链存储,设计一个算法,判断一棵二叉树是否为完全二叉树。
解:根据完全二叉树的定义,对完全二叉树按照从上到下、从左到右的 次序遍历(层次 遍历)应该满足:
//顺序队首尾指针 //cm=1 表示二叉树为完全二叉树 //bj=1 表示到目前为止所有结点均有左右孩子
if (b!=NULL)
{ rear++;
Qu[rear]=b;
while (first!=rear) { first++;
//队列不空 //出队
p=Qu[first];
if (p->lchild==NULL) //*p 结点没有左孩子
{ bj=0;
if (p->rchild!=NULL)//没有左孩子但有右孩子, 违反(1),
cm=0;
}
else
//*p 结点有左孩子
{ if (bj==1)
//迄今为止,所有结点均有左右孩子
{ rear++;
//左孩子进队
Qu[rear]=p->lchild; if (p->rchild==NULL)//*p 有左孩子但没有右孩子,则 bj=0
Ctree(t->lchild,A,2*i);
//递归构造*t 的左子树
Ctree(t->rchild,A,2*i+1); //递归构造*t 的右子树
}
}
7.5 设计一个算法,将一棵以二叉链方式存储的二叉树 t 按顺序方式存储到数组 A 中。
解:由二叉树的顺序存储方式可知本题的递归模型f()如下:
f(t,A,i):A[i]=' ';
二叉树树 形表示。
答:由《教程》7.6 节的构造算法得到的二叉树的构造过程和二叉树如图 7.3 所示。
b 左:c 右:ed
a 左:cbed 右:hgijf
f 左:hgij 右:空
c 左:空 右:空
d
g
左:e
左:h
右:空 右:ij
e 左:空 右:空
h 左:空 右:空
i 左:空 右:j
j 左:空 右:空
解:先在以b 为根结点的二叉树中查找data 值为 e 的结点*p,若结点*p 是 e1 和 e2 的 祖先,则在以结点*p 为根的子树中一定能够找到e1 和 e2 对应的结点,其 中 FindNode 是二 叉树的基本运算算法,参见《教程》。本题的算法如下:
int commparent(BTNode *b,ElemType e,ElemType e1,ElemType e2) { BTNode *p,*p1,*p2;
p=FindNode(b,e); p1=FindNode(p,e1); p2=FindNode(p,e2); if (p1!=NULL && p2!=NULL)
return 1; else
return 0; }
设计如下主函数:
void main() { ElemType e='A',e1='D',e2='E';
列各题:
(1)画出二叉树 bt 的树形表示; (2)写出按先序、中序和后序遍历二叉树bt 所得到的 结点序列; (3)画出二叉树 bt 的后序线索树。
答:(1)二叉树 bt 的树形表示如图 7.1 所示。
a
a
b
b
c
d
c
d
e
f
g
e
f
g
h
i
h
i
j 图 7.1 二叉树 bt 的逻辑结构
j 图 7.2 二叉树 bt 的后线索
else printf("%c 不†%c …%c 的Š‹Œ
\n",e,e1,e2);
}
程序执行结果如下:
//k出当前的栈l元素 //右子树不mn或已ofg,fgp //当前fg的结点为qr的结 点,s出tu
{ for (i=0;i<=top;i++)
printf("%c ",St[i]->data);
return 1;
}
else
{ top--;
p=t;
//p 指e则ofg的结
}
}
else
{
t=t->rchild;
化树 (2)先序遍历序列:abcedfhgij 中序遍历序列:ecbhfdjiga 后序遍历序列:echfjigdba
(3)二叉树 bt 的后序遍历序列为 echfjigdba,则后序线索树如图 7.2 所示。 7.2 已知一棵二叉树的中序序列为 cbedahgijf,后序序列为 cedbhjigfa,给出该
对应的算法如下:
int Symm(BTNode *t1,BTNode *t2) //判断二叉树 t1 … t2 †‡ˆ‰ { if (t1==NULL && t2==NULL)
return 1; else if (t1==NULL || t2==NULL)
return 0; else
return (symm(t1->lchild,t2->lchild) & symm(t1->rchild,t2->rchild));
7.4 一棵具有 n 个结点的完全二叉树以顺序方式存储在数组 A 中。设计
一个算法构造 该二叉树的二叉链存储结构。
解:对于以顺序方式存储在数组 A(其大小为 MaxSize)中的一棵完全 二叉树,结点 A[i]的左孩子为 A[2i],右孩子为 A[2i+1]。采用递归方式创建该
二叉树的链接存储表示。对 应的算法如下:
图 7.3 二叉树的构造过程
7.3 设给定权集 w={2,3,4,7,8,9},试构造关于 w 的一棵哈夫曼树,并求其带权 路径长度 WPL。
答:本题的哈夫曼树如图 7.4 所示。
33
18
15
9
97
8
5
4
2
3
图 7.4 一棵哈夫曼树
其带权路径长度WPL=(9+7+8)×2+4×3+(2+3)×4=80。
(1)某结点没有左孩子,则一定无右孩子; (2)若某结点缺左或右孩子,则其所有后继一定无孩子。
若不满足上述任何一条,均不为完全二叉树。对应的算法如下:
int CompBTNode(BTNode *b)
{ BTNode *Qu[MaxSize],*p;
//定义一个队列,用于分层判断
int first=0,rear=0; int cm=1; int bj=1;
7.1 设二叉树 bt 的一种存储结构如下:
1 2 3 4 5 6 7 8 9 10 lchild 0 0 2 3 7 5 8 0 10 1 data j h f d b a c e g i rchild 0 0 0 9 4 0 0 0 0 0
tyh
在
这
里
使
用
结点编号作为指针域值,0 表示指针域值为空;data 为结点的数据域。请完成下
bj=0;
else
//*p 有右孩子,则继续判断
{
rear++; //右孩子进队
Qu[rear]=p->rchild;
}
}
else
//bj=0: 迄今为止,已有结点缺左或右孩子
cm=0
//此时*p 结点有左孩子,违反(2)
}
} //while
return cm;
}
return 1;
//空树当成特殊的完全二叉树