实现一个AI大模型当前都无法正确实现的基础二叉树读取算法

概述

图1: 

图2:

上图帮大家温习完全二叉树的概念,本文讲的是完全顺序二叉树的初始化

华为的员工、考过华为OD的员工、参加过其他类似大厂的考试的员工一般做过二叉树的初始化,甚至有些还碰到过手撕代码时面试官要求做二叉树遍历,看完本文的读者,我相信一定能拿到比较高的评分(尽管手撕的时候面试官一般不会要你关心二叉树的动态构造,只要写初始化一个固定的树跑过测试就行)。

对华为或华为OD感兴趣的同学可以参看文章:

华为OD入门级、工作级、专业级技术技能知识点要求及职级薪资表

Java初始化顺序二叉树 

百度AI初始化顺序二叉树

 百度AI生成的代码分析:

1、buildTree方法明显逻辑错误

理由:左节点如果是index*2+1,那么根节点就应该是0,而实际root又是用1初始化的。

其他的我就不详细分析了,核心逻辑都错了结果一定也是错的

读者可以亲自在百度上试验。并在本地用其代码验证。

作者初始化顺序二叉树

在这之前先给大家看一下我们传奇人物塔子哥的题库中的这一道题:

完全二叉树非叶子部分后序遍历(100分) - Problem Detail - CodeFun2000

可能需要付费,不过没关系作者截图出来:

 额,作者代码注释中也有原题,下面看作者代码实现:

