前言
二叉树的题目中输入用例在ACM模式下应该怎么构造呢?
力扣上的题目,输入用例就给了一个数组,怎么就能构造成二叉树呢?
1.知识点
相信大家应该都知道,二叉树可以有两种存储方式,一种是 链式存储,另一种是顺序存储。
链式存储,就是大家熟悉的二叉树,用指针指向左右孩子。(左右指针)
顺序存储,就是用一个数组来存二叉树,其方式如下图所示:(层序遍历)
那么此时大家是不是应该知道了,数组如何转化成 二叉树了。如果父节点的数组下标是i,那么它的左孩子下标就是i * 2 + 1,右孩子下标就是 i * 2 + 2。
2. 定义及构建二叉树
难点在于如何定义以及构建生成二叉树,之后调用核心代码输出结果
定义二叉树:
public class TreeNode{
int val;
TreeNode left;
TreeNode right;
public TreeNode(int val){
this.val = val;
}
public TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
构建二叉树:
public static TreeNode construct(int[] arr){
List<TreeNode> list = new ArrayList<>();
TreeNode root = null;
int n = arr.length;
for(int i = 0;i < n;i++){
TreeNode node = null;
// 对应数组的-1节点为null,如果不定义int类型数组,则可使用Object类型来判定null类型
if(arr[i] != -1){
node = new TreeNode(arr[i]);
}
list.add(node);
// 区分根节点,将其定义为root
if(i == 0)root = node;
}
// 通过二叉树的性质来生成,结尾节点是 i*2 + 1
for(int i = 0;i * 2 + 1 < n;i++){
TreeNode node = list.get(i);
if(node != null){
// 左节点指向
node.left = list.get(i * 2 + 1);
// 再次判断下
if(i * 2 + 2 < n){
// 右节点指向
node.right = list.get(i * 2 + 2);
}
}
}
return root;
}
3. 完整代码
假设求二叉树的右视图,也就是求树的所有右节点
具体核心代码如下:(通过层次遍历的结构)
public List<Integer> rightSideView(TreeNode root) {
List<Integer> list = new ArrayList<>();
if(root == null)return list;
LinkedList<TreeNode> que = new LinkedList<>();
que.offer(root);
while(!que.isEmpty()){
int n = que.size();
for(int i = 0;i < n;i++){
TreeNode node = que.poll();
if(i == n - 1)list.add(node.val);
if(node.left != null) que.offer(node.left);
if(node.right != null) que.offer(node.right);
}
}
return list;
}
完整代码如下:
import java.util.*;
class test3 {
// acm的测试代码
public static void main(String[] args) {
// 此处如果是Scanner的获取,可通过Scanner进行输入对应数组
int[] arrs = {1,2,3,-1,5,-1,4};
TreeNode root = construct(arrs);
List<Integer> objects = rightSideView(root);
for(int i = 0 ;i < objects.size();i++){
System.out.println(objects.get(i));
}
}
//定义二叉树性质
public static class TreeNode{
int val;
TreeNode left;
TreeNode right;
public TreeNode(int val){
this.val = val;
}
public TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
/**
* 根据数组构建二叉树
* @param arr 树的数组表示
* @return 构建成功后树的根节点
*/
public static TreeNode construct(int[] arr){
List<TreeNode> list = new ArrayList<>();
TreeNode root = null;
int n = arr.length;
for(int i = 0;i < n;i++){
TreeNode node = null;
if(arr[i] != -1){
node = new TreeNode(arr[i]);
}
list.add(node);
if(i == 0)root = node;
}
// 遍历一遍,根据规则左右孩子赋值就可以了
// 注意这里 结束规则是 i * 2 + 1 < arr.length,避免空指针
// 为什么结束规则不能是i * 2 + 2 < arr.length呢?
// 如果i * 2 + 2 < arr.length 是结束条件
// 那么i * 2 + 1这个符合条件的节点就被忽略掉了
for(int i = 0;i * 2 + 1 < n;i++){
TreeNode node = list.get(i);
if(node != null){
node.left = list.get(i * 2 + 1);
if(i * 2 + 2 < n){
node.right = list.get(i * 2 + 2);
}
}
}
return root;
}
// 核心代码
public static List<Integer> rightSideView(TreeNode root) {
List<Integer> list = new ArrayList<>();
if(root == null)return list;
LinkedList<TreeNode> que = new LinkedList<>();
que.offer(root);
while(!que.isEmpty()){
int n = que.size();
for(int i = 0;i < n;i++){
TreeNode node = que.poll();
if(i == n - 1)list.add(node.val);
if(node.left != null) que.offer(node.left);
if(node.right != null) que.offer(node.right);
}
}
return list;
}
}
PS:整理不容易,文章但凡对你有点儿帮助或者启发,希望可以帮我一键三连!