不知道有没有跟我一样,最近再刷leecode的时候老是遇到输入一个数组然后形成二叉树再进行做题的题目。如果是直接在leecode进行做题那还好说,不需要自己构建二叉树就可以进行做题,但是如果是自己使用vs编译器来写题,就要自己一个个把左树和右树对应上,非常的麻烦,这里我就想自己手写一个数组创建二叉树的代码来方便进行做题。其中有几个点我是觉得有所收获的点
1、在构建二叉树的时候,数组往往会以NULL来代替没有数值的节点,但是在C++中NULL通常代表了0,也就是
#define NULL 0
这样我们会有一个比较困扰人的地方,比如当遇到数组中本身就是0的节点的时候,我们应该怎么导入数据,为了将其进行区分,我选择在这里定义了一个全局常量NULLvalue 来代替NULL以便跟0来进行区分
const int NULLvalue = INT_MIN;
其中INT_MIN这个需要包含头文件<climits>
2、我们知道二叉树的子节点和父节点之间的关系为2*n(节点数)+1 或者2*n+2,我们可以看到一个父亲节点是对应两个子节点的,如果我们写一个循环,我们子节点走两次,父亲节点才走一次,但是父亲节点如果找到下一个需要成为父亲节点的子节点呢?这里我想的是使用队列来解决这个问题,即每走一个子节点,我们都将其当作备用的父亲节点存入队列中。然后父亲节点链接子节点后我们将其删除再取队列前端充当父亲节点。
3、还有一种极端情况如果输入的是如下队列[1,2,3,4,5,NULLvalue,NULLvalue,NULLvalue,NULLvalue,6,7,NULLvalue,NULLvalue,NULLvalue,NULLvalue,,NULLvalue,NULLvalue,NULLvalue,NULLvalue,8,9];
我们会产生如下二叉树
我们队列在前五个节点删除都是没问题的,但是当子节点走到数据8存放的节点的时候,我们会发现queue队列里面父亲节点都删除完了,以至于我们没有数据来链接这个节点了,这是应为由于有父亲节点走到NULLvalue的时候,没能存放数据,导致删除queue数据的时候,误把后面的父亲节点给删除了,所以我们在删除父亲节点的时候,需要加一个判断条件:
if(x[parent_idx]!=NULLvalue)
{
parent_node.pop();
parent = parent_node.front();
}
其中x为题目所给的队列,parent_node 为父亲节点队列,parent为父亲节点
完整代码如下:
TreeNode* TreeNode_struct_by_vector(vector<int>x)
{
if(x.size()>0)
{
TreeNode* root = new TreeNode(x[0]);
TreeNode* parent = root;
queue<TreeNode*> parent_node;
parent_node.push(parent);
int child_idx = 1;
int parent_idx = 0;
while (child_idx < x.size())
{
if(x[child_idx]!= NULLvalue)
{
TreeNode* child = new TreeNode(x[child_idx]);
parent_node.push(child);
if (child_idx == 2 * parent_idx + 1)
{
parent->left = child;
child_idx++;
}
else if (child_idx == 2 * parent_idx + 2)
{
parent->right = child;
parent_idx++;
child_idx++;
parent_node.pop();
parent = parent_node.front();
}
}
else
{
if (child_idx == 2 * parent_idx + 1)
{
child_idx++;
}
else if (child_idx == 2 * parent_idx + 2)
{
parent_idx++;
child_idx++;
if(x[parent_idx]!=NULLvalue)
{
parent_node.pop();
parent = parent_node.front();
}
}
}
}
return root;
}
else
{
return nullptr;
}
}