算法学习之二叉排序树

面试官问我:什么是“伸展树”? 学过数据结构的小伙伴,一定都知道二叉查找树,也叫二叉排序树,英文缩写是BST。 为了维持二叉查找树的高效率查找,就需要对二叉查找树进行平衡调整。在数据结构当中大名鼎鼎的红黑树、AVL,就是典型的自平衡二叉查找树。 今天,我们来介绍一种更有意思的自平衡二叉树:伸展树。它的英文名字是Splay Tree。 Part 1为什么要伸展 我们来回顾一下,二叉搜索树满足:左子结点 < 当前结点 < 右子结点 为什么要有平衡树呢?因为当二叉搜索树如下图“瘸腿”时,搜索左侧的结点,原来的速度... 阅读详情

为了使二叉树的查找效率更高,我们对二叉树进行了优化,如此产生了对于查找效率比较高的二叉排序树(也叫二叉搜索树)

目录

概念

原理

创建二叉排序树

二叉排序树的查找


概念

BST(Binary Sort(Search) Tree),对于二叉排序树的任何一个非叶子结点,要求左子节点的值比当前节点的值小,右子节点的值比当前节点的值大,特别说明:如果有相同的值,可以将该节点放在左子节点或右子节点

原理

因二叉排序树满足上述特点,其查找操作如下:

先检查当前节点是否与要查找的值匹配

  • 若匹配则返回该节点

  • 若节点值小于查找值,则遍历其右子树(右子树的值均大于根结点)

  • 若节点值大于查找值,则遍历其左子树(左子树的值均小于根结点)

创建二叉排序树

这里我们给出一个数组,根据数组中的值构建二叉排序树

构建的步骤:

  • 我们默认数组中的第一个值为根结点

  • 从根节点开始遍历

    • 若有左节点且插入的值比节点值小,则向左遍历

    • 若有右节点且插入的值节点值大,则向右遍历

  • 遍历到相应位置后,根据节点值的大小,将插入的节点放到其左右节点

class BinaryNode {
    private int value;
    BinaryNode left;
    BinaryNode right;

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }

    @Override
    public String toString() {
        if (left != null && right != null) {
            return "HuffNode{ " +
                    " value=" + value +
                    " left=" + left.value +
                    " right=" + right.value +
                    " }";
        } else if (left != null && right == null) {
            return "HuffNode{ " +
                    " value=" + value +
                    " left=" + left.value +
                    " }";
        }
        else if (right != null && left == null) {
            return "HuffNode{ " +
                    " value=" + value +
                    " right=" + right.value +
                    " }";
        }else {
            return "HuffNode{ " +
                    " value=" + value +
                    " }";
        }
    }

    public BinaryNode(int value) {
        this.value = value;
        this.left = null;
        this.right = null;
    }
    public BinaryNode() {
        this.left = null;
        this.right = null;
    }
}

class BinarySortTree {
    private BinaryNode root;

    public BinaryNode getRoot() {
        return root;
    }

    /**
     * 构造二叉排序树,要求左子节点的值比当前节点的值小,右子节点的值比当前节点的值大
     * 特别说明:如果有相同的值,可以将该节点放在左子节点或右子节点
     * @param arr 原数组
     */
    public void createBinarySortTree(int []arr) {
        BinaryNode node = new BinaryNode(arr[0]);
        this.root = node;
        for (int i = 1; i < arr.length; i++) {
            // 1.从根节点开始
            node = root;
            // 2.比节点值小且有左节点,向左移动
            while (node.left != null && arr[i] <= node.getValue() || node.right != null && arr[i] > node.getValue()) {
                if (node.left != null && arr[i] <= node.getValue()) {
                    node = node.left;
                }
                // 3.比节点值大且有右节点,向右移动
                if (node.right != null && arr[i] > node.getValue()) {
                    node = node.right;
                }
            }
            // 4.移动到相应位置后,与节点值做比较
            // 比节点值大放在右边
            if (arr[i] > node.getValue()) {
                BinaryNode temp = new BinaryNode(arr[i]);
                node.right = temp;
            }
            // 小于等于节点值放在左边
            if (arr[i] <= node.getValue()) {
                BinaryNode temp = new BinaryNode(arr[i]);
                node.left = temp;
            }
        }
    }

}

