二叉树面试题

1.创建一颗二叉树

template<class T>
struct BinaryTreeNode
{
    BinaryTreeNode(const T& data)
    :_left(NULL)
    , _right(NULL)
    , _data(data)
    {}
    BinaryTreeNode* _left;
    BinaryTreeNode* _right;
    T _data;
};
void CreateBinaryTree(Node*& pRoot, const T* array, size_t size, size_t& index,const T& invalid)
    {
        if (index < size && array[index]!=invalid)
        {
            pRoot = new Node(array[index]);
            //创建pRoot的左子树
                CreateBinaryTree(pRoot->_left, array, size, ++index,invalid);
            //创建pRoot的右子树
                CreateBinaryTree(pRoot->_right, array, size, ++index,invalid);
        }
    }

2.前/中/后序遍历二叉树(递归)
(1)前序(遍历次序:根节点->左子树->右子树)

void _PreOrder(Node* pRoot)
    {
        if (pRoot)
        {
            cout << pRoot-> _data <<" ";
            _PreOrder(pRoot->_left);
            _PreOrder(pRoot->_right);
        }
    }

(2)中序(遍历次序:左子树->根节点->右子树)

void _InOrder(Node* pRoot)
    {
        if (pRoot)
        {
            _InOrder(pRoot->_left);
            cout << pRoot->_data << " ";
            _InOrder(pRoot->_right);
        }
    }

(3)后序(遍历次序:左子树->右子树->根节点)

void _PostOrder(Node* pRoot)
    {
        if (pRoot)
        {
            _PostOrder(pRoot->_left);
            _PostOrder(pRoot->_right);
            cout << pRoot->_data << " ";
        }
    }

3.前/中/后序遍历二叉树(非递归)

void _PreOrder_Nor(Node* pRoot)  //前序遍历非递归
    {
        stack<Node*> s;
        Node* pcur = pRoot;
        while (pcur || !s.empty())
        {
            while (pcur)
            {
                //访问根节点,根结点入栈
                cout << pcur->_data << " ";
                s.push(pcur);
                pcur = pcur->_left;
            }
            pcur = s.top();
            s.pop();
            //若pcur右子树存在,将其当成一颗新的树来访问
            pcur = pcur->_right;
        }
    }

