二叉树oj题

二叉树的层序遍历

思路分析:

题目要求从上而下并且为从左到右依次打印出每层的值~,这也称为二叉树的广度优先搜索(BFS),BFS通常借助队列来实现"~而且这里是需要使用二维数组返回的~

处理流程:

如果根为空那么就会直接返回了~

不为空就先把根入队的, 计数器size++;为这一层节点的个数~然后将这一层pop掉的同时将这个节点的左右入队~这里需要一个临时的节点变量来记录这个节点的数据~然后将队列头节点pop掉~头节点pop掉左右孩子继续入队~在pop的同时将数据放入数组中存起来~

class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        /* 根据函数返回值定义存储结果的变量 */
        vector<vector<int>> result;
        /* 定义一个队列用于存储节点的数据 */
        queue<TreeNode*> que;
        /* 判空 */
        if(root != NULL) que.push(root);

        /* 开始层序遍历 */
        while(!que.empty()) {
            /* 计算队列的大小也即有多少个孩子 */
            int size = que.size();
            /* 定义一个临时vector 存储每一层 */
            vector<int> vec;
            /* 层序遍历 */
            for(int i = 0; i < size; i++) {
                /* 获取第一个节点数据 */
                TreeNode* node = que.front();
                que.pop();

                vec.push_back(node->val);
                if(node->left != NULL) que.push(node->left);
                if(node->right != NULL) que.push(node->right);
            }
            /* 将一层的数据保存 */
            result.push_back(vec);
        }
        return result;
    }

2.最近公共祖先

思路分析:

    这个题是要我们找给定两个节点的最近公共祖先~直接画图分析

 第一种情况为要找的两个节点分别在根节点的左边和右边~如果是这样那么这个根节点就为他们的最近公共祖先~

第二种情况就是要找的两个节点都在左边或者右边,这种情况就需要再到左树或者右树查找~

第三中情况就是最近公共节点为自己本身,这个可以在开始就判断一下~

class Solution {
public:
   //查询p这个节点是否在左子树,或者右子树~
    bool find(TreeNode* root, TreeNode* p)
    {
        if(root==nullptr)
        {
            return false;
        }
        if(root==p)
        {
            return true;
        }
        return find(root->left,p)||find(root->right,p);
    }
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
    if(!root)
    {
        return nullptr;
    }
    if(root==p||root==q)
    {
        return root;
    }
    bool pInleft,pInright,qInleft,qInright;
    //观察p是否在左子树。
    pInleft=find(root->left,p);
    //如果没有在左子树,那么就在右子树
    pInright=!pInleft;
    //q节点也是一样~~
    qInleft=find(root->left,q);
    qInright=!qInleft;
    //找到这里有可能两个就在两边,直接就返回就可以~
    if((pInleft&&qInright)||(qInleft&&pInright))
    {
        return root;
    }
    else if(qInleft&&pInleft)
    {
        return lowestCommonAncestor(root->left,p,q);
    }
    else if(qInright&&pInright)
    {
        return lowestCommonAncestor(root->right,p,q);
    }
    return nullptr;
    }
};

3.二叉搜索树与双向链表

思路分析:

    题目要求将这个树转化为升序的双向链表~既然是升序那么这里可以考虑到中序遍历打印出来是升序~但是这里注意不能创建新的节点~ 

class Solution {
public:
    void Inorder(TreeNode*root,TreeNode*& prev)
    {
        if(root==nullptr)
        {
            return ;
        }
        //中序遍历直接去找最左边的节点~为空时就开始返回~
        Inorder(root->left,prev);
        //将最左边节点的前驱指针指向nullptr,
            root->left=prev;
        //这个是防止第一次空指针时候出现问题~
        //如果不是空指针那么说明已经到了中间部分的节点~
        //就开始处理这个随着prev指针走向的右边或者左边
            if(prev)
            {
                prev->right=root;
            }
        //因为不能创建节点就让prev递归走向原来的根节点~
        prev=root;
          
        Inorder(root->right,prev);
    }
    TreeNode* Convert(TreeNode* pRootOfTree) {
        if(!pRootOfTree)
        {
            return nullptr;
        }
        TreeNode*prev=nullptr;
        //递归去中序遍历~
        Inorder(pRootOfTree,prev);
        TreeNode*head=pRootOfTree;
        while(head->left)
        {
            head=head->left;
        }
        return head;
    }
};

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值