實現一個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
英文地址,請注明出處:http://en.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. 點擊事件&…