今天完成了第六章的学习,这本书的课后题其他都有答案,但是算法设计没有,我发一下我这部分的的答案,希望能够共同研究其中是否有错,也算是为一起学习的同学提供一个可以共同学习的参考。
五、算法设计题
1. 试设计一个算法:分别采用递归和非递归算法后序遍历二叉树。
递归方法:
void PostOrderBiTree_1(BiTree BT) {
if(BT) {
PostOrderBiTree_1(BT->lchild);
PostOrderBiTree_1(BT->rchild);
cout<<BT->data;
}
}
非递归方法:
//非递归方法
void PostOrderBiTree_2(BiTree BT) {
BiTNode p=BT;//设置辅助指针p
InitStack_Sq(SqStack S);//初始化辅助栈S,用于存放BT的结点
Binode pre=NULL;//pre指向刚刚遍历的结点
while(p||S.top!=-1) {
if(p) {
Push_Sq(S,p);
p=p->lchild;//找到最左侧结点
} else {
GetTop_Sq(S,p);//读取刚刚访问的结点并赋值给p
if(p->rchild&&p->rchild!=pre) {
p=p->rchild;
/*若p有右孩子且刚没遍历(因为后序遍历中如果遍历过其右孩
子一定是上一次遍历到的)那么将p指向p的右孩子*/
} else {
Pop_Sq(S,p);
cout<<p->data<<" ";//出栈栈顶元素并赋值给p,并输出p的值
pre=p;//pre指向刚刚遍历的结点
p=NULL;//将p置空以便下次循环直接进else
}
}
}
}
2. 设计一个算法:交换一棵二叉树中每个结点的左孩子和右孩子
void TransBiTree(BiTree &BT){
BiTNode p=BT;
if(BT){
TransBiTree(BT->lchild);//递归交换左子树
TransBiTree(BT->rchild);//递归交换右子树
p=BT->lchild;
BT->lchild=BT->rchild;
BT->rchild=p;//交换左右孩子结点
}
}
3.设计一个算法:计算二叉树的叶子结点总数
int SumLeaves_BT(BiTree BT){
if(BT==NULL) return 0;//若为空树则返回0
int count=0;//初始化计数器
if(BT->lchild==NULL&&BT->rchild==NULL)
count=1;//若为叶子节点则返回1
count+=SumLeaves_BT(BT->lchild);//递归寻找左子树
count+=SumLeaves_BT(BT->rchild);//递归寻找右子树
return count;//返回总叶子结点数
}
}
4.设计一个算法:判断一棵二叉树是否为完全二叉树
bool CheckComBiTree(BiTree BT){
if(BT==NULL) return TRUE;//空树为完全二叉树
InitQueue_Sq(SqQueue Q);//初始化辅助队列Q
EnQueue_Sq(Q,BT);//让根节点BT入队
BiTNode p;//设置辅助结点p
while(Q.front!=Q.rear){//循环至队空
DeQueue_Sq(Q,p);//队头出队并赋值给p
if(p!=NULL){//若p非空则让p的左右孩子入队(层序遍历)
EnQueue_Sq(Q,p->lchild);
EnQueue_Sq(Q,p->rchild);
}else{//当遇到队列中第一个空结点时,如果后面还有非空结点那么就不是完全二叉树
while(Q.front!=Q.rear){
DeQueue_Sq(Q,p);
if(p) return FALSE;
}
}
}
return TRUE;
}
5.设计一个算法:在二叉树中查找值为e的结点,并输出e的所有祖先。 假设二叉树中值为e的结点不多于一个。
bool PrintAncestors_BT(BiTree BT,ElemType e){//bool返回值为方便if语句的判断
if(!BT) return FALSE;//若为空树则返回false
if(BT->data==e) return TRUE;//若找到值为e的结点则返回true
if(PrintAncestors_BT(BT->lchild,p)||PrintAncestors_BT(PrintAncestors_BT,p)){
cout<<BT->data;<<" ";
//递归搜索左右子树,判断e是否在这棵树里,也顺便输出了其祖先的值
return TRUE;//若在则返回true
}
return FALSE;//若e不在该树则返回false
}
感觉树的算法设计比起前面的那些链表,栈什么的更加难以构思,需要积累一些设计经验才能更好更快的设计出算法。上面这几个算法可以看出来树的算法设计比较常用递归的方式,这也是由树的结构决定的。因为没有双亲结点的指针所以关于树的问题就比较难解,我还是得再攒攒经验啊...