23.10.17 彭波数据结构第六章习题 算法设计

文章讲述了如何使用递归和非递归方法后序遍历二叉树,以及交换二叉树节点的左右孩子、计算叶子节点数、判断是否为完全二叉树和查找值的祖先等算法。作者强调树算法设计的挑战性和递归在其中的应用。
摘要由CSDN通过智能技术生成

今天完成了第六章的学习,这本书的课后题其他都有答案,但是算法设计没有,我发一下我这部分的的答案,希望能够共同研究其中是否有错,也算是为一起学习的同学提供一个可以共同学习的参考。

五、算法设计题

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 
} 

感觉树的算法设计比起前面的那些链表,栈什么的更加难以构思,需要积累一些设计经验才能更好更快的设计出算法。上面这几个算法可以看出来树的算法设计比较常用递归的方式,这也是由树的结构决定的。因为没有双亲结点的指针所以关于树的问题就比较难解,我还是得再攒攒经验啊...

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值