数据结构(树)

树形结构是一种非常重要的数据结构,它被广泛用于各种实际应用中,如文件系统、搜索引擎、数据库索引等;常用来做查询操作

树的基本概念#

节点(Node):树形结构中的基本元素,它可以是数据元素,也可以是一个空指针。

边(Edge):连接两个节点的线段,表示父子关系。

子树(Subtree):以某个节点为根节点的树。

父节点(Parent Node):一个节点在树中直接上层节点。

祖先节点(Ancestor Node):从根节点到该节点所经过的所有节点。

子孙节点(Descendant Node):以该节点为根的子树中所有节点。

根节点(Root Node):树中最顶层的节点,它没有父节点。

叶子节点(Leaf Node):没有子节点的节点。

树的深度(Depth):树中节点的层最大数。

树的度(Degree):树中所有节点度的最大值。

常见的树结构#

二叉搜索树(Binary Search Tree):也叫做二叉查找树、有序二叉树或者排序二叉树。是指一棵空树或者具有下列性质的二叉树:

  • 如果任意节点的左子树不为空,则左子树上所有节点的值均小于它的根节点的值。
  • 如果任意节点的右子树不为空,则右子树上所有节点的值均大于它的根节点的值。
  • 任意节点的左子树、右子树均为二叉搜索树。

平衡二叉树(Balanced Binary Tree):它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。平衡二叉树的常用实现方法有红黑树、AVL、替罪羊树、Treap、伸展树等。 最小二叉平衡树的节点的公式如下 F(n)=F(n-1)+F(n-2)+1 这个类似于一个递归的数列,可以参考Fibonacci数列,1是根节点,F(n-1)是左子树的节点数量,F(n-2)是右子树的节点数量

AVL树:AVL树是高度平衡的二叉树。它的特点是: AVL树中任何节点的两个子树的高度最大差别为1,AVL树的平衡性要求更加严格,因此在插入和删除操作时可能需要进行更多的旋转操作来保持平衡,这可能会导致性能略低于其他平衡二叉树

红黑树(Red Black Tree) 红黑树是一种自平衡的二叉搜索树,它通过引入“颜色”来保持树的大致平衡,是在计算机科学中用到的一种数据结构,典型的用途是实现关联数组,是平衡二叉树和AVL树的折中

红黑树与AVL树的比较:

  • AVL树的时间复杂度虽然优于红黑树,但是对于现在的计算机,cpu太快,可以忽略性能差异
  • 红黑树的插入删除比AVL树更便于控制操作
  • 红黑树整体性能略优于AVL树(红黑树旋转情况少于AVL树)

B树(B-tree):多路搜索树,每个节点可以拥有多个子节点。

  • 优点:适合大规模数据存储,减少磁盘I/O操作;搜索、插入和删除的时间复杂度稳定在O(log n)。
  • 缺点:实现复杂,不适合小规模数据。

B+树(B+ tree) 基于B树的一种树结构,叶节点之间通过指针连接形成有序链表

  • 优点:适合大规模数据存储,减少磁盘I/O操作;范围查询效率高。
  • 缺点:实现复杂。

Trie树(前缀树) 多叉树,用于存储字符串集合,通常用于字符串检索。

  • 优点:适合前缀匹配检索;搜索效率高。
  • 缺点:空间消耗较大。

Java实现树形结构#

前面我们知道有很多不同的树结构,每种树结构都有不同的存储方式。比如二叉树、平衡二叉树、AVL树等,为了减少树的深度而做特殊的扁平化处理;下面是一个简单的二叉树示例:

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    TreeNode(int x) {
        val = x;
    }
}

public class BinaryTree {
    private TreeNode root;

    public void addElement(int value) {
        root = addElementToTree(root, value);
    }

    private TreeNode addElementToTree(TreeNode node, int value) {
        if (node == null) {
            return new TreeNode(value);
        }

        if (value < node.val) {
            node.left = addElementToTree(node.left, value);
        } else if (value > node.val) {
            node.right = addElementToTree(node.right, value);
        }

        return node;
    }
}

将第一个元素当作根节点,小于val则放入left,大于val放入right节点。但这种方式很容易发生不平衡的情况,极有可能很形成链表的方式。导致出现复杂度O(n)的情况;所以后续引入的平衡二叉树的概念,通过旋转的方式调整树的结构

4种常见的遍历方式#

前序遍历 访问根结点;先序遍历左子树;先序遍历右子树。
中序遍历 中序遍历左子树;访问根结点;中序遍历右子树。
后序遍历 后序遍历左子树;后序遍历右子树;访问根结点。
层序遍历 从上到下、从左到右依次访问每一个节点

public class TreeTraversal {
    // 前序遍历
    public void preOrder(TreeNode root) {
        if (root != null) {
            System.out.print(root.val + " ");
            preOrder(root.left);
            preOrder(root.right);
        }
    }

    // 中序遍历
    public void inOrder(TreeNode root) {
        if (root != null) {
            inOrder(root.left);
            System.out.print(root.val + " ");
            inOrder(root.right);
        }
    }

    // 后序遍历
    public void postOrder(TreeNode root) {
        if (root != null) {
            postOrder(root.left);
            postOrder(root.right);
            System.out.print(root.val + " ");
        }
    }

    // 层序遍历
    public void levelOrder(TreeNode root) {
        if (root == null) {
            return;
        }
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            TreeNode node = queue.poll();
            System.out.print(node.val + " ");
            if (node.left != null) {
                queue.offer(node.left);
            }
            if (node.right != null) {
                queue.offer(node.right);
            }
        }
    }
    public static void main(String[] args) {
        TreeNode root = new TreeNode(1);
        root.left = new TreeNode(2);
        root.right = new TreeNode(3);
        root.left.left = new TreeNode(4);
        root.left.right = new TreeNode(5);
    }
}

运行这段代码将输出以下结果:

前序遍历:
1 2 4 5 3 
中序遍历:
4 2 5 1 3 
后序遍历:
4 5 2 3 1 
层序遍历:
1 2 3 4 5 

总结#

树形结构是一种非常有用的数据结构,它可以帮助我们有效地管理和处理具有层次关系的数据。在Java中,我们可以使用类来表示树的节点,并通过添加和删除节点来操作树形结构。
了解更多:https://www.cnblogs.com/henuliulei/p/15114440.html

posted @   糯米๓  阅读(45)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示