首先简单介绍下什么是满二叉树,满二叉树是一种特殊的二叉树,其中每个非叶子节点都有两个子节点,且所有叶子节点都在相同的深度上。
下面我们使用java语言,采用两种方法来生成n层的满二叉树。
第一种:循环遍历法
首先就是定义树的节点,我们就叫TreeNode吧,定义如下,我们这里引入了泛型,这样我们的二叉树就可以存储各种类型value值了。parent节点用来记录当前节点的父节点。left和right分别代表左孩子和右孩子。
class TreeNode<T> {
T val;
TreeNode<T> parent;
TreeNode<T> left;
TreeNode<T> right;
TreeNode(T data) {
this.val = data;
}
}
有了节点定义之后,我们就可以开始写生成满二叉树的逻辑了,当然了,我这里没有给节点的val赋值。下面这段代码很巧妙的利用了队列的特性,先进先出,刚开始就把根节点保存到了队列,然后从第一层开始创建,之所以让level<n,是因为第n层都是叶子节点,不需要再处理左右节点了,for循环之前先获取队列中元素的个数,这样就知道当前这一层要处理几个节点了,我们二叉树第一层只有1个节点,第二层有2个节点,依次类推。for循环中第一行便是从队列的头部取出一个元素,然后就是给这个节点绑定左右孩子节点并且让左右孩子节点的父节点指向这个节点。创建的左右孩子节点要添加到队列中,用于下一层的遍历。
public static TreeNode createTree(int n) {
TreeNode<Integer> root = new TreeNode<Integer>();
int level = 1;
Queue<TreeNode<Integer>> queue = new LinkedList<>();
queue.add(root);
while (level < n) {
int levelSize = queue.size();
for (int i = 0; i < levelSize; i++) {
TreeNode node = queue.remove();
TreeNode left = new TreeNode<Integer>();
left.parent = node;
node.left = left;
queue.add(left);
TreeNode right = new TreeNode<Integer>();
right.parent = node;
node.right = right;
queue.add(right);
}
level++;
}
return root;
}
第二种:递归
递归方法,相对来说不像循环遍历那样容易理解,所需要的参数也由原来的一个n变成3个参数。如下所示,第一个参数root需要由调用方先创建好,这个也是二叉树的根节点,第二个参数level是当前正在生成的层数,n则代表我们总共要生成n层的满二叉树。
相信眼尖的同学已经看出来了,递归这个方法我给节点的val赋值了,上面循环遍历的方法我没有赋值,这个要看你实际的场景了,需要给val赋值就赋值,不需要的就不用赋值就行了。下面我说下代码的意思。
if判断中level >= n || root == null直接什么也不处理,直接return,因为第n层是不需要我们处理左右孩子节点的,因此我们递归,只需要重点关注level < n就行了。然后就是创建左节点,让第一个参数root节点的左节点指向新创建的left节点,同时让left节点的父节点指向root节点。右节点跟左节点的逻辑一样(只是val值比左节点的val大1而已),不多言。再往下就是递归了,先处理root左半部分的递归,同时让level+1,表示要生成下一层的节点了,n这个参数不用变。处理完root左半部分的递归后,就是处理root右半部分的递归了。最终我们得到的就是一颗n层的满二叉树。
public static void createTree(TreeNode<Integer> root, int level, int n) {
if (level >= n || root == null) {
return;
}
TreeNode<Integer> left = new TreeNode<Integer>(2*root.val);
root.left = left;
left.parent = root;
TreeNode<Integer> right = new TreeNode<Integer>(2*root.val + 1);
root.right = right;
right.parent = root;
createTree(root.left, level+1, n);
createTree(root.right, level+1, n);
}