0

0

通用树中查找节点父节点:基于广度优先遍历的实现指南

花韻仙語

花韻仙語

发布时间:2025-08-11 17:24:20

|

1047人浏览过

|

来源于php中文网

原创

通用树中查找节点父节点:基于广度优先遍历的实现指南

本教程详细介绍了如何在通用树数据结构中查找指定节点的父节点。我们将采用广度优先遍历(BFS)算法,通过系统地逐层探索树的节点,高效地定位目标节点的父级。文章将涵盖节点结构定义、BFS算法原理、Java代码实现、时间与空间复杂度分析,以及相关注意事项,帮助读者掌握这一核心树操作技巧。

1. 通用树节点结构定义

首先,我们定义通用树的节点结构。一个通用树的节点通常包含一个键(key)用于标识,以及一个子节点列表(children),因为通用树的每个节点可以拥有任意数量的子节点。

import java.util.ArrayList;

public class Node {
    int key; // 节点键值
    ArrayList children = new ArrayList<>(); // 存储子节点的列表

    /**
     * 判断当前节点是否有子节点。
     * 虽然在查找父节点的逻辑中不直接使用,但有助于理解节点特性。
     * @return 如果有子节点返回 true,否则返回 false。
     */
    public boolean hasChildren(){
        return !children.isEmpty(); // 更简洁的判断方式
    }
}

2. 查找父节点:广度优先遍历(BFS)原理

要查找一个指定键值(token)的节点的父节点,我们可以利用广度优先遍历(Breadth-First Search, BFS)算法。BFS 是一种逐层探索树或图的算法,非常适合解决需要查找最近关系或最短路径的问题,例如查找父节点。

算法核心思想: BFS 使用队列(Queue)来管理待访问的节点。它从根节点开始,先访问当前节点的所有子节点,然后将这些子节点加入队列,再从队列中取出下一个节点进行同样的操作,直到队列为空或找到目标。

在查找父节点的场景中,当我们从队列中取出一个节点 p(作为潜在的父节点)时,我们会遍历它的所有子节点 c。如果发现某个子节点 c 的键值与我们正在寻找的 token 匹配,那么当前的 p 就是我们目标节点的父节点,我们可以立即返回 p。如果 c 不匹配,我们就将 c 加入队列,以便在后续的迭代中将其作为潜在的父节点进行检查。

Lessie AI
Lessie AI

一款定位为「People Search AI Agent」的AI搜索智能体

下载

3. Java 实现

下面是基于上述原理的 Java 实现代码:

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;

public class TreeOperations {

    /**
     * 在通用树中查找指定键值节点的父节点。
     * 使用广度优先遍历(BFS)实现。
     *
     * @param root 树的根节点。
     * @param token 要查找的子节点的键值。
     * @return 如果找到,返回目标节点的父节点;如果未找到或目标节点是根节点(无父节点),则返回 null。
     */
    public static Node findParent(Node root, int token) {
        // 如果树为空,或者根节点为空,直接返回null
        if (root == null) {
            return null;
        }

        // 使用LinkedList作为Queue的实现
        Queue queue = new LinkedList<>();
        queue.add(root); // 将根节点加入队列,作为遍历的起点

        // 广度优先遍历
        while (!queue.isEmpty()) {
            Node currentNode = queue.poll(); // 从队列中取出当前节点,它将作为潜在的父节点

            // 遍历当前节点的所有子节点
            for (Node child : currentNode.children) {
                // 如果子节点的键值与目标token匹配
                if (child.key == token) {
                    return currentNode; // 找到了,当前节点就是目标节点的父节点
                }
                // 如果子节点不匹配,将其加入队列,以便后续作为潜在的父节点进行检查
                queue.add(child);
            }
        }

        // 遍历完所有节点仍未找到,说明目标节点不存在或其是根节点(无父节点)
        return null;
    }