public class BinarySortTreeDemo {
    public static void main(String[] args) {
        int[] arr = {10,11,7,6,8,9};
        BinarySortTree binarySortTree = new BinarySortTree();
        // 创建二叉排序树
        binarySortTree.createBinarySortTree(arr);
    }
}

此时我们根据数组{5,10,9,6,1,11,3,8}构建出来的二叉排序树如图:

二叉排序树的查找

 查找方法原理已将说明,这里不再赘述,直接上代码(其中附带前序遍历的代码)

class BinaryNode {

    /**
     * 前序遍历
     */
    public void preOrder() {
        System.out.println(this);
        if (this.left != null) {
            this.left.preOrder();
        }
        if (this.right != null) {
            this.right.preOrder();
        }
    }

    /**
     * 查询节点,要查找的值比当前节点值小则向左查询,反之向右查询,若找到则返回
     * @param value 要查询的节点的值
     * @return 若找到节点,则返回该节点,否则,返回null
     */
    public BinaryNode binaryFind(int value) {
        BinaryNode node = null;
        // 找到则返回该节点
        if (this.value == value) {
            node = this;
            return  node;
        } else if (this.left != null && this.value > value) {
            // 比节点值小,向左查询
            node = this.left.binaryFind(value);
        }else if (this.right != null && this.value < value){
            // 比节点值大,向右查询
            node = this.right.binaryFind(value);
        }
        return node;
    }

}
class BinarySortTree {
   
    /**
     * 前序遍历
     */
    public void preOrder() {
        if (root == null) {
            System.out.println("k");
        }else {
            root.preOrder();
        }
    }

    /**
     * 查询节点,要查找的值比当前节点值小则向左查询,反之向右查询,若找到则返回
     * @param value 要查询的节点的值
     * @return 若找到节点,则返回该节点,否则,返回null
     */
    public BinaryNode binaryFind(int value) {
        if (root == null) {
            return null;
        } else {
            BinaryNode node = root.binaryFind(value);
            return node;
        }
    }
}

节点的删除

为了使删除节点后的二叉树依旧是一个二叉排序树,我们的删除操作要复杂一点

当我们删除二叉排序树中的一个节点时,为了使其仍然构成排序树,我们需要将删除节点的

  • 左子树中最大的节点放到删除节点的位置

    • 左子树中的最大值比左子树中任意值都大,比右子树中任意值都小

  • 或者右子树中最小的节点放到删除节点的位置

    • 右子树中的最小值比右子树中任意值都小,比左子树中任意值都大

