二叉树OJ题(C++实现)

简介: 二叉树OJ题(C++实现)

1.二叉树的层序遍历

二叉树的层序遍历 OJ连接


e1e8d9e693af445d91ade6844e06575f.png主要思路是借助一个队列,将每一层的数据以size统计,当size为0时说明该层数据已经输入完,将这一层的数据传入vector中,再通过push_back 传入 vector< vector< int >中

991047647da34185b2570480978b177f.png

class Solution {
public:
    string tree2str(TreeNode* root) {
        if(root==NULL)
        {
            return "";
        }
         string s;
        //to_string 将任意类型转换为字符串
         s=to_string(root->val);
         //只有左右子树都为空时 左子树才不加括号
        if(root->left==NULL&&root->right==NULL)
        {
             //;
        }
        else 
        {
        s+='(';
        s+= tree2str(root->left);
        s+=')';
        }
        //若右子树为空 ,则不加括号
     if(root->right!=NULL)
     {
         s+='(';
         s+=  tree2str(root->right);
         s+=')';
     }
        return s;
    }
};

2. 二叉树的最近公共祖先

二叉树的最近公共祖先OJ连接


0ec392fba81a49e98e8356ff316152ee.png


共分为三种情况


第一种情况

1fceef3208cf461c8fe8f2d1b64e5a04.png


寻找节点7与0的公共祖先为 根节点3

节点7在根的左子树,而节点0在根的右子树


若一个在根的左子树,一个在根的右子树 , 则根就为公共祖先


第二种情况

以左子树为例


a66a1117b4b541aaa6eb95af46113bd4.png


节点7与节点4属于根的左子树

节点7与节点4的最近公共祖先为 他们共同的父节点2


cb52a7363d25487cb9bd132c5171c8d2.png


若两个节点都在根的左子树,则递归根的左子树的节点为根,判断两个节点是否为根的左右子树,直到寻找到


第三种情况


54f0793ad31d4b72aa65e19f0d0d481e.png


节点5与节点4的最近公共祖先是节点5

节点5与节点4都属于根的左子树

若两个节点都在根的左子树,则递归根的左子树的节点为根,当这个根为两个节点其中一个时,则这个节点就为公共祖先


由于第二种和第三种情况,节点都在左子树上,所以可以看作是一种情况

class Solution {
public:
bool istree(TreeNode*root,TreeNode*x)
{
      if(root==NULL)
      {
          return false;
      }
      if(root==x)
      {
          return true;
      }
      return istree(root->left,x)|| istree(root->right,x);
}
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
          if(root==NULL)
          {
              return NULL;
          }
          //若p/q节点有一个节点为根节点,则最近公共祖先为根节点
          if(p==root||q==root)
          {
              return root;
          }
           bool pleft=istree(root->left,p);
           bool pright=!pleft;
           bool qleft=istree(root->left,q);
           bool qright=!qleft;
           //两个节点分别在左右子树上
           if( (pleft&&qright)|| (pright&&qleft))
           {
               return root;
           }
           //两个节点都在根的左子树上,则递归左子树
           else if(pleft&&qleft)
           {
                return lowestCommonAncestor(root->left,p,q);
           }
           //两个节点都在根的右子树上,则递归右子树
           else 
           {
              return lowestCommonAncestor(root->right,p,q);
           }
    }
};

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

二叉搜索树与双向链表OJ连接

e3a94d302115446f9e200e4565467b27.png


prev节点用于记录cur节点的上一个


72bb90f5ac4f4ea2a00638162af4fd51.png


当cur节点值为4时,prev=NULL,因为4属于双向链表第一个节点值 所以没必要链接

只需更新prev的值为cur值即可


16310f91d0204d90846c230ea075744f.png


prev值不为空时,将cur节点与prev节点进行连接,并更新prev节点值

prev->right=cur

cur->left=prev

class Solution {
  public:
  void inconvert(TreeNode*cur,TreeNode*&prev)
  //因为prev是要跟着cur进行变化的,所以使用引用
  {
  if(cur==nullptr)
  return ;
  inconvert(cur->left,prev);
  //cur出现的顺序就为中序
  if(prev)
  {
    prev->right=cur;
    cur->left=prev;
  }
  prev=cur;
  inconvert(cur->right,prev);
  }
    TreeNode* Convert(TreeNode* root) {
    TreeNode*prev=nullptr;//记录cur节点的上一个
       inconvert(root,prev);
      TreeNode*head=root;
    //通过遍历左子树的方式找到第一个节点
    while(head&&head->left)
    {
      head=head->left;
    }
    return head;
    }
};

4.从前序与中序遍历序列构造二叉树


从前序与中序遍历序列构造二叉树OJ链接

b4ed6895bd064bfdbce666256df5dd18.png


d598e264d04b49aea1188a3e8b5aafea.png

0bd6362b8ba640ee9e43261c673c0227.png

创建root,并确定值为3

在中序数组中寻找 root值为3的节点 ,并标记其下标为rooti

再通过递归的方式分别创建root的left与root的right

bc115ebef01c43c2becdc9b4f2a16cca.png


