携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,点击查看活动详情
久违的更文活动,刷题也死灰复燃了
完全二叉树插入器
该题出自力扣的919题 —— 完全二叉树插入器【中等题】,难度确实有点,但并不会压到我
审题
完全二叉树 是每一层(除最后一层外)都是完全填充(即,节点数达到最大)的,并且所有的节点都尽可能地集中在左侧。
设计一种算法,将一个新节点插入到一个完整的二叉树中,并在插入后保持其完整。
实现 CBTInserter 类:
- CBTInserter(TreeNode root) 使用头节点为 root 的给定树初始化该数据结构;
- CBTInserter.insert(int v) 向树中插入一个值为 Node.val == val的新节点 TreeNode。使树保持完全二叉树的状态,并返回插入节点 TreeNode 的父节点的值;
- CBTInserter.get_root() 将返回树的头节点。
- 依据题意就是需要实现二叉树的三个方法,分别是初始化方法、新增一个节点并自旋、返回头结点的方法
- get_Root的这个方法,只需要返回头结点,那么与初始化方法所结合,初始化方法时,在类里面赋值一个私有的树节点存放,那么get_Root方法就只需要返回私有变量即可
- 相应的,初始化方法也只需要保存传参进入变量即可
- 重点在于insert方法,需要插入一个节点,并且使二叉树始终为完全二叉树
- 首先,完全二叉树,也就是说,节点按层序遍历的形式分布,每个节点与其编号相等;那么该树称为完全二叉树
- 显而易见的,层序遍历可以为这个方法打开思路
- 层序遍历
- 判断子节点左右子树是否为空,为空则插入左子树
- 右子树为空则插入右子树
- 左右子树都不为空,则证明该节点下无法插入新的节点
编码
class CBTInserter {
TreeNode root;
public CBTInserter(TreeNode root) {
this.root = root;
}
/**
* 返回父节点
* @param val
* @return
*/
public int insert(int val) {
int result = -1;
TreeNode index = root;
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(index);
while (!queue.isEmpty()){
int child = queue.size();
for (int i = 0; i < child; i++) {
TreeNode poll = queue.poll();
//判断是否为满二叉树
if (poll.left == null && poll.right == null){
//插入左子树
TreeNode t = new TreeNode(val);
poll.left = t;
result = poll.val;
while (!queue.isEmpty()){
queue.poll();
}
break;
}
//判断右子树为空
if (poll.right == null){
//插入右子树
TreeNode t = new TreeNode(val);
poll.right = t;
result = poll.val;
while (!queue.isEmpty()){
queue.poll();
}
break;
}
if (poll.left != null){
queue.offer(poll.left);
}
if (poll.right != null){
queue.offer(poll.right);
}
}
}
return result;
}
/**
* 返回头结点
* @return
*/
public TreeNode get_root() {
return root;
}
}