class BinaryNode {
    /**
     * 删除节点,删除完之后,依旧保持为二叉排序树
     * @param value
     * @return
     */
    public boolean delBinary(int value) {
        boolean flag = false;
        // 方案2
        // 1. 找到父节点
        while (this.left != null && value <= this.getValue() || this.right != null && value > this.getValue()) {
            // 如果该节点的左子节点或者右子节点为该值,则找到其父节点
            if (this.left != null && this.left.value == value || this.right != null && this.right.value == value) {
                break;
            }
            // 节点值大于查找值,并且左子树不为空,向左遍历
            if (this.value > value && this.left != null) {
                flag = this.left.delBinary(value);
                return flag;
            }
            // 节点值小于查找值,并且右子树不为空,向右遍历
            if (this.value < value && this.right != null) {
                flag = this.right.delBinary(value);
                return flag;
            }
        }
        // 如果父节点的左子节点是叶子节点或者右子节点是叶子节点,即要删除的节点是叶子节点,直接删除即可
        if (this.left != null && this.left.value == value && this.left.left == null && this.left.right == null || this.right != null && this.right.value == value && this.right.left == null && this.right.right == null) {
            if (this.left != null) {
                this.left = null;
            }
            if (this.right != null) {
                this.right = null;
            }
            flag = true;
        } else {
            //删除该节点后将该节点左子树中最大的节点或者右子树最小的节点放到该节点的位置
            // 这里我们的思路是新建一个节点与最大节点的值相同,然后让最大节点的父节点的右子树指向最大节点的左子树(即删除了最大节点)
            // 在让新建节点的左节点指向删除节点的左子树,再将删除节点的父节点指向新建节点(最大节点替换了删除节点)
            // 要删除的节点
            System.out.println("-----"+this);
            // 如果要删除的节点是父节点的左节点
            if (this.left != null && this.left.value == value) {
                // 要删除的节点
                BinaryNode node = this.left;
                // 如果删除的节点没有左子树,直接将右子树放过来
                if (node.left == null) {
                    this.left = node.right;
                    return true;
                }
                // 如果删除的节点没有右子树,直接将左子树放过来
                if (node.right == null) {
                    this.right = node.left;
                    return true;
                }
                // 左子树的根结点
                BinaryNode index = node.left;
                // 找到左子树中最大的节点的父节点
                while (index.right != null) {
                    if (index.right.right == null) {
                        break;
                    }
                    index = index.right;
                }
                // 创建一个新的节点,新节点的值与最大值相同
                BinaryNode maxNode = new BinaryNode(index.right.value);
                // 让最大节点的父节点右节点指向最大节点的左子树
                index.right = index.right.left;
                maxNode.left = node.left;
                this.left = maxNode;
            }else {
                BinaryNode node = this.right;
                // 如果删除的节点没有左子树,直接将右子树放过来
                if (node.left == null) {
                    this.left = node.right;
                    return true;
                }
                // 如果删除的节点没有右子树,直接将左子树放过来
                if (node.right == null) {
                    this.right = node.left;
                    return true;
                }
                BinaryNode index = node.left;
                while (index.right != null) {
                    if (index.right.right == null) {
                        break;
                    }
                    index = index.right;
                }
                // 创建一个新的节点,新节点的值与最大值相同
                BinaryNode maxNode = new BinaryNode(index.right.value);
                // 让最大节点的父节点右节点指向最大节点的左子树
                index.right = index.right.left;
                // 新建节点的左节点指向删除节点的左子树
                maxNode.left = node.left;
                this.right = maxNode;
            }
        }
        return flag;
    }
}
class BinarySortTree {
    /**
     * 删除节点,删除完之后,依旧保持为二叉排序树
     * @param value
     * @return
     */
    public boolean delBinary(int value) {
        boolean flag = false;
        if (root == null) {
            return false;
        } else {
            flag = root.delBinary(value);
        }
        return flag;
    }
}

AI工程化之生成式UI & A2UI(二) 本文介绍了生成式UI框架A2UI的架构设计与核心实现。项目采用AI协作开发模式,通过ATDD(AI驱动的测试驱动开发)确保代码质量。前端SDK基于zustand实现框架无关的状态管理,包含协议解析器、存储管理、渲染器等核心模块。重点展示了基础store构建、A2UI协议解析器的实现过程,包括mock数据准备、测试用例生成和可视化调试。项目采用monorepo管理,利用vite实现高效开发构建。整个系统设计遵循模块化原则,通过清晰的接口定义实现各组件解耦,为后续功能扩展打下基础。 阅读详情

相关推荐

医学图像中的小目标病灶检测难题:我的硕士研究总结与思考

医学图像中的小目标检测和分割,主要指在CT、MRI、超声等医学影像中识别和分割微小病灶或细小结构。这些小目标通常体积小、边界模糊、特征不明显,却往往是关键病灶,例如肺部小结节、脑微出血、乳腺微钙化等。

weixin_45638136的博客 2370

二叉排序树

