Java 根据某棵树树中的一个节点,获取这棵树的所有相关联节点

59 阅读4分钟

有很多棵树 根据某棵树树中的一个节点,获取这棵树的所有相关联节点

package subtree;

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

class Main {
    public static void main(String[] args) {
        // 创建一些节点
        SubTree node1 = new SubTree(1, 0, "A");
        SubTree node2 = new SubTree(2, 1, "B");
        SubTree node3 = new SubTree(3, 1, "C");
        SubTree node4 = new SubTree(4, 2, "D");
        SubTree node5 = new SubTree(5, 2, "E");
        SubTree node8 = new SubTree(8, 5, "H");
        SubTree node9 = new SubTree(9, 8, "I");
        SubTree node6 = new SubTree(6, 3, "F");
        SubTree node7 = new SubTree(7, 3, "G");

        SubTree node11 = new SubTree(10, 0, "A1");
        SubTree node22 = new SubTree(20, 10, "B1");
        SubTree node33 = new SubTree(30, 10, "C1");
        SubTree node44 = new SubTree(40, 20, "D1");
        SubTree node55 = new SubTree(50, 20, "E1");
        SubTree node88 = new SubTree(80, 50, "H1");
        SubTree node99 = new SubTree(90, 80, "I1");
        SubTree node66 = new SubTree(60, 30, "F1");
        SubTree node77 = new SubTree(70, 30, "G1");

        SubTree node111 = new SubTree(101, 0, "A11");
        SubTree node221 = new SubTree(201, 101, "B11");
        SubTree node331 = new SubTree(301, 101, "C11");
        SubTree node441 = new SubTree(401, 201, "D11");
        SubTree node551 = new SubTree(501, 201, "E11");
        SubTree node881 = new SubTree(801, 501, "H11");
        SubTree node991 = new SubTree(901, 801, "I11");
        SubTree node661 = new SubTree(601, 301, "F11");
        SubTree node771 = new SubTree(701, 301, "G11");

        // 将节点放入一个列表中
        List<SubTree> nodes = new ArrayList<>();
        nodes.add(node1);
        nodes.add(node2);
        nodes.add(node3);
        nodes.add(node4);
        nodes.add(node5);
        nodes.add(node6);
        nodes.add(node7);
        nodes.add(node8);
        nodes.add(node9);

        nodes.add(node11);
        nodes.add(node22);
        nodes.add(node33);
        nodes.add(node44);
        nodes.add(node55);
        nodes.add(node66);
        nodes.add(node77);
        nodes.add(node88);
        nodes.add(node99);

        nodes.add(node111);
        nodes.add(node221);
        nodes.add(node331);
        nodes.add(node441);
        nodes.add(node551);
        nodes.add(node661);
        nodes.add(node771);
        nodes.add(node881);
        nodes.add(node991);

        long l = System.currentTimeMillis();
        System.out.println("——————————————开始——————————————————————————");
        // 创建一个树结构
        Tree tree = new Tree(nodes);

        // 根据节点id获取整颗树结构数据和父节点信息
//        SubTree treeById = tree.getTreeById(2);
        List<SubTree> result = tree.getTreeAndParentsById(201);
//        result.addAll(treeById.children);
        List<SubTree> subTrees = tree.traverseTree(result);
        // 打印结果
        for (SubTree node : subTrees) {
            System.out.println(node.data); // B D E A
//            if (!node.children.isEmpty()) {
//                for (SubTree nodeSub : node.children) {
//                    System.out.println(nodeSub.data); // B D E A
//                }
//            }
        }



        System.out.println("结束:" + (System.currentTimeMillis() - l));
    }
}

// 定义树节点类
class SubTree {
    int id; // 节点的唯一标识
    int parentId; // 父节点的标识,如果为0,表示根节点
    String data; // 节点存储的数据
    List<SubTree> children; // 子节点的列表

    // 构造方法
    public SubTree(int id, int parentId, String data) {
        this.id = id;
        this.parentId = parentId;
        this.data = data;
        this.children = new ArrayList<>();
    }
}

// 定义树结构类
class Tree {
    List<SubTree> nodes; // 树中所有的节点

    // 构造方法
    public Tree(List<SubTree> nodes) {
        this.nodes = nodes;
    }

    // 根据节点id获取整颗树结构数据
    public SubTree getTreeById(int id) {
        // 遍历所有的节点,找到目标节点
        for (SubTree node : nodes) {
            if (node.id == id) {
                // 递归构建子树
                buildSubTree(node);
                // 返回目标节点作为根节点的树
                return node;
            }
        }
        // 如果没有找到目标节点,返回null
        return null;
    }

    // 递归构建子树
    public void buildSubTree(SubTree node) {
        // 遍历所有的节点,找到当前节点的子节点
        for (SubTree n : nodes) {
            if (n.parentId == node.id) {
                // 将子节点添加到当前节点的子节点列表中
                node.children.add(n);
                // 递归构建子节点的子树
                buildSubTree(n);
            }
        }
    }

    // 根据节点id获取整颗树结构数据和父节点信息,并按照从父节点到子节点的顺序排序
    public List<SubTree> getTreeAndParentsById(int id) {
        // 创建一个空的列表,用于存储结果
        List<SubTree> result = new ArrayList<>();
        // 遍历所有的节点,找到目标节点
        for (SubTree node : nodes) {
            if (node.id == id) {
                // 递归构建子树
                buildSubTree(node);
                // 将目标节点添加到结果列表中
                result.add(node);
                // 递归查找父节点
                findParents(node, result);
                // 返回结果列表
                return result;
            }
        }
        // 如果没有找到目标节点,返回空列表
        return result;
    }

    // 递归查找父节点
    public void findParents(SubTree node, List<SubTree> result) {
        // 遍历所有的节点,找到当前节点的父节点
        for (SubTree n : nodes) {
            if (n.id == node.parentId) {
                // 将父节点添加到结果列表中
                result.add(n);
                // 递归查找父节点的父节点
                findParents(n, result);
            }
        }
    }

    public List<SubTree> traverseTree(List<SubTree> roots) {
        // 如果根节点列表为空,直接返回
        if (roots == null || roots.isEmpty()) {
            return new ArrayList<>();
        }
        // 创建一个队列,用于存储待遍历的节点
        List<SubTree> objects = new ArrayList<>();
        Queue<SubTree> queue = new LinkedList<>();
        // 将根节点列表加入队列
        queue.addAll(roots);
        // 当队列不为空时,循环遍历
        while (!queue.isEmpty()) {
            // 从队列中弹出一个节点
            SubTree node = queue.poll();
            // 打印节点的 id 和 name
            objects.add(node);
//            System.out.println("id: " + node.getId() + ", name: " + node.getName());
            // 如果节点有子节点,将子节点加入队列
            if (node.children != null && !node.children.isEmpty()) {
                queue.addAll(node.children);
            }
        }
        return objects;
    }

}

// 测试代码