import java.util.Arrays;
import java.util.Scanner;
import java.util.Stack;/*** @Description: #P2988. 完全二叉树非叶子部分后序遍历(100分*
给定一个以顺序储存结构存储整数值的完全二叉树序列(最多1000个整数),请找出此完全二叉树的所有非叶子节点部分,然后采用后序遍历方式将此部分树(不包含叶子)输出。
只有一个节点的树,此节点认定为根节点(非叶子)。
此完全二叉树并非满二叉树,可能存在倒数第二层出现叶子或者无右叶子的情况
其他说明:二叉树的后序遍历是基于根来说的,遍历顺序为:左-右-根输入描述
一个通过空格分割的整数序列字符串
输出描述
非叶子部分树结构。备注:输出数字以空格分隔样例1
输入
1 2 3 4 5 6 7
输出
2 3 1
说明
找到非叶子部分树结构,然后采用后序遍历输出。1/    \2       3/  \      /  \4     5     6     7/  \   /  \  /  \    /  \8   9  10 11 12  13  14  15* @Author: Dand* @CreateDate: 2025/6/22 22:06* @Version: 1.0*/
public class Main {public static void main(String args[]){Scanner sc = new Scanner(System.in);int[] arr= Arrays.stream(sc.nextLine().split("\\ ")).mapToInt(Integer::parseInt).toArray();Node root = new Root(arr);// 后序遍历Stack<Node> stack = new Stack<Node>();while (true){if (root != null){stack.push(root);root = root.getLeft();} else {if (stack.isEmpty())return;if (null == stack.peek().getRight()) {// 叶子root = stack.pop();
//                    System.out.print(root.getData() + " ");  // 不打叶子while (root == stack.peek().getRight()) {root = stack.pop();System.out.print(root.getData() + " ");  // 只打非叶子if (stack.isEmpty()) {break;}}}if (!stack.isEmpty())root = stack.peek().getRight();elseroot = null;}}}
}class Node<T> {public T data;public Node<T> left;public Node<T> right;Node(T e){data = e;}public T getData() {return data;}public void setData(T data) {this.data = data;}public Node<T> getLeft() {return left;}public Node<T> getRight() {return right;}public void setLeft(Node<T> node){this.left = node;}public void setRight(Node<T> node){this.right = node;}
}class Root extends Node {public Integer data;public Node<Integer> left;public Node<Integer> right;Root(int[] arr){// size 一定要大于0super(arr[0]);int size = arr.length;if (size > 0) {data = arr[0]; // 根节点是数组第一个值buildTree( this, 1, size , arr);}}/**** @param node* @param index 从1开始* @param size* @param arr*/private void buildTree(Node node, int index, int size, int[] arr) {if ( index * 2 <= size ) {node.left = new Node(arr[index * 2-1] ); // 左子节点值是 2*index + 1buildTree( node.left, index * 2, size, arr ); // 递归构建左子树if (index * 2 + 1 <= size) { // 如果有右子节点node.right = new Node(arr[index * 2] ); // 右子节点值是2*index + 2buildTree( node.right, index * 2 + 1, size, arr ); // 递归构建右子树}}}
}

代码走读:

1、作者将用户输入读入int[]中

2、实际输入不一定是连续的数字

3、如果是连续数字这行用值 index*2初始化即可

node.left = new Node(arr[index * 2-1] ); 

因数组索引是0开始,所以以第1个左子节点为例:第2个节点值在整型数组中的索引就是1,遵循AI开始的逻辑,构建ROOT的子树时传的index为1,所以上面 index * 2-1刚好是1(输入的数组中第二个数:arr[index * 2-1])

4、作者树采用先创建了一个能用的父类,不用场景可实现不同的子类

5、本题中data只是个简单的整型值,解决实际问题(如saas平台健康度的决策树,因然健康度一般为多叉树,逻辑有些不一样,也差不了多少)时读者可以把子类中的data换成数据对象

6、本题要求后序遍历,所以作者使用栈实现了后序遍历

7、相比递归,栈占用更少的cpu和内存。

8、本题要求不打印叶子,所以只要注释掉内部while循环前的那边打印语句

               if (null == stack.peek().getRight()) {// 叶子root = stack.pop();
//                    System.out.print(root.getData() + " ");  // 不打叶子while (root == stack.peek().getRight()) {root = stack.pop();System.out.print(root.getData() + " ");  // 只打非叶子if (stack.isEmpty()) {break;}}}

递归

简单

先序

    /*** 递归先序遍历* @param root*/private void priOrderWithRecursion(BinaryTreeNode root) {if (null != root) {System.out.print(root.getValue() + "\t");priOrderWithRecursion(root.getLeftChild());priOrderWithRecursion(root.getRightChild());}}

后序

    /*** 递归后序遍历* @param root*/private void postOrderWithRecursion(BinaryTreeNode root) {if (null != root) {postOrderWithRecursion(root.getLeftChild());postOrderWithRecursion(root.getRightChild());System.out.print(root.getValue()+ "\t");}}

中序

    /*** 递归中序遍历* @param root*/private void inOrderWithRecursion(BinaryTreeNode root) {if (null != root) {inOrderWithRecursion(root.getLeftChild());System.out.print(root.getValue() + "\t");inOrderWithRecursion(root.getRightChild());}}

栈(非递归)

占更少的计算资源,更好的性能 

先序

    /*** 非递归先序遍历,虽然是采用栈的方式,但是并未完全应用栈的思想,采取循环过程中输出的方式来遍历* @param root*/private void preOrder(BinaryTreeNode root) {Stack<BinaryTreeNode> stack = new Stack<>();while (null != root || !stack.isEmpty()) {while (null != root) {System.out.print(root.getValue() + "\t");stack.push(root);root = root.getLeftChild();}if (!stack.isEmpty()) {root = stack.pop();root = root.getRightChild();}}}

后序

见上面 作者初始化顺序二叉树  章节的代码(包含了后序遍历)。

中序

    /*** 非递归中序遍历* @param root*/private void inOrder(BinaryTreeNode root) {Stack<BinaryTreeNode> stack = new Stack<>();while (null != root || !stack.isEmpty()) {while (null != root) {stack.push(root);root = root.getLeftChild();}if (!stack.isEmpty()) {root = stack.pop();System.out.print(root.getValue() + "\t");root = root.getRightChild();}}}

二叉树的概念

二叉树是一种每个节点最多有两个子树的树结构‌,广泛应用于计算机科学领域,是数据结构中最基本且重要的非线性存储形式之一。其核心特征包括递归定义、有序性和节点度限制(不超过2)。

基本定义

二叉树(Binary Tree)是由节点构成的有限集合,该集合要么为空,要么由一个根节点及其两棵互不相交的子树组成,分别称为左子树和右子树。这两棵子树同样遵循二叉树的定义,形成递归结构。‌‌

关键特性

  1. 节点度限制‌:每个节点的子节点数不超过2,区别于普通树结构。‌‌
  2. 有序性‌:即使节点数量相同,左右子树的顺序不同也会被视为不同的二叉树。‌‌
  3. 递归定义‌:子树本身也是二叉树,允许通过递归算法高效处理。‌‌‌‌

常见类型

  • 满二叉树‌:所有非叶子节点均有左右子树,且所有叶子节点在同一层。
  • 完全二叉树‌:除最后一层外,其他层节点数达到最大值,且最后一层节点从左向右连续排列。‌‌

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/912243.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/912243.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【攻防篇】阿里云服务器中 如何关闭docker api端口

在阿里云服务器&#xff08;ECS&#xff09;上&#xff0c;Docker API 默认监听 2375&#xff08;非加密&#xff09;和 2376&#xff08;TLS加密&#xff09;端口。如果未正确配置&#xff0c;可能被恶意利用&#xff08;如挖矿攻击&#xff09;。以下是关闭和加固 Docker API…

暑假复习篇之类与对象

面向对象&#xff1a;①类与对象②封装③继承④接口 类与对象&#xff1a; 概念&#xff1a;类就是类别的意思 用class表示 / 面向对象编程&#xff0c;万物皆可编程&#xff0c;在程序中表示一个事物时&#xff0c;往往因为事物的复杂程度导致编程的代码非常复杂 【基本数…

RabbitMQ RPC模式Python示例

文章目录 1.服务端2.客户端3.调用结果 1.服务端 #!/usr/bin/env python3 # -*- coding: UTF-8 -*- """ File: rabbitmq_server.py Date: 2025/6/26 10:42 Author: xxx Description: 1. RabbitMQ服务端&#xff0c;支持多节点命令执行 2. 作为被控…

Rust代码规范之蛇形命名法和驼峰命名法

Rust 使用两种主要的命名风格&#xff1a;驼峰命名法&#xff08;UpperCamelCase&#xff09;和蛇形命名法&#xff08;snake_case&#xff09;。通常&#xff0c;类型&#xff08;如结构体、枚举、特征&#xff09;使用驼峰命名法&#xff0c;而变量、函数、方法等使用蛇形命名…

编写CSS的格式

1、内联样式的css import React, { PureComponent } from reactexport class App extends PureComponent {constructor() {super()this.state {fs: 20}}render() {const { fs } this.statereturn (<div><p style{{ color: red, fontSize: ${fs}px }}>哈哈哈哈哈…

Redis—主从复制

引言 Redis的应用还得是在分布式系统当中。在分布式系统中&#xff0c;涉及到一个非常关键的问题&#xff0c;就是单点问题。例如&#xff0c;如果某个服务器程序&#xff0c;只有一个节点&#xff08;只搞了一个物理服务器&#xff0c;来部署这个服务器程序&#xff09;&…

【网络安全】从IP头部看网络通信:IPv4、IPv6与抓包工具 Wireshark 实战

从IP头部看网络通信&#xff1a;IPv4、IPv6与抓包工具 Wireshark实战 在网络安全分析和数据通信的世界中&#xff0c;一切都始于“数据包”。数据包是网络上传输的基本单位&#xff0c;而数据包的结构与内容&#xff0c;正是我们理解网络行为的核心。本文将带你深入了解 IP 协…

IPv4网络地址分类

目录 一、核心分类标准 二、详细范围与主机数量 1. A类网络&#xff08;超大规模网络&#xff09; 2. B类网络&#xff08;中大型网络&#xff09; 3. C类网络&#xff08;小型网络&#xff09; 三、三类网络对比表 四、保留地址说明 五、现代网络中的变化 六、主机数…

Qt:QCustomPlot库简介

QCustomPlot 是一个基于 Qt 框架的轻量级 C 绘图库&#xff0c;专为高效绘制二维图表&#xff08;如曲线图、柱状图、金融图表等&#xff09;而设计。相比 Qt Charts 模块&#xff0c;它以 高性能 和 高度可定制性 著称&#xff0c;尤其适合需要实时数据可视化的科学计算、工业…

【云桌面容器KasmVNC】如何关闭SSL使用HTTP

1 缘起 根据实际的诉求,调整实现方式。 为用户提供云浏览器(通过浏览器访问远程浏览器),多用户的每个任务提供资源隔离的云浏览器。 该功能,由同事祥嵩曾调研与开发,使用KasmVNC实现功能,非常佩服祥嵩,无论是技术广度还是技术深度都是杠杠滴,无可挑剔。 实际的诉求是…

跟着AI学习C#之项目实战-电商平台 Day5

&#x1f4c5; Day 5&#xff1a;订单提交与支付模拟 ✅ 今日目标&#xff1a; 创建 Order 和 OrderItem 模型实现从购物车生成订单的功能模拟支付流程&#xff08;成功/失败页面&#xff09;添加订单状态跟踪&#xff08;如“待付款”、“已发货”等&#xff09;提交 Git 版…

复杂驱动开发-TLE9471的休眠流程与定时唤醒

文章目录 前言休眠流程定时唤醒功能总结 前言 开发SBC时非常重要的一环就是开发休眠流程&#xff0c;其目的是为了保证接KL30的ECU在休眠模式下尽可能小的消耗低压蓄电池的电量&#xff0c;防止车辆放置长时间后出现亏电。而定时唤醒功能在部分ECU中会有需求休眠后定期对车辆状…

Spark 之 Reuse

src/main/scala/org/apache/spark/sql/execution/reuse/ReuseExchangeAndSubquery.scala case object ReuseExchangeAndSubquery extends Rule[SparkPlan] {def apply(plan: SparkPlan): SparkPlan = {if (conf.exchan

Solidity学习 - 错误处理

文章目录 前言EVM错误处理机制EVM错误处理的核心特性程序中的错误处理 错误抛出方法require()函数require()触发异常的场景关键特性 assert()函数assert()触发异常的场景关键特性 require() vs assert()&#xff1a;选择指南revert()函数关键特性 异常捕获&#xff1a;try/catc…

如何永久删除Android上的短信[无法恢复]

当您不再保留 Android 设备时&#xff0c;您将需要彻底删除所有私人数据&#xff0c;包括短信。因此&#xff0c;有必要了解如何永久删除Android上的短信。现在&#xff0c;阅读本指南&#xff0c;掌握消除信息的实用方法。 第 1 部分&#xff1a;如何一键永久删除 Android 上的…

P12894 [蓝桥杯 2025 国 Java B] 智能交通信号灯

[Problem] \color{blue}{\texttt{[Problem]}} [Problem] 给定一个长度为 n n n 的数组 a 1 … n a_{1\dots n} a1…n​&#xff0c;进行 m m m 次一下操作&#xff1a; 给定 l , r l,r l,r&#xff0c;求出 ∑ l ≤ i < j ≤ r mex { a i , a j } \sum\limits_{l \le…

华为云Flexus+DeepSeek征文|基于华为云一键部署的 Dify-LLM 平台构建智能试卷生成助手

目录 前言 1 华为云Dify-LLM应用平台部署 1.1 一键部署平台简介 1.2 四步完成部署流程 2 接入华为云 DeepSeek 自定义大模型 2.1 ModelArts Studio 模型服务介绍 2.2 配置自定义大模型 3 创建试卷生成工具&#xff08;工作流&#xff09; 3.1 设计 DSL 工作流 3.2 工…

嵌入式硬件与应用篇---寄存器GPIO控制

在 ARM 架构中&#xff0c;通过 32 位寄存器控制 GPIO&#xff08;通用输入输出&#xff09;的核心步骤和方法可分为以下几个关键环节&#xff0c;结合不同芯片的实现差异&#xff0c;具体操作需参考对应的数据手册&#xff1a; 一、GPIO 控制的核心步骤 1. 使能 GPIO 时钟 …

Fiddler中文版抓包工具在跨域与OAuth调试中的深度应用

跨域和OAuth授权流程一直是Web和移动开发中最容易踩坑的领域。复杂的CORS配置、重定向中的Token传递、授权码流程的跳转&#xff0c;以及多域名环境下的Cookie共享&#xff0c;常常让开发者陷入调试困境。此时&#xff0c;一款能够精准捕获、修改、重放请求的抓包工具显得至关重…

React用户交互事件

在React中处理用户交互事件&#xff08;如点击、输入、提交等&#xff09;的方式与原生JavaScript类似&#xff0c;但有一些语法差异和最佳实践。以下是常见交互事件的处理方法及代码示例&#xff1a; 一、基本事件处理&#xff08;点击、输入等&#xff09; 1. 点击事件&…