ACM模式如何构建二叉树

前言

二叉树的题目中输入用例在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:整理不容易,文章但凡对你有点儿帮助或者启发,希望可以帮我一键三连!

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝色乌云

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值