void _InOrder_Nor(Node* pRoot)   //中序遍历非递归
    {
        stack<Node*> s;
        Node* pcur = pRoot;
        while (pcur || !s.empty())
        { //找最左边的结点,并保存路径上经过的所有节点
            while (pcur)
            {
                s.push(pcur);  //根结点入栈
                pcur = pcur->_left;
            }
            //取栈顶元素并访问
            pcur = s.top();
            cout << pcur->_data << " ";
            s.pop();
            //若pcur右子树存在,将其当成一颗新的树来访问
            pcur = pcur->_right;
        }

void _PostOrder_Nor(Node* pRoot)   //后序遍历非递归
    {
        stack<Node*> s;
        Node* prev = NULL;  //标记最近刚访问过的结点
        Node* pcur = pRoot;
        while (pcur || !s.empty())
        { //找最左边的结点,并保存路径上经过的所有节点
            while (pcur)
            {
                s.push(pcur);  //根结点入栈
                pcur = pcur->_left;
            }
            // 取栈顶元素并访问
            pcur = s.top();
            if (pcur->_right == NULL || pcur->_right == prev)
            {
                cout << pcur->_data << " ";
                prev = pcur;
                s.pop();
                pcur = NULL;
            }
            else
            {
                pcur = pcur->_right;
            }
        }
    }

4.层序遍历二叉树

void _LevelOrder_Nor(Node* pRoot) //层序遍历
    {
        //1 每一次打印一个结点,如果该节点有子结点,则把该结点的子结点放到一个队列的末尾
        //2 接下来到队列的头部取出最早进入队列的结点,打印,直到队列中所有的结点都被打印出来
        if (pRoot == NULL)
            return;
        deque<Node*> q;  //定义一个队列
        q.push_back(pRoot);  //根节点入队列
        while (q.size())   //判满
        {
            Node* pNode = q.front();  //取队头元素
            q.pop_front();
            cout << pNode->_data << " ";
            if (pNode->_left)
            q.push_back(pNode->_left);  //左子树入队列
            if (pNode->_right)
            q.push_back(pNode->_right);  //右子树入队列
        }
    }

5.求二叉树的高度

size_t _Height(Node* pRoot)  //求二叉树的深度
    {
        if (pRoot == NULL)
            return 0;
        if (pRoot->_left == NULL && pRoot->_right == NULL)
            return 1;
        size_t leftHeight = _Height(pRoot->_left);
        size_t rightHeight = _Height(pRoot->_right);
        return (leftHeight > rightHeight) ? leftHeight + 1 : rightHeight + 1;
    }

6.求叶子结点的个数(度为0的结点的个数)

    size_t _GetLeefCount(Node* pRoot)  //求二叉树叶子结点的个数
    {
        if (pRoot == NULL)
            return 0;
        if (pRoot->_left == NULL&&pRoot->_right == NULL)
            return 1;
        return _GetLeefCount(pRoot->_left) + _GetLeefCount(pRoot->_right);

7.判断一个结点是否在一棵二叉树中

Node* _Find(Node* pRoot,  const T& data)
    {
        if (pRoot == NULL)
            return NULL;
        if (pRoot->_data == data)
            return pRoot;
        Node* ret = NULL;
        if (ret = _Find(pRoot->_left, data))
            return ret;
            return  _Find(pRoot->_right, data);
    }

8.获取指定结点的双亲结点

Node* _GetParent(Node* pRoot,Node* pNode) //求一个结点的双亲结点
    {
        if (pRoot==NULL||(pRoot->_left == NULL&&pRoot->_right == NULL))
            return NULL;
        if (pRoot->_left == pNode || pRoot->_right == pNode)
            return pRoot;
        Node* ret = NULL;
        if (ret =_GetParent(pRoot->_left, pNode))  //不为空就返回
            return ret;
            return _GetParent(pRoot->_right, pNode);
    }

9.求二叉树的镜像

void _MirrorBinaryTree(Node* pRoot) //求二叉树的镜像
    {
        //1 先序遍历二叉树的每一个结点
        //2 如果遍历到的结点有子结点,就交换它的两个子结点,直到交换完所有非叶子结点的左右子结点
        if (pRoot == NULL)
            return;
        if (pRoot->_left == NULL&&pRoot->_right == NULL)
            return;
        Node* tmp = pRoot->_left;
        pRoot->_left = pRoot->_right;
        pRoot->_right = tmp;
        if (pRoot->_left)
            _MirrorBinaryTree(pRoot->_left);
        if (pRoot->_right)
            _MirrorBinaryTree(pRoot->_right);
    }

10.获取二叉树中第K层结点的个数

size_t _GetKLevelNodeCount(Node* pRoot, int K)
    {
        //若二叉树为空或者k小于0,返回0
        if (pRoot == NULL || K < 0)
            return 0;
        if (K == 1)  //只有一个根节点
            return 1;
        return _GetKLevelNodeCount(pRoot->_left, K - 1) + _GetKLevelNodeCount(pRoot->_right, K - 1);
    }

11.判断一棵二叉树是否是完全二叉树
这里写图片描述

bool _IsCompleteBinaryTree(Node* pRoot)
    {
        bool flag = false;
        queue<Node*> q;
        q.push(pRoot);
        Node* pNode = q.front();
        while (pNode)
        {
            //有右孩子无左孩子
            if (pNode->_left == NULL && pNode->_right != NULL)
                return false;
            //如果flag=true并且当前节点存在孩子
            if (flag == true && (pNode->_left || pNode->_right))
                return false;
            //如果当前结点少一个孩子
            if (pNode->_left == NULL || pNode->_right == NULL)
                flag = true;
            if (pNode->_left)
                q.push(pNode->_left);
            if (pNode->_right)
                q.push(pNode->_right);
            q.pop();
            if (!q.empty())
                pNode = q.front();
            else
            pNode = NULL;
        }
        return true;
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python二叉树面试题有很多种,以下是其中几个常见的面试题: 1. 二叉树的最大深度:这个问题要求计算给定二叉树的最大深度。可以使用递归的方法来解决,递归函数的定义是返回当前节点的深度,递归终止条件是节点为空时返回0,递归过程中比较左右子树的深度并返回较大值加1。时间复杂度为O(n),空间复杂度为O(n)。 2. 二叉树的前序遍历:这个问题要求按照前序遍历的顺序输出二叉树的节点值。可以使用递归或迭代的方法来解决。递归方法的思路是先输出当前节点的值,然后递归遍历左子树,最后递归遍历右子树。迭代方法可以使用栈来辅助实现,把根节点压入栈中,然后循环弹出栈顶节点,输出其值,并将其右子节点和左子节点依次压入栈中。时间复杂度为O(n),空间复杂度为O(n)。 3. 二叉树的层序遍历:这个问题要求按照层序遍历的顺序输出二叉树的节点值。可以使用队列来辅助实现。首先将根节点入队,然后循环直到队列为空,每次从队列中取出一个节点,输出其值,并将其左右子节点依次入队。时间复杂度为O(n),空间复杂度为O(n)。 以上是几个常见的Python二叉树面试题的解法,根据具体的问题要求和输入条件选择合适的解法即可。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [【编程之路】面试必刷TOP101:二叉树系列(23-30,Python实现)](https://blog.csdn.net/be_racle/article/details/125531755)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [【面试题8】二叉树的下一个节点](https://download.csdn.net/download/weixin_38589168/14035034)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值