数据结构-树java实现

数据结构-树

定义

树是由节点和边组成的一种非线性数据结构。树中的每个节点都可以有零个或多个子节点,并且一个节点只有一个父节点(除了根节点)

特性

树(Tree)作为一种非线性数据结构,具有以下一般特性:

  1. 树由节点(Node)和边(Edge)组成:每个节点表示一个实体,边表示节点之间的关系。
  2. 树有一个根节点(Root):根节点是树的顶部节点,是树中所有节点的起点。
  3. 节点之间存在父子关系:除了根节点外,每个节点都有一个父节点和零个或多个子节点。父节点是子节点的直接上级,而子节点是父节点的直接下级。
  4. 节点的度(Degree):节点的度表示节点拥有的子节点数量。
  5. 节点的层级(Level):根节点的层级为1,其子节点的层级为2,以此类推。
  6. 节点的深度(Depth):节点的深度表示从根节点到该节点的路径长度,根节点的深度为0。
  7. 节点的高度(Height):节点的高度表示从该节点到其最远叶子节点的路径长度,叶子节点的高度为0。
  8. 子树(Subtree):树中的任意节点和其所有子孙节点组成的子树。
  9. 叶子节点(Leaf Node):没有子节点的节点称为叶子节点,也称为终端节点。
  10. 祖先节点和后代节点:节点的祖先节点是其到根节点的路径上的所有节点,节点的后代节点是其子节点和子节点的子节点。
  11. 路径(Path):从一个节点到另一个节点经过的边的序列。
  12. 森林(Forest):由多个互不相交的树组成的集合。

树的分类

  1. 二叉树(Binary Tree):每个节点最多有两个子节点,分别称为左子节点和右子节点。
  2. 二叉搜索树(Binary Search Tree):左子节点的值小于等于父节点的值,右子节点的值大于等于父节点的值。
  3. 完全二叉树(Complete Binary Tree):除了最后一层,其他层的节点都是满的,且最后一层的节点依次从左到右排列。
  4. 满二叉树(Full Binary Tree):每个节点都有零个或两个子节点,且所有的叶子节点都在同一层上。
  5. 平衡二叉树(Balanced Binary Tree):左子树和右子树的高度差不超过1的二叉树,常见的平衡二叉树有AVL树和红黑树。
  6. B树(B-Tree):一种多路搜索树,用于大规模数据存储和快速访问,常用于数据库和文件系统。
  7. 二叉堆(Binary Heap):一种特殊的完全二叉树,满足堆的性质,常用于实现优先队列。
  8. 树堆(Treap):一种随机化平衡二叉搜索树,结合了二叉搜索树和堆的性质。
  9. 字典树(Trie):一种用于高效存储和搜索字符串的树形数据结构。
  10. 赫夫曼树(Huffman Tree):用于实现赫夫曼编码的特殊二叉树,常用于数据压缩。

代码实现

1 树的节点,TreeNode类表示树中的一个节点,它具有一个整(val)和一个子节点列表(children);每个TreeNode对象都可以有零个或多个子节点,通过列表(List)来存储子节点

public class TreeNode<T> {


    /**
     * 用来存储节点的数值或数据,它为树的节点提供了附加的信息,
     * 帮助对树进行操作和处理
     */
    public T val;

    /**
     * 个子节点列表(children)。
     * 每个TreeNode对象都可以有零个或多个子节点,通过列表(List<TreeNode>)来存储子节点
     */
    List<TreeNode<T>> children;


    public TreeNode(T val) {
        this.val = val;
        this.children = new ArrayList<>();
    }
}

2 Tree类表示整棵树,它具有一个根节点(root),通过TreeNode对象来表示树的结构

public class Tree<T> {

    TreeNode<T> root;

    public Tree(TreeNode<T> root) {
        this.root = root;
    }

    /**
     * 添加子节点
     */
    public void addChild(TreeNode<T> parent, TreeNode<T> child) {
        parent.children.add(child);
    }

    /**
     * 删除子节点
     */
    public void removeChild(TreeNode<T> parent, TreeNode<T> child) {
        parent.children.remove(child);
    }

    /**
     * 修改节点值
     */
    public void updateValue(TreeNode<T> node, T newVal) {
        node.val = newVal;
    }

    /**
     * 深度优先搜索(DFS)
     */
    public TreeNode dfs(T target) {
        return dfsHelper(root, target);
    }


    /**
     * dfs(T target) 方法接收一个目标值作为参数,
     * 以深度优先搜索的方式在树中查找匹配的节点,并返回找到的节点。如
     * 果未找到匹配的节点,则返回 null
     */
    private TreeNode<T> dfsHelper(TreeNode<T> node, T target) {
        if (node == null) {
            return null;
        }

        if (node.val.equals(target)) {
            return node;
        }

        for (TreeNode<T> child : node.children) {
            TreeNode<T> result = dfsHelper(child, target);
            if (result != null) {
                return result;
            }
        }

        return null;
    }

    /**
     * 广度优先搜索(BFS)
     */
    public TreeNode<T> bfs(T target) {
        if (root == null) {
            return null;
        }

        List<TreeNode<T>> queue = new ArrayList<>();
        queue.add(root);

        while (!queue.isEmpty()) {
            TreeNode<T> node = queue.remove(0);

            if (node.val.equals(target)) {
                return node;
            }

            queue.addAll(node.children);
        }

        return null;
    }
}

3 简单的测试用例

    public void testTree() {
        // 创建树节点
        TreeNode node1 = new TreeNode(1);
        TreeNode node2 = new TreeNode(2);
        TreeNode node3 = new TreeNode(3);
        TreeNode node4 = new TreeNode(4);
        TreeNode node5 = new TreeNode(5);

        // 构建树结构
        Tree tree = new Tree(node1);
        tree.addChild(node1, node2);
        tree.addChild(node1, node3);
        tree.addChild(node2, node4);
        tree.addChild(node3, node5);

        // 测试增删改查操作
        System.out.println("深度优先搜索结果:" + tree.dfs(4).val); // 输出:4
        System.out.println("广度优先搜索结果:" + tree.bfs(5).val); // 输出:5

        tree.updateValue(node3, 6);

        tree.removeChild(node3, node5);

    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值