这是LeetCode上的一道题目
![]()
我的解法:
定义完全二叉树数据类型,定义一个二叉树指针类型的数组用来模拟队列,再定义一个top指向队首,在初始化完全二叉树时找到第一个没有左子树或者右子树的节点,用top记录下他的位置,此后每次插入,插入top指向的节点缺少的部分,再判断节点是否完整了,若完整则将top+1,rear指向队列中最后一个节点,每次新插入的节点入队至rear后面的位置。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
#define Max_SIZE 11000 //最多有这么多节点
typedef struct {
struct TreeNode ** levelTree;
int top;
int rear;
} CBTInserter;
CBTInserter* cBTInserterCreate(struct TreeNode* root) {
CBTInserter *obj=(CBTInserter*)malloc(sizeof(CBTInserter));
obj->levelTree=(struct TreeNode**)malloc(sizeof(struct TreeNode*)*Max_SIZE); //开辟对列空间
int front=-1,rear=-1;
obj->levelTree[++rear]=root;
struct TreeNode *p;
bool flag=true;
while(front<rear){ //层序遍历根节点
p=obj->levelTree[++front];
if(p->left){
obj->levelTree[++rear]=p->left;
}
if(p->right){
obj->levelTree[++rear]=p->right;
}
if((!p->left||!p->right)&&flag){
obj->top=front; //找到第一个不完整的节点并停止寻找
flag=false;
}
}
obj->rear=rear; //找到队尾指针
return obj;
}
int cBTInserterInsert(CBTInserter* obj, int val) {
struct TreeNode *p=(struct TreeNode*)malloc(sizeof(struct TreeNode));
p->val=val;
p->left=NULL;
p->right=NULL;
obj->levelTree[++obj->rear]=p; //将新节点入队
if(obj->levelTree[obj->top]->left==NULL){ //将新节点插入到树中 并返回父节点的值
obj->levelTree[obj->top]->left=p;
return obj->levelTree[obj->top]->val;
}
else{
obj->levelTree[obj->top]->right=p;
obj->top++;
return obj->levelTree[obj->top-1]->val;
}
}
struct TreeNode* cBTInserterGet_root(CBTInserter* obj) {
return obj->levelTree[0];
}
void cBTInserterFree(CBTInserter* obj) {
free(obj->levelTree);
free(obj);
}
改进的解法:
对于一棵完全二叉树而言,其除了最后一层之外都是完全填充的,并且最后一层的节点全部在最左侧。那么,只有倒数第二层(如果存在)最右侧的若干个节点,以及最后一层的全部节点可以再添加子节点,其余的节点都已经拥有两个子节点。
因此,我们可以使用一个队列存储上述提到的这些可以添加子节点的节点。队列中的存储顺序为:首先「从左往右」存储倒数第二层最右侧的节点,再「从左往右」存储最后一层的全部节点。这一步可以使用广度优先搜索来完成,因为广度优先搜索就是按照层优先进行遍历的。
随后,当我们每次调用 insert(val) 时,我们就创建出一个节点 child,并将它最为队列的队首节点的子节点。在这之后,我们需要把 child 加入队尾,并且如果对队首节点已经有两个子节点,我们需要将其从队列中移除。
class CBTInserter:
def __init__(self, root: TreeNode):
self.root = root
self.candidate = deque()
q = deque([root])
while q:
node = q.popleft()
if node.left:
q.append(node.left)
if node.right:
q.append(node.right)
if not (node.left and node.right):
self.candidate.append(node)
def insert(self, val: int) -> int:
candidate_ = self.candidate
child = TreeNode(val)
node = candidate_[0]
ret = node.val
if not node.left:
node.left = child
else:
node.right = child
candidate_.popleft()
candidate_.append(child)
return ret
def get_root(self) -> TreeNode:
return self.root