力扣105题c++解法

最近在复习数据结构,在力扣上面找了一个题目做。基础不太好,所以给自己记录一下从懵逼到搞懂的整个过程

测试通过如图

贴一下通过代码

TreeNode* BuildTree(vector<int>& preorder, vector<int>& inorder, int& rooti, int left, int right)
{
	if (left > right)
		return NULL;
	int i = 0;
	while (preorder[rooti] != inorder[i])
		i++;
	TreeNode* root = new TreeNode(preorder[rooti++]);
	root->left = BuildTree(preorder, inorder, rooti, left, i - 1);
	root->right = BuildTree(preorder, inorder, rooti, i + 1, right);
	return root;
}
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        int  rooti=0;
        int left=0;
        int right=preorder.size()-1;
        return BuildTree(preorder,inorder,rooti,left,right);
    }

 以下是整个题目的思考过程

我的思路

前序进栈,每次递归出栈且第一个为根节点为上一个节点的子节点

然后在中序中找到出栈的元素,一分为二,左边为该根节点左边的子节点,右边为右边的子节点。

然后递归,前序遍历序列出栈,为根节点,重复直到为空。

伪代码如下:

#include<iostream>
#include<queue>
#include<vector>
using namespace std;

typedef struct tree

{
       int data;
       tree* lchild;
       tree* rchild;
};

tree* buildtree(数组1,数组2)
{
       queue<int> a;
       for (i = 0; i < n; i++)
       {
              //入队列
              a.push(a1[i]);
       }
       //先序出队
       a.出队
              为上一个节点的子节点
              //中序定位
              //分中序组为左右
              //前序遍历序列出来的那个数在中序分好的小组中,若左边无则左指针指空,右边无则右指针指空
              //怎么链接呢???
              return root;
}
int main()
{
       int i, n;
       cin >> n;
       int a[100];
       for (i == 0; i < n; i++)
       {
              cin >> a[i];
       }
}

整个懵逼。

问题汇总如下:

1怎么通过指针去形成链接的关系?

通过TreeNode* root创造一个指针root,然后将其赋值为new TreeNode(preorder[rooti++]),这样这一次递归之中的root指向本次新创立的根节点,然后再将本次创立的根节点结构体中的left与right指向新的递归产生的指针,则根节点与自己的两个子节点能够成功地链接在一起。

2怎么将数组输入到函数中?

通过动态存储vector,需要用到头文件#include<vector>;以及vector<int>& 名称;来实现动态输入。

3函数怎么定义类型,tree*吗?

没错,这样能够返回指向tree型的指针。

4队列的头怎么出,然后怎么选这个元素?

不需要使用队列,数组循环即可。

5中序序列以什么方式进行存储,字符串吗?

动态数组存储即可。

6怎么去把它分为多个方便后续使用,怎么去找这个字符串?

不需要分为多个,记录下前序序列中每次产生的新的根节点的位置,通过循环来在中序序列中找到,并通过记录边界来达到每次都能够分为左右数组的目的。

参考代码

TreeNode* _buildTree(vector<int>& preorder, vector<int>& inorder, int& rooti, int left, int right)
//问,rooti是啥。
//问,为什么代码的结构为TreeNode*。
//问,vector<int>&中的&有什么用。
//答,rooti 是一个整型引用(int&),用于追踪在前序遍历数组中的根节点的索引。
//答,在 C++ 中,函数的返回类型决定了该函数调用后返回的值的类型。具体到你的//问题中,TreeNode* 是一个指针类型,表示该函数返回一个指向 TreeNode 类型的//指针。
//答,vector<int>& preorder
&这个符号表示引用(reference)。
使用引用传递参数时,不会复制对象,而是直接操作原始对象。这样可以提高性能,尤其是对于大型对象(如 vector)时,避免不必要的拷贝开销。
{
       //中序区间不存在
    if (left > right) return nullptr;
//问,left跟right是什么,为什么比大小可以判断
//答,left跟right表示中序数列的边界,例如1,2,3,left为0,right为2
     int i = 0;
     //在中序区间找当前根,划分左右子树
     while (preorder[rooti] != inorder[i]) i++;
     TreeNode* root = new TreeNode(preorder[rooti++]);
//问,new是干什么
//答,new 操作符会创建一个新的指针,用于动态分配内存。这里创建了一
//个 TreeNode 对象,并返回其指针这样就不需要之前就确定节点的个数。
//问,这句话的语法知识点有哪些,以及有哪些含义。
//答,创建一个指向TreeNode型的指针root,动态分配内存创建一个新的、//TreeNode型的对象,为新产生的节点,赋值为前序遍历序列的下一个值。
//然后root指针等于这个新产生的指针。
//问,这个rooti怎么变化。
//答,先访问preorder[rooti],然后rooti自增。
     //递归构建左右子树
     // [left, i - 1] i [i + 1 right]
//通过对root->进行操作来给left与right进行赋值与定义
//产生的新结构体TreeNode中的left指向
//i-1表示上一个选中的根的左边为左子树区域,进入递归
     root->left = _buildTree(preorder, inorder, rooti, left, i - 1);
//i+1表示上一个选中的根的右边为右子树区域,进入递归
     root->right = _buildTree(preorder, inorder, rooti, i + 1, right);
//最终返回根节点的地址
     return root;
}
//问,这个函数的作用,不是已经建好树了吗。
//答,用来调用上面的函数。
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder)
{
       int i = 0;//当前树的根的位置
    return _buildTree(preorder, inorder, i, 0, inorder.size() - 1);
}

最后在参考的基础上稍微改了一下,其余基本一致。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值