这两天看了几篇关于面试中关于二叉树的常见问题,感到思路得到了很大的拓展,对递归的理解也更加深入,下面将问题及代码总结如下:
Q1:求二叉树第k层的结点个数
A:递归思路:空树返回0;只有根节点返回1;其余情况对左右子树进行递归,返回左右子树(k-1)层结点数之和
/*求二叉树第k层的结点个数*/
/*空树返回0,只有根节点返回1,其余情况对左右子树进行递归,返回左右子树(k-10层)结点数之和*/
Status GetKthLevelNum(BiTree T,int k){
int numL,numR;/*声明两个变量,分别代表左右子树结点个数*/
if(!T)
return 0;
if(k==1)
return 1;
else{
numL=GetKthLevelNum(T->Lchild,k-1);
numR=GetKthLevelNum(T->Rchild,k-1);
return (numL+numR);
}
}
Q2:比较两棵二叉树是否同构
A:递归思路:两棵树均为空,返回true;有一棵为空一棵不为空,返回false;其余情况递归判断两棵树的左子树和右子树,最后返回两个布尔值经过”与”之后的值
/*比较两棵二叉树是否同构*/
/*两棵树均为空,返回true;有一棵为空一棵不为空,返回false;其余情况递归判断两棵树的左子树和右子树,最后返回两个布尔值经过"与"之后的值*/
bool BiTreeCmp(BiTree T1,BiTree T2){
bool result1,result2;/*两个布尔值用来标记两棵树的子树是否同构*/
if(!T1&&!T2)
return true;
if((!T1&&T2)||(T1&&!T2))
return false;
else{
result1=BiTreeCmp(T1->Lchild,T2->Lchild);
result2=BiTreeCmp(T1->Rchild,T2->Rchild);
return (result1&&result2);
}
}
Q3:求二叉树镜像
A:递归思路:树返回ERROR;非空则递归处理左右子树,最后把处理后的pRight赋值给左子树,pLeft赋值给右子树即可
/*求二叉树镜像*/
/*空树返回ERROR;非空则递归处理左右子树,最后把处理后的pRight赋值给左子树,pLeft赋值给右子树即可*/
BiTree Mirror(BiTree T){
BiTree pLeft,pRight;
if(!T)
return ERROR;
else{
pLeft=Mirror(T->Lchild);
pRight=Mirror(T->Rchild);
T->Lchild=pRight;
T->Rchild=pLeft;
}
}
Q4:寻找最低公共祖先
/*查找节点,供FindCommonParent()进行调用*/
/*若为空树或节点为空,返回ERROR;节点为根节点时直接返回TRUE;其余情况分别在左右子树中递归查找即可*/
bool FindNode(BiTree T,BiTree pNode){
if(!pNode||!T)
return false;
if(pNode==T)
return true;
else{
/*在左子树中找到*/
if(FindNode(T->Lchild,pNode))
return true;
/*左子树中未找到,在右子树中递归查找*/
else
FindNode(T->Rchild,pNode);
}
}
/*寻找最低公共祖先*/
BiTree FindCommonParent(BiTree T,BiTree pNode1,BiTree pNode2){
if(!T||!pNode1||!pNode2)
return NULL;
/*若两节点一左一右,则最低公共祖先为根节点*/
if(FindNode(T->Lchild,pNode1)){
if(FindNode(T->Rchild,pNode2))
return T;
/*若节点2在左子树,则在左子树上递归寻找最低公共祖先*/
else
FindCommonParent(T->Lchild,pNode1,pNode2);
}
/*若节点1在右子树*/
else{
/*节点2在左子树,返回根节点*/
if(FindNode(T->Lchild,pNode2))
return T;
/*节点2在右子树,则在右子树上递归查找*/
else
FindCommonParent(T->Rchild,pNode1,pNode2);
}
}
Q5:求二叉树两节点间最大距离
A:
int Max(int num1,int num2){
return num1>num2? num1:num2;
}
/*求二叉树两节点间最大距离*/
/*二叉树两节点最大距离可能有三种: 0.左子树上的最大距离 1.右子树上最大距离 2.左右子树中的节点到根节点最大距离之和*/
int GetMaxDistance(BiTree T,int &MaxLeft,int &MaxRight){
if(!T)
return ERROR;
int maxLL,maxLR,maxRL,maxRR;/*maxLL为根节点左子树的左子树部分,其他以此类推*/
int MaxDistLeft,MaxDistRight;/*这两个变量指左右子树上的节点到根节点的最大距离*/
/*如果有左子树*/
if(T->Lchild){
/*递归求解左子树中的节点到根节点最大距离*/
MaxDistLeft=GetMaxDistance(T->Lchild,maxLL,maxLR);
/*求解左子树内部的最大距离*/
MaxLeft=Max(maxLL,maxLR)+1;
}
else{
MaxLeft=0;
MaxDistLeft=0;
}
if(T->Rchild){
MaxDistRight=GetMaxDistance(T->Rchild,maxRL,maxRR);
MaxRight=Max(maxRL,maxRR)+1;
}
else{
MaxRight=0;
MaxDistRight=0;
}
/*返回 左右子树最大距离 和 左右子树中的节点到根节点的距离之和 中的较大值*/
return Max(Max(MaxDistLeft,MaxDistRight),MaxLeft+MaxRight);
}
2016-05-22日更新
Q5:根据先序遍历和中序遍历重建二叉树
A:思路见代码注释
/*根据前中序遍历序列重建二叉树*/
/*基本思路:在先序遍历中找到首元素,其为树根节点;再找出中序遍历时根节点的位置,左边为左子树,右边为右子树。之后递归恢复其左右子树*/
/*接收三个参数,在此给出解释:pPreorder为先序遍历得到的字符串,pInorder同理,Nodenum为节点数*/
BiTree ReBuildTree(TElemType * pPreorder,TElemType * pInorder,int Nodenum) {
if(!pPreorder||!pInorder||Nodenum<=0)
return ERROR;
BiTree p=(BiTree)malloc(sizeof(BiTreeNode));
if(!p)
return ERROR;
/*将先序遍历的第一个赋值给p的数据域*/
p->data=pPreorder[0];
p->Lchild=NULL;
p->Rchild=NULL;
/*rootposition记录了根节点在中序遍历的位置*/
int rootposition=-1;
for(int i=0; i<Nodenum; i++) {
if(pInorder[i]==p->data) {
rootposition=i;
break;
}
}
int NodenumLeft=rootposition;
TElemType * pPreorderLeft=pPreorder+1;
TElemType * pInorderLeft=pInorder;
/*递归恢复左子树*/
p->Lchild=ReBuildTree(pPreorderLeft,pInorderLeft,NodenumLeft);
int NodenumRight=Nodenum-rootposition-1;
TElemType * pPreorderRight=pPreorder+NodenumLeft+1;
TElemType * pInorderRight=pInorder+NodenumLeft+1;
/*递归恢复右子树*/
p->Rchild=ReBuildTree(pPreorderRight,pInorderRight,NodenumRight);
return p;
}
持续更新中,敬请关注