• 二叉树(面试易考题整理)


     涉及易考题目如下:

    1. 求二叉树中的节点个数
    2. 求二叉树的深度
    3. 求二叉树第K层的节点个数
    4. 求二叉树中叶子节点的个数
    5. 判断两棵二叉树是否结构相同
    6. 判断二叉树是不是平衡二叉树
    7. 求二叉树的镜像
    8. 判断二叉树是不是完全二叉树

     二叉树节点定义:

    struct BinaryTreeNode
    {
        int   _Value;
        BinaryTreeNode* _pLeft;
        BinaryTreeNode* _pRight;
    };
    

     1、求二叉树中的节点个数

    递归解法:
    (1)如果二叉树为空,节点个数为0
    (2)如果二叉树不为空,二叉树节点个数 = 左子树节点个数 + 右子树节点个数 + 1
    参考代码如下:

    int GetNodeNum(BinaryTreeNode * pRoot)
    {
        if(pRoot == NULL) // 递归出口
            return 0;
        return GetNodeNum(pRoot->_pLeft) + GetNodeNum(pRoot->_pRight) + 1;
    }
    

    2、求二叉树的

    递归解法:
    (1)如果二叉树为空,二叉树的深度为0
    (2)如果二叉树不为空,二叉树的深度 = max(左子树深度, 右子树深度) + 1
    参考代码如下:

    int GetDepth(BinaryTreeNode * pRoot)
    {
        if(pRoot == NULL) // 递归出口
            return 0;
        int depthLeft = GetDepth(pRoot->_pLeft);
        int depthRight = GetDepth(pRoot->_pRight);
        return depthLeft > depthRight ? (depthLeft + 1) : (depthRight + 1); 
    }
    

    3、求二叉树第K层的节点个数

    递归解法:
    (1)如果二叉树为空或者k<1返回0
    (2)如果二叉树不为空并且k==1,返回1
    (3)如果二叉树不为空且k>1,返回左子树中k-1层的节点个数与右子树k-1层节点个数之和
    参考代码如下:

    int GetNodeNumKthLevel(BinaryTreeNode * pRoot, int k)
    {
        if(pRoot == NULL || k < 1)
            return 0;
        if(k == 1)
            return 1;
        int numLeft = GetNodeNumKthLevel(pRoot->_pLeft, k-1); // 左子树中k-1层的节点个数
        int numRight = GetNodeNumKthLevel(pRoot->_pRight, k-1); // 右子树中k-1层的节点个数
        return (numLeft + numRight);
    }
    

    4、求二叉树中叶子节点的个数

    递归解法:
    (1)如果二叉树为空,返回0
    (2)如果二叉树不为空且左右子树为空,返回1
    (3)如果二叉树不为空,且左右子树不同时为空,返回左子树中叶子节点个数加上右子树中叶子节点个数
    参考代码如下:

    int GetLeafNodeNum(BinaryTreeNode * pRoot)
    {
        if(pRoot == NULL)
            return 0;
        if(pRoot->_pLeft == NULL && pRoot->_pRight == NULL)
            return 1;
        int numLeft = GetLeafNodeNum(pRoot->_pLeft); // 左子树中叶节点的个数
        int numRight = GetLeafNodeNum(pRoot->_pRight); // 右子树中叶节点的个数
        return (numLeft + numRight);
    }
    

    5、判断两棵二叉树是否结构相同

    不考虑数据内容。结构相同意味着对应的左子树和对应的右子树都结构相同。
    递归解法:
    (1)如果两棵二叉树都为空,返回真
    (2)如果两棵二叉树一棵为空,另一棵不为空,返回假
    (3)如果两棵二叉树都不为空,如果对应的左子树和右子树都同构返回真,其他返回假
    参考代码如下:

    bool StructureCmp(BinaryTreeNode * pRoot1, BinaryTreeNode * pRoot2)
    {
        if(pRoot1 == NULL && pRoot2 == NULL) // 都为空,返回真
            return true;
        else if(pRoot1 == NULL || pRoot2 == NULL) // 有一个为空,一个不为空,返回假
            return false;
        bool resultLeft = StructureCmp(pRoot1->_pLeft, pRoot2->_pLeft); // 比较对应左子树 
        bool resultRight = StructureCmp(pRoot1->_pRight, pRoot2->_pRight); // 比较对应右子树
        return (resultLeft && resultRight);
    } 
    

    6、 判断二叉树是不是平衡二叉树

    递归解法:
    (1)如果二叉树为空,返回真
    (2)如果二叉树不为空,如果左子树和右子树都是AVL树并且左子树和右子树高度相差不大于1,返回真,其他返回假
    参考代码:

    bool IsAVL(BinaryTreeNode * pRoot, int & height)
    {
        if(pRoot == NULL) // 空树,返回真
        {
            height = 0;
            return true;
        }
        int heightLeft;
        bool resultLeft = IsAVL(pRoot->_pLeft, heightLeft);
        int heightRight;
        bool resultRight = IsAVL(pRoot->_pRight, heightRight);
        if(resultLeft && resultRight && abs(heightLeft - heightRight) <= 1) // 左子树和右子树都是AVL,并且高度相差不大于1,返回真
        {
            height = max(heightLeft, heightRight) + 1;
            return true;
        }
        else
        {
            height = max(heightLeft, heightRight) + 1;
            return false;
        }
    }

    7、求二叉树的镜像

    递归解法:
    (1)如果二叉树为空,返回空
    (2)如果二叉树不为空,求左子树和右子树的镜像,然后交换左子树和右子树
    参考代码如下:

    BinaryTreeNode * Mirror(BinaryTreeNode * pRoot)
    {
        if(pRoot == NULL) // 返回NULL
            return NULL;
        BinaryTreeNode * pLeft = Mirror(pRoot->_pLeft); // 求左子树镜像
        BinaryTreeNode * pRight = Mirror(pRoot->_pRight); // 求右子树镜像
            // 交换左子树和右子树
        pRoot->_pLeft = pRight;
        pRoot->_pRight = pLeft;
        return pRoot;
    }
    

    8、判断二叉树是不是完全二叉树

    若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全
    二叉树。
    有如下算法,按层次(从上到下,从左到右)遍历二叉树,当遇到一个节点的左子树为空时,则该节点右子树必须为空,且后面遍历的节点左
    右子树都必须为空,否则不是完全二叉树。

    bool IsCompleteBinaryTree(BinaryTreeNode * pRoot)
    {
        if(pRoot == NULL)
            return false;
        queue<BinaryTreeNode *> q;
        q.push(pRoot);
        bool mustHaveNoChild = false;
        bool result = true;
        while(!q.empty())
        {
            BinaryTreeNode * pNode = q.front();
            q.pop();
            if(mustHaveNoChild) // 已经出现了有空子树的节点了,后面出现的必须为叶节点(左右子树都为空)
            {
                if(pNode->_pLeft != NULL || pNode->_pRight != NULL)
                {
                    result = false;
                    break;
                }
            }
            else
            {
                if(pNode->_pLeft != NULL && pNode->_pRight != NULL)
                {
                    q.push(pNode->_pLeft);
                    q.push(pNode->_pRight);
                }
                else if(pNode->_pLeft != NULL && pNode->_pRight == NULL)
                {
                    mustHaveNoChild = true;
                    q.push(pNode->_pLeft);
                }
                else if(pNode->_pLeft == NULL && pNode->_pRight != NULL)
                {
                    result = false;
                    break;
                }
                else
                {
                    mustHaveNoChild = true;
                }
            }
        }
        return result;
    }
    
  • 相关阅读:
    Nginx详解十四:Nginx场景实践篇之代理服务
    PyCharm设置字体风格
    PyCharm+SVN
    Nginx详解十三:Nginx场景实践篇之防盗链
    Nginx详解十二:Nginx场景实践篇之跨站访问相关
    Nginx详解十一:Nginx场景实践篇之Nginx缓存
    Nginx详解十:Nginx场景实践篇之Nginx静态资源场景配置
    Nginx详解九:Nginx基础篇之Nginx的访问控制
    浅谈控件(组件)制作方法一(附带一delphi导出数据到Excel的组件实例)(原创)
    切断数据感知控件,大大提升软件运行速度
  • 原文地址:https://www.cnblogs.com/-zyj/p/5694787.html
Copyright © 2020-2023  润新知