一.定义 数据集无序方便插入与删除 有序利于查找 在一般情况下,查询效率比链表结构要高 二.性质 1.若左子树不空,则左子树上所有结点的值均小于它的根结点的值; 2.若右子树不空,则右子树上所有结点的值均大于它的根结点的值; 3。左、右子树也分别为二叉排序树(递归) 4.没有键值相等的结点 三.查找操作 遍历采用中序遍历,这样成为了有序 1.二叉树的结构 2.代码 四.插入操作 插入要先查找是否存在 存在则不再插入 插入就是将关键字放到树中合适的位置 五.删除操作 删除的核心思想就是 不是特殊结点(

triggerV的博客 918

Cesium体渲染实战:从医学CT到气象数据的3D可视化全攻略

本文详细介绍了如何利用Cesium体渲染技术实现医学CT和气象数据的3D可视化。从数据预处理到交互式渲染,涵盖了DICOM和NetCDF格式的处理技巧,以及性能优化的实战策略,帮助开发者高效处理复杂的三维数据集。

weixin_28717431的博客 420

「架构师必学」数据库中查询性能的提升--索引的深度剖析

本文为博学谷狂野架构师团队原创内容,转载请标明出处。 课程说明 索引的本质 数据结构与算法 B+树深入剖析 索引的使用 1、索引的本质 在生产环境中,随着数据量不断的增长,SQL执行速度会越来越慢,常见的手段就是通过索引来提升查询速度,那么究竟为什么要添加索引?应该如何正确添加索引?本套课程将以MySQL为例,从索引的底层进行分析,一起探究索引相关的一系列问题。 MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构(有序)。所以,就可以得到索引的本质:...

a6636656的博客 1292

Qt6导入QtChart绘制图表(添加组件)

我在按照大佬们的说明添加QtChart时发现,我的电脑上并不能正确的添加QtChart并编译通过,所以在综合了两位大佬的说明又自己探索了一番后,正确编译通过,分享出来,以便同志们节省一些时间。

Nuaa0719301zyx的博客 2952

期末求生指南:手把手教你用浏览器开发者工具绕过百一测评切屏检测

本文详细介绍了如何利用浏览器开发者工具绕过百一测评的切屏检测功能。通过分析JavaScript事件监听机制,定位关键检测代码,并提供实时调试和本地覆盖两种修改方法,帮助学生在遵守规则的前提下更灵活地应对在线考试。文章还包含风险控制和替代方案等实用建议。

weixin_28698059的博客 551

二叉排序树与平衡二叉树

目录 1、为什么要用树表查询 ​ 2、二叉排序树 2.1二叉排序树的定义 2.2二叉排序树的操作-查找 2.3用二叉链表存储二叉排序树 2.4二叉排序树递归查找的算法与思想 2.5二叉排序树的查找分析 2.6二叉排序树的操作-插入 2.7二叉排序树的操作-生成 2.8二叉排序树的操作-删除 2.8.1删除节点要考虑的两点 2.8.2若被删除结点节点为叶子节点 ​ 2.8.3若被删除节点只有左子树或只有右子树 2.8.4若被删除节点既有左子树又有右子树 2.8.5 三...

qq_52971866的博客 826

ADS2023实战:2.4GHz超外差接收机从设计到链路预算全流程解析

本文以ADS 2023软件为平台,详细解析了2.4GHz超外差接收机从核心指标定义、架构原理到完整链路搭建与仿真的全流程。通过实战演练,重点阐述了如何利用ADS进行谐波平衡仿真和链路预算分析,以量化评估系统增益、噪声系数等关键性能,为射频工程师提供了一套从理论到仿真的系统级设计方法。

herb5的博客 819

算法学习之二叉排序树的平衡化

首先提出问题问什么要让二叉树排序树平衡化比如给出{1,2,3,4,5,6,7}让我们将其构造成排序树,如下图可以看出,此时二叉树变成了数组,而我们为了提高搜索效率的初衷也被打破了为了解决这种极端情况,我们需要对二叉树进行平衡化。...

fnetworkmaster的博客 886

从零开始的立绘拆包教程

蓝毒小天使天下第一! 本文拆包教程不限于明日方舟,在后面也会给出其他手游的拆包教程,例如少女前线 首先拆包最简单的无非就是拆取游戏资源,例如游戏立绘,音频,视频等,再深层次一点有拆取游戏配置文件,apk反编译得到部分源码 在本文,我们只介绍拆取游戏资源和对游戏资源的后期处理(因为另外两个讲道理我也没太搞懂,虽然可以提取游戏配置文件,但似乎大部分重要的数据都有加密,反编译出来的源码也只是部分,...

Conyrol的博客 9万+

# YOLOv11-seg改进系列 | 引入CVPR MetaFormer的C3k2_PoolingFormerCGLU模块,池化Token混合+CGLU门控MLP

本文引入 CVPR 2022 论文(MetaFormer/PoolFormer)提出的 MetaFormer 元架构设计,以Pooling Token 混合器 + ConvolutionalGLU(CGLU)MLP构成,将其封装为,用于替换 YOLOv11-seg 的 C3k2 块。对比维度C3k2(基线)C3k2_PoolingFormerCGLU(本文)参数量(n scale)2.46M≈2.49M9.6≈9.69.7(+1.0%)架构范式单阶段卷积MetaFormer 双阶段。

qq_44224801的博客 846

数据结构与算法学习之二叉排序树及二叉排序树的相关操作

<br />二叉排序树是数表动态查找中的一种重要应用。<br />二叉排序树具备以下特点:<br />1)若它的左子树不为空,则左子树上的各结点的值均小于它的根结点的值;2)若它的右子树不为空,则其右子树上的各结点的值均大于等于它的根节点的值;3)它的左子树和右子树分别又是一个二叉排序树。<br />二叉排序树中的一些操作应该掌握,如如何建立一个二叉排序树,它的插入和删除操作,以及查找某个元素值的操作。下面是本人在学习时联系写的一些代码:<br />#include <iostream> using na