    public static void main(String[] args) {
        // 构建一个示例通用树
        //       1
        //      /|\
        //     2 3 4
        //    / \   \
        //   5   6   7
        Node root = new Node();
        root.key = 1;

        Node node2 = new Node(); node2.key = 2;
        Node node3 = new Node(); node3.key = 3;
        Node node4 = new Node(); node4.key = 4;
        root.children.add(node2);
        root.children.add(node3);
        root.children.add(node4);

        Node node5 = new Node(); node5.key = 5;
        Node node6 = new Node(); node6.key = 6;
        node2.children.add(node5);
        node2.children.add(node6);

        Node node7 = new Node(); node7.key = 7;
        node4.children.add(node7);

        // 测试查找
        Node parentOf6 = findParent(root, 6);
        if (parentOf6 != null) {
            System.out.println("节点 6 的父节点是: " + parentOf6.key); // 预期输出 2
        } else {
            System.out.println("未找到节点 6 的父节点。");
        }

        Node parentOf7 = findParent(root, 7);
        if (parentOf7 != null) {
            System.out.println("节点 7 的父节点是: " + parentOf7.key); // 预期输出 4
        } else {
            System.out.println("未找到节点 7 的父节点。");
        }

        Node parentOf1 = findParent(root, 1); // 根节点无父节点
        if (parentOf1 != null) {
            System.out.println("节点 1 的父节点是: " + parentOf1.key);
        } else {
            System.out.println("未找到节点 1 的父节点(或其是根节点)。"); // 预期输出 未找到...
        }

        Node parentOf99 = findParent(root, 99); // 不存在的节点
        if (parentOf99 != null) {
            System.out.println("节点 99 的父节点是: " + parentOf99.key);
        } else {
            System.out.println("未找到节点 99 的父节点。"); // 预期输出 未找到...
        }
    }
}

4. 复杂度分析

  • 时间复杂度: O(N),其中 N 是树中节点的总数。在最坏情况下,我们需要访问树中的所有节点才能找到目标节点的父节点(例如,目标节点是最后一个被访问的叶子节点,或者目标节点不存在)。每个节点最多被访问一次(入队一次,出队一次)。
  • 空间复杂度: O(W),其中 W 是树的最大宽度(即在任何一层中节点的最大数量)。在最坏情况下,例如一个完整的二叉树,最后一层的节点数量接近 N/2,此时队列中可能存储接近 N/2 个节点。对于一个高度为 H 的完美平衡树,空间复杂度为 O(N)。在极端情况下(例如,一个只有一层,包含所有子节点的扁平树),空间复杂度也是 O(N)。

5. 注意事项与总结

  • 根节点的父节点: 根节点没有父节点。如果 token 恰好是根节点的键值,findParent 函数将返回 null,这符合逻辑。
  • 目标节点不存在: 如果树中不存在与 token 匹配的节点,函数也将返回 null。
  • BFS的优势: 对于查找父节点这类需要遍历所有可能路径的问题,BFS 能够确保我们按层级顺序发现节点,并且在找到第一个匹配项时立即返回,效率较高。
  • 递归与迭代的选择: 尽管某些树遍历问题常采用递归(如深度优先遍历DFS),但对于查找父节点这类问题,广度优先遍历(BFS)通过迭代配合队列实现,通常更为直观和高效。当 currentNode 作为潜在父节点被处理时,其 child 如果匹配 token,那么 currentNode 立刻就是其父节点,这种层级关系在 BFS 中自然体现。而直接用递归(DFS)来查找父节点会更复杂一些,可能需要额外的参数来传递父节点信息或返回一个包含父子对的结果。

通过本教程,您应该已经掌握了在通用树中利用广度优先遍历查找指定节点父节点的方法。理解

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

832

2023.06.15

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

738

2023.07.05

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

734

2023.07.31

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

397

2023.08.01

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

398

2023.08.02

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

446

2023.08.02

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

430

2023.08.02

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

16926

2023.08.03

Golang gRPC 服务开发与Protobuf实战
Golang gRPC 服务开发与Protobuf实战

本专题系统讲解 Golang 在 gRPC 服务开发中的完整实践,涵盖 Protobuf 定义与代码生成、gRPC 服务端与客户端实现、流式 RPC(Unary/Server/Client/Bidirectional)、错误处理、拦截器、中间件以及与 HTTP/REST 的对接方案。通过实际案例,帮助学习者掌握 使用 Go 构建高性能、强类型、可扩展的 RPC 服务体系,适用于微服务与内部系统通信场景。

8

2026.01.15

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
10分钟--Midjourney创作自己的漫画
10分钟--Midjourney创作自己的漫画

共1课时 | 0.1万人学习

Midjourney 关键词系列整合
Midjourney 关键词系列整合

共13课时 | 0.9万人学习

AI绘画教程
AI绘画教程

共2课时 | 0.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号