面试中关于二叉树的常见习题(持续更新)

这两天看了几篇关于面试中关于二叉树的常见问题,感到思路得到了很大的拓展,对递归的理解也更加深入,下面将问题及代码总结如下:

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;
}

持续更新中,敬请关注

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章