guiyinzhou的专栏 978

手把手教你学SOME/IP「3.2.1.发布/订阅行为」

本文详细介绍了SOME/IP协议中的服务发现机制,重点解析了发布/订阅行为的流程。主要内容包括:1)服务发布与Method通信流程,涵盖find/offer报文交互、TTL保活机制及异常处理;2)服务订阅与Event通信流程,包括subscribe/ack报文交互和组播延迟机制;3)特殊场景如快速发送、半周期回复、重置订阅等机制。通过邮局订阅报纸的类比,帮助理解服务发现的核心原理,并强调流程图对于问题定位的重要性。文章为SOME/IP协议的工程实现提供了实用指导。

nihaoljq2010的博客 1222

数据结构和算法学习之二叉排序树

数据结构和算法学习之二叉排序树

m0_55895641的博客 152

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

算法与数据结构学习笔记(9):无序表之二叉排序树

可引用信号量,定义一个全局变量,让所有设备分别操作此变量

光脚小孩的博客 513

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

查找算法之二叉排序树

文章目录二叉排序树定义及性质二叉排序树的存储结构二叉排序树的递归查找查找分析二叉排序树平均查找长度 二叉排序树 定义及性质 二叉排序树(Binary Sort Tree)又称为二叉搜索树、二叉查找树。 定义: 二叉排序树或是空树,或是满足如下性质的二叉树: (1)若其左子树非空,则左子树上所有结点的值均小于根结点的值; (2)若其右子树非空,则右子树上所有结点的值均大于等于根结点的值; (3)其左右子树本身又各是一棵二叉排序树 二叉排序树的性质: 中序遍历非空的二叉排序树所得到的数据元素序列是一个按关键字

diviner_s的博客 3319

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

数据结构之二叉排序树的建立

一、普通二叉树的建立    提到二叉树的建立,就不得不提一下“递归”,建立二叉树所采用的思想就是递归。递归基本形式:  void recursion() { if(递归结束条件) { 表达式 } else { 表达式; recursion(); } }    有了递归思想后,我们如何建立二叉树呢?比如建立如图的二叉树:问题:发现此二叉树并不是完全二叉树,有的只有右孩子没有左...

ZHAO 6万+

数据结构之二叉排序树