同时每次都需要prev++,来确定新的根,

每次rooti都被赋值为inbegin,是为了中序数组的新区间内寻找到根


递归结束的判断条件

8a0ff1378b1644be97647eb2c66eed96.png



若rooti与inbegin都为数组中第一个数的下标时,

[inbegin, rooti-1] 即 [ 0,-1] 为不存在的区间

所以当 inbegin >inright时,就直接返回


class Solution {
public:
//prev为先序数组的下标
//inbeing与inend为 左右子树分割区间
    TreeNode*istree(vector<int>& preorder, vector<int>& inorder,int &prev,
    int inbegin,int inend)
    {
        //若rooti值与inbegin同时为第一个值,
        //则 [inegin,rooti-1]即 [0 ,-1]会报错
        if(inbegin>inend)
        {
            return nullptr;
        }
        //通过先序创建根节点
        TreeNode*root=new TreeNode();
        root->val=preorder[prev];
        //在中序数组中查找root对应的值
        int rooti=inbegin;
        while(rooti<=inend)
        {
            if(preorder[prev]==inorder[rooti])
            {
                break;
            }
            rooti++;
        }
        prev++;//由于是引用,前序的根也要跟着变化
        //分割左右子树区间
      // [inbegin rooti-1] rooti [rooti+1 inend]
      root->left=istree(preorder,inorder,prev,inbegin,rooti-1);
      root->right=istree(preorder,inorder,prev,rooti+1,inend);
      return root;
    }
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        int i=0;
           return  istree(preorder,inorder,i,0,inorder.size()-1);
    }
};
相关文章
|
23天前
|
Java C++
【C++数据结构——树】二叉树的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现二叉树的基本运算。​ 相关知识 创建二叉树 销毁二叉树 查找结点 求二叉树的高度 输出二叉树 //二叉树节点结构体定义 structTreeNode{ intval; TreeNode*left; TreeNode*right; TreeNode(intx):val(x),left(NULL),right(NULL){} }; 创建二叉树 //创建二叉树函数(简单示例,手动构建) TreeNode*create
40 12
|
23天前
|
C++
【C++数据结构——树】二叉树的性质(头歌实践教学平台习题)【合集】
本文档介绍了如何根据二叉树的括号表示串创建二叉树,并计算其结点个数、叶子结点个数、某结点的层次和二叉树的宽度。主要内容包括: 1. **定义二叉树节点结构体**:定义了包含节点值、左子节点指针和右子节点指针的结构体。 2. **实现构建二叉树的函数**:通过解析括号表示串,递归地构建二叉树的各个节点及其子树。 3. **使用示例**:展示了如何调用 `buildTree` 函数构建二叉树并进行简单验证。 4. **计算二叉树属性**: - 计算二叉树节点个数。 - 计算二叉树叶子节点个数。 - 计算某节点的层次。 - 计算二叉树的宽度。 最后,提供了测试说明及通关代
40 10
|
23天前
|
存储 算法 测试技术
【C++数据结构——树】二叉树的遍历算法(头歌教学实验平台习题) 【合集】
本任务旨在实现二叉树的遍历,包括先序、中序、后序和层次遍历。首先介绍了二叉树的基本概念与结构定义,并通过C++代码示例展示了如何定义二叉树节点及构建二叉树。接着详细讲解了四种遍历方法的递归实现逻辑,以及层次遍历中队列的应用。最后提供了测试用例和预期输出,确保代码正确性。通过这些内容,帮助读者理解并掌握二叉树遍历的核心思想与实现技巧。
41 2
|
7月前
|
存储 C++
【C++】二叉树进阶之二叉搜索树(下)
【C++】二叉树进阶之二叉搜索树(下)
41 4
|
7月前
|
Java 编译器 C++
【C++】二叉树进阶之二叉搜索树(上)
【C++】二叉树进阶之二叉搜索树(上)
41 3
|
7月前
|
算法 C++
【C++高阶】高效搜索的秘密:深入解析搜索二叉树
【C++高阶】高效搜索的秘密:深入解析搜索二叉树
54 2
|
9月前
|
算法 C语言 容器
从C语言到C++_25(树的十道OJ题)力扣:606+102+107+236+426+105+106+144+94+145(下)
从C语言到C++_25(树的十道OJ题)力扣:606+102+107+236+426+105+106+144+94+145
73 7
|
9月前
|
C语言
从C语言到C++_25(树的十道OJ题)力扣:606+102+107+236+426+105+106+144+94+145(中)
从C语言到C++_25(树的十道OJ题)力扣:606+102+107+236+426+105+106+144+94+145
68 1
|
9月前
|
算法 C语言 C++
从C语言到C++_25(树的十道OJ题)力扣:606+102+107+236+426+105+106+144+94+145(上)
从C语言到C++_25(树的十道OJ题)力扣:606+102+107+236+426+105+106+144+94+145
50 1
|
9月前
|
算法 C语言 C++
从C语言到C++_14(vector的常用函数+相关选择题和OJ题)(中)
从C语言到C++_14(vector的常用函数+相关选择题和OJ题)
171 1