二叉树面试题

将二叉查找树变为有序双向链表:

        考虑,二叉查找树的特点是左子树比根节点小,根节点又比右子树小。所以要把二叉查找树变为有序的双向链表,就要把左子树连接到它的前一个结点,右子树作为后一个结点,递归的进行下去。如图所示:


问题解决:

        按照中序遍历二叉树,如果根节点为空,直接返回;

        如果左子树为空,修改它的左指针指向上一次访问的结点(*last)(由于是中序遍历,上一次访问的结点就是前一个结点);否则递归的处理该节点的左子树;

        判断上一个结点(*last)是否为空,若为空,直接赋值为当前结点;否则,将(*last)的右指针指向当前结点的同时更新*last;

        最后,如果右子树不为空,递归的处理右子树。

代码实现:

void ConvertTree(TreeNode* root, TreeNode** last)
{
    if(root == NULL)                                                                                                                 
        return;
    if(root->lchild != NULL)
        ConvertTree(root->lchild, last);
    root->lchild = *last;
    if(*last != NULL)
        (*last)->rchild = root;
    (*last) = root;
    if(root->rchild != NULL)
        ConvertTree(root->rchild, last);
    return;
}

判断两树是否结构相同:

问题解决:

1.若两树都为空,返回1;

2.若一个为空,一个不为空,返回0;

3.递归的进行判断左子树和右子树,返回与结果。

代码实现:

int IsOneStruct(TreeNode* root1, TreeNode*root2)
{
    if(root1 == NULL && root2 == NULL)
        return 1;
    else if(root1 == NULL || root2 == NULL)
        return 0;
    return IsOneStruct(root1->rchild, root2->rchild) && IsOneStruct(root1->lchild, root2->lchild);
}

判断一个树是否是平衡二叉树:

问题解决:

平衡二叉树数每个子树的左右高度差不超过一。设置一个输出型参数记录每个树的高度,

若该树为空,返回1,同时令高度为0;

否则,利用递归判断左右子树是否为平衡二叉树,

    若左右子树均为平衡二叉树,且高度差小于等于1,返回1.

int IsAVLTree(TreeNode* root, int* height)
{
    if(root == NULL)
    {                                                                                                                                
        (*height) = 0;
        return 1;
    }   
    int rresult, lresult;
    //分别记录左右子树高度
    int lheight;
    int rheight;
    rresult = IsAVLTree(root->rchild, &rheight);
    lresult = IsAVLTree(root->lchild, &lheight);
    *height = lheight > rheight ? lheight+1 : rheight+1;
    if(abs(rheight - lheight) <= 1 && rresult && lresult)
        return 1;
    else
        return 0;
}                                                                                                                                    

寻找公共祖先结点:

int FindNode(TreeNode* root, TreeNode* node)
{
    if(root == NULL)                                                                                                                 
        return 0;
    if(root == node)
        return 1;
    if(root->lchild == node || root->rchild == NULL)
        return 1;
    return FindNode(root->lchild, node) || FindNode(root->rchild, node);
}
TreeNode* FindCommonParent(TreeNode* root, TreeNode* node1, TreeNode* node2)
{
    if(root == NULL)
        return NULL;
    if((FindNode(root->rchild, node1)&&(FindNode(root->lchild, node2))) || ((FindNode(root->lchild, node2)&&FindNode(root->rchild, no
    {
        return root;
    }                                                                                                                                
    TreeNode* r1 = FindCommonParent(root->rchild, node1, node2);
    TreeNode* r2 = FindCommonParent(root->lchild, node1, node2);
    return r1 != NULL ? r1 : r2;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值