二叉排序树一、二叉排序树的定义二、二叉排序树的查找算法三、二叉排序树的插入算法四、二叉排序树的删除算法五、二叉排序树性能分析 一、二叉排序树的定义 二叉排序树又称“二叉查找树”、“二叉搜索树” 一棵空树,或者是具有下列性质的二叉树: (1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值; (2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值; (3)左、右子树也分别为二叉排序树; (4)没有键值相等的结点。 二叉排序树通常采用二叉链表作为存储结构。中序遍历二叉排序树可得到一个依据关

weixin_43520450的博客 2098

Java算法之二叉排序树

Java 算法之二叉排序树 二叉排序树(BST)的定义 二叉排序树或者是空树,或者是满足以下性质的二叉树: 若它的左子树不空,则左子树上所有关键字的值均小于根关键字的值。 若它的右子树不空,则右子树上所有关键字的值均大于根关键字的值。 左右子树又各是一棵二叉排序树。 说明:由二叉排序树的定义可以知道,如果输出二叉排序树的中序遍历序列,则这个序列是递增有序的。 二叉排序树的存储结构 二叉排序树通...

java阳旭的博客 579

查找——树表之二叉排序树

这篇文章就介绍一下关于树表的查找方法。我们知道,当表插入、删除操作频繁时,为维护表的有序性,需要移动表中很多记录。所以改用动态查找表——几种特殊的树,我们主要介绍二叉排序树与平衡二叉树。

Blusher1的博客 1701

C语言动态查找表之二叉排序树

目录 1.静态查找表与动态查找表的比较 2.二叉排序树(Binary Sort Tree) 2.1二叉排序树的定义 2.2二叉排序树的查找算法 2.3二叉排序树的插入算法 2.4二叉排序树的构造算法 2.5二叉排序树的删除算法 3.源代码示例 1.静态查找表与动态查找表的比较 静态查找表一旦生成,所含记录在查找过程中一般是固定不变的。动态查找表不仅可以实现对数据的查找,在表生成...

记录学习点滴 2590

Python描述数据结构之二叉排序树篇

本篇章主要介绍二叉树的应用之一------二叉排序树,包括二叉排序树的定义、查找、插入、构造、删除及查找效率分析。

夏小悠的博客 1648

项目 1 - 验证算法之二叉排序树

/*  *Copyright (c) 2016,烟台大学计算机学院  *All right reserved.      *文件名称:test.cpp      *作者:杨天瑞      *完成日期:2016年12月15日      *版本号:v1.7.1     *      *  问题描述:验证线分块查找。               *

Foreigner_Y的博客 1355

动态查找之二叉排序树

二叉排序树简介建立 之前讲过二分、插值和斐波那契查找方式,这三种查找算法是针对有序线性表的,但有序表的插入和删除操作比较复杂,它需要移动插入和删除元素之后的所有元素。那有没有即可以高效的查找又可以高效的插入和删除呢?有,二叉排序树就可以实现。下面介绍一下二叉排序树。 简介 二叉排序树又称二叉查找树,它若不为空则具有如下性质: 若左子树不为空,则左子树上所有节点的值均小于它根节点的值; 若右子树不...

横扫天下的博客 1951

查找-之二叉排序树(查找、插入、删除)

问题: 有序的线性表采用:折半/二分、插值、斐波那契查找相比顺序查找效率得到提高,但是在插入和删除时效率低(为维持数据的有序性) 在高效实现查找操作时,如何提高插入和删除的效率? 在一些应用场景:在查找时需要插入和删除 解决方法: 二叉排序树 二叉排序树特点 1)若左子树不为空,左子树上所有结点的值均小于或等于它的根节点的值 2)若右子树不为空,右子树上所有结点的值均大于...

heda3的博客 3419

数据结构之二叉排序树的基本操作

二叉排序树的创建,查找,删除

bsqetuo的博客 3862
上一篇: 算法学习之二叉树
下一篇: 算法学习之二叉排序树的平衡化
管管儿
博客等级 码龄7年 1粉丝 11原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值