【数据结构与算法 13】二叉树

【数据结构和算法】13张图解+实例+实战题目,二叉树存储结构详解 ???? 作者:Linux猿 ???? 简介:优快云博客专家????,华为云享专家????,Linux、C/C++、面试、刷题、算法尽管咨询我,关注我,有问题私聊! ???? 关注专栏: 动图讲解数据结构和算法(优质好文持续更新中……)???? ???? 欢迎小伙伴们点赞????、收藏⭐、留言???? 一、顺序存储结构 二、链式存储结构 2.1左右孩子法 2.2 左孩子右兄弟法 三、总结 ... 阅读详情

一、前言

数组的搜索比较方便,可以直接用下标,但删除和插入就比较麻烦;

链表与之相反,删除和插入元素很快,但查找比较慢;

此时,二叉树应运而生,二叉树既有链表的好处,也有数组的好处,在处理大批量的动态数据时比较好用,是一种折中的选择。

文件系统和数据库系统一般都是采用树(特别是B树)的数据结构数据,主要为排序和检索的效率。

二叉树是一种最基本最典型的排序树,用于教学和研究树的特性,本身很少在实际中进行应用,因为缺点太明显,就像冒泡排序一样,因为效率问题并不实用,但也是我们必须会的。

二、二叉树缺点

1、顺序存储可能会浪费空间(在非完全二叉树的时候),但是读取某个指定的结点的时候效率比较高O(0);

2、链式存储相对于二叉树,浪费空间较少,但是读取某个结点的时候效率偏低O(nlogn)。

三、遍历与结点删除

二叉树是一种非常重要的数据结构,非常多的数据结构都是基于二叉树的基础演变而来的。对于二叉树有深度遍历和广度遍历,深度遍历有前序、中序以及后序三种遍历方法,广度遍历即我们寻常所说的层次遍历。由于树的定义本身就是递归定义,因此采用递归的方法实现树的三种遍历。

对于一段代码来说,可读性有时候要比代码本身的效率要重要的多。

1、四种基本的遍历思想

  • 前序遍历:根结点 -->左子树-->右子树;
  • 中序遍历:左子树 -->根结点-->右子树;
  • 后续遍历:左子树 -->右子树-->根结点;
  • 层次遍历:仅仅需按成次遍历即可;

2、自定义二叉树

3、代码实现

package dataStructure.tree;

public class BinaryTreeTest {
    public static void main(String[] args) {
        //创建一个二叉树
        BinaryTree binaryTree = new BinaryTree();
        //创建结点
        HeroNode root = new HeroNode(1, "宋江");
        HeroNode node2 = new HeroNode(2, "卢俊义");
        HeroNode node3 = new HeroNode(3, "吴用");
        HeroNode node4 = new HeroNode(4, "公孙胜");
        HeroNode node5 = new HeroNode(5, "关胜");
        root.setLeft(node2);
        root.setRight(node3);
        node3.setLeft(node4);
        node3.setRight(node5);
        binaryTree.setRoot(root);
        System.out.println("前序遍历");
        binaryTree.preOrder();
        System.out.println("中序遍历");
        binaryTree.midOrder();
        System.out.println("后序遍历");
        binaryTree.postOrder();
        binaryTree.delNode(3);
        System.out.println("删除结点3,前序遍历");
        binaryTree.preOrder();
    }
}

//定义BinaryTree 二叉树
class BinaryTree {
    private HeroNode root;

    public HeroNode getRoot() {
        return root;
    }

    public void setRoot(HeroNode root) {
        this.root = root;
    }
    //前序遍历
    public void preOrder() {
        if(this.root != null) {
            this.root.preOrder();
        }else {
            System.out.println("二叉树为空,不能遍历");
        }
    }
    //中序遍历
    public void midOrder() {
        if(this.root != null) {
            this.root.midOrder();
        }else {
            System.out.println("二叉树为空,无法遍历");
        }
    }
    //后序遍历
    public void postOrder() {
        if(this.root != null) {
            this.root.postOrder();
        }else {
            System.out.println("二叉树为空,无法遍历");
        }
    }

    //删除结点
    public void delNode(int no) {
        if(root != null) {
            //如果只有一个root结点, 这里立即判断root是不是就是要删除结点
            if(root.getNo() == no) {
                root = null;
            } else {
                //递归删除
                root.delNode(no);
            }
        }else{
            System.out.println("空树,不能删除~");
        }
    }
}

//先创建HeroNode 结点
class HeroNode {
    private int no;
    private String name;
    private HeroNode left; //默认null
    private HeroNode right; //默认null
    public HeroNode(int no, String name) {
        this.no = no;
        this.name = name;
    }
    public int getNo() {
        return no;
    }
    public void setNo(int no) {
        this.no = no;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public HeroNode getLeft() {
        return left;
    }
    public void setLeft(HeroNode left) {
        this.left = left;
    }
    public HeroNode getRight() {
        return right;
    }
    public void setRight(HeroNode right) {
        this.right = right;
    }
    @Override
    public String toString() {
        return "HeroNode [no=" + no + ", name=" + name + "]";
    }

    //前序遍历
    public void preOrder() {
        System.out.println(this);//先输出父节点
        //递归向左子树前序遍历
        if(this.left != null) {
            this.left.preOrder();
        }
        //递归向右子树前序遍历
        if(this.right != null) {
            this.right.preOrder();
        }
    }

    //中序遍历
    public void midOrder() {
        //递归向左子树中序遍历
        if(this.left != null) {
            this.left.midOrder();
        }
        System.out.println(this);//输出父节点
        //递归向右子树前序遍历
        if(this.right != null) {
            this.right.midOrder();
        }
    }

    //后序遍历
    public void postOrder() {
        //递归向左子树后序遍历
        if(this.left != null) {
            this.left.postOrder();
        }
        //递归向右子树前序遍历
        if(this.right != null) {
            this.right.postOrder();
        }
        System.out.println(this);//输出父节点
    }

    //递归删除结点
    //1.如果删除的节点是叶子节点,则删除该节点
    //2.如果删除的节点是非叶子节点,则删除该子树
    public void delNode(int no) {
        //思路
		/*
		 * 	1. 因为我们的二叉树是单向的,所以我们是判断当前结点的子结点是否需要删除结点,而不能去判断当前这个结点是不是需要删除结点.
			2. 如果当前结点的左子结点不为空,并且左子结点 就是要删除结点,就将this.left = null; 并且就返回(结束递归删除)
			3. 如果当前结点的右子结点不为空,并且右子结点 就是要删除结点,就将this.right= null ;并且就返回(结束递归删除)
			4. 如果第2和第3步没有删除结点,那么我们就需要向左子树进行递归删除
			5.  如果第4步也没有删除结点,则应当向右子树进行递归删除.

		 */
        //2. 如果当前结点的左子结点不为空,并且左子结点 就是要删除结点,就将this.left = null; 并且就返回(结束递归删除)
        if(this.left != null && this.left.no == no) {
            this.left = null;
            return;
        }

        //3.如果当前结点的右子结点不为空,并且右子结点 就是要删除结点,就将this.right= null ;并且就返回(结束递归删除)
        if(this.right != null && this.right.no == no) {
            this.right = null;
            return;
        }

        //4.我们就需要向左子树进行递归删除
        if(this.left != null) {
            this.left.delNode(no);
        }

        //5.则应当向右子树进行递归删除
        if(this.right != null) {
            this.right.delNode(no);
        }
    }
}

4、控制台输出

算法与数据结构【30天】集训营——树和二叉树课后习题详解之数据结构C语言严蔚敏版(13) 题目分析 ] 因为后序遍历栈中保留当前结点的祖先的信息,用一变量保存栈的最高栈顶指针,每当退栈时,栈顶指针高于保存最高栈顶指针的值时,则将该栈倒入辅助栈中,辅助栈始终保存最长路径长度上的结点,直至后序遍历完毕,则辅助栈中内容即为所求。解释:设度为 0 结点(叶子结点)个数为 A,度为 1 的结点个数为 B,度为 2 的结点个数为 C,有A=C+1, A+B+C=1001> ,可得 2C+B=1000 ,,又因为 C 为整数,所以 B=0, C=500 , A=501 ,即有> 501 个叶子结点。 阅读详情

相关推荐

RexUniNLU零样本通用自然语言理解:nlp_deberta_rex-uninlu_chinese-base模型实战解析

本文深入解析了RexUniNLU零样本通用自然语言理解模型(nlp_deberta_rex-uninlu_chinese-base)的实战应用。通过详细的环境配置、模型加载及实战案例,展示了该模型在零样本场景下的强大能力,如实体识别和复杂关系抽取,显著提升NLP任务效率。

weixin_29088655的博客 250

二叉树,平衡二叉树,红黑树,b树,b+树,b*树的缺点与优点以及使用场景

1、二叉查找树的缺点 二叉查找树,相信大家都接触过,二叉查找树的特点就是左子树的节点值比父亲节点小,而右子树的节点值比父亲节点大,如图 基于二叉查找树的这种特点,我们在查找某个节点的时候,可以采取类似于二分查找的思想,快速找到某个节点。n 个节点的二叉查找树,正常的情况下,查找的时间复杂度为 O(logn)。 之所以说是正常情况下,是因为二叉查找树有可能出现一种极端的情况,例如 这种情况也是满...

ff_simon的博客 1万+

手把手教你用Gazebo和VINS-MONO搞定VIO SLAM仿真(附Realsense D435i模型配置)

本文详细介绍了如何使用Gazebo和VINS-MONO构建VIO SLAM仿真环境,包括Realsense D435i模型的配置与集成。通过实战指南,帮助开发者快速搭建高保真仿真平台,优化VIO性能,并解决常见问题,适用于机器人感知与定位导航领域。

weixin_30682415的博客 158

二叉树与多叉树

序言 多叉树 2-3树 B树 B+树 B*树 序言 二叉树的缺点 二叉树需要加载到内存中,如果节点少,没什么问题,若是节点非常多,就会带来问题 当构建二叉树时,需要进行多次I/O操作,构造速度会有影响 节点海量,会造成二叉树的高度非常大降低操作速度 多叉树 每个节点可以右多个子节点 B树 节点的度:此节点拥有子节点的个数称为节点的度 数的度:数中所有节点的度的最大值 B树通过重新组织节点,降低了数的高度 文件系统或是数据库系统利用了磁盘预先读取原理,将一个节点的大小设置为一个页(一个页的大小为4

wangzilong_2019的博客 1664

QT5.14.2+VS2019安装配置教程Windows

QT5.14.2+VS2019安装使用教程Windows前言一. QT的下载与安装1. QT的下载2. QT的安装二. 配置Visual Studio编译器环境1. 扩展工具下载2. 扩展工具配置 前言 由于Visual Studio 的功能强大,很多开发人员比较熟悉使用,所以可以通过将QT配置到Visual Studio中进行开发。 一. QT的下载与安装 1. QT的下载 QT5.14.2下载地址 2. QT的安装 断开网络!断开网络!!断开网络!!! 安装QT之前,需要断开电脑的网络连接,这样就

Zander0的博客 7246

FCN---训练cityspaces

未经允许,不要随意转载! 最近想试试用FCN训练自己的数据集,想想标注是一件很费劲的事,于是就想到了用其他库里的数据,这里选用了cityspaces,默认已经配置好FCN. 1、下载cityspaces https://www.cityscapes-dataset.com/ 需要注册一个账号 cityspaces包含2...

wangyu088的专栏 2030

面试高频必问-二叉树

二叉树 1、为什么需要树这种数据结构 数组存储方式的分析 优点:通过下标方式访问元素,速度快。对于有序数组,还可使用二分查找提高检索速度。 缺点:如果要检索具体某个值,或者插入值(按一定顺序)会整体移动,效率较低 操作示意图: 链式存储方式的分析 优点:在一定程度上对数组存储方式有优化(比如:插入一个数值节点,只需要将插入节点,链接到链表中即可,删除效率也很好)。 缺点:在进行检索时,效率仍然较低,比如(检索某个值,需要从头节点开始遍历) 操作示意图: 树存储方式的分析 能提高数据存储,读取的效率,比

qq_25913607的博客 513

详解相机的sensor工作原理

目录sensor成像原理拜尔马赛克变换(BAYER DEMOSAICING)维伦阵列摩尔纹 sensor成像原理 相机或摄像头使用数百万个微小的光腔(感光元件)来记录图像。 成像时,sensor将镜头投射来的光子储存为模拟电信号。 曝光完成后,相机关闭这些光腔(感光元件),然后通过测量模拟电信号的强度来评估每个腔中有多少光子掉入来计算数字电信号的数值。 然后模拟电信号转换为数字电信号,数字电信号的数值由位深度决定(RGB的位深度)。 最后,根据正在记录的文件格式(8位JPEG位0-255),可能会再次降低

路人coder 2万+

二叉树(链式存储)

二叉树(链式存储) 1、树数据结构与数组和链表的区别 数组存储方式的分析 优点: 通过 下标方式访问元素,速度快。对于有序数组,还可使用二分查找提高检索速度。 缺点: 如果要检索具体某个值,或者插入值( 按一定顺序) 会整体移动,效率较低 链式存储方式的分析 优点: 在一定程度上对数组存储方式有优化(比如: 插入一个数值节点,只需要将插入节点,链接到链表中即可, 删除效率也很好)。 缺点: 在进行检索时,效率仍然较低,比如(检索某个值,需要从头节点开始遍历) 树存储方式的分析

qq_43906881的博客 2232

2.1 直流无刷电机(BLDC):机械结构与组件

本文详细解析了直流无刷电机(BLDC)的机械结构与核心组件。BLDC电机通过电子换向取代传统机械电刷,主要包含定子、转子、位置传感器和电子换向器四大组件。定子采用硅钢片叠压结构,配有三相绕组;转子采用永磁体材料,结构设计影响转矩特性;位置传感器(霍尔、编码器、旋转变压器)实现精准换向;电子换向器通过功率逆变拓扑完成电流控制。文章还对比了不同绕组类型、永磁材料及传感器技术的性能特点,为BLDC电机的设计与应用提供了理论基础。

技术工作者 387

C# MVVM的“核武器”:CommunityToolkit.Mvvm的RelayCommand实战全解

你默默打开VS:“该用RelayCommand的‘量子纠缠’魔法了!用户点击按钮无响应,调试器显示命令未绑定,但代码看起来完美无缺。“我的MVVM应用?那可是能穿越线程的命令量子计算机!异步操作阻塞了UI线程,用户界面变成“加载中”死循环。:UI与业务逻辑通过命令“量子隧道”解耦。:所有长时间操作自动进入“量子跃迁”模式。:携带任意上下文的“量子信封”传递。:命令可用性随数据变化实时同步。

java专栏 663

二叉树知识总结

数组的搜索比较方便,可以直接用下标,但删除和插入就比较麻烦;链表与之相反,删除和插入元素很快,但查找比较慢;此时,二叉树应运而生,二叉树既有链表的好处,也有数组的好处,在处理大批量的动态数据时比较好用,是一种折中的选择。文件系统和数据库系统一般都是采用树(特别是B树)的数据结构数据,主要为排序和检索的效率。二叉树是一种最基本最典型的排序树,用于教学和研究树的特性,本身很少在实际中进行应用,因为缺点太明显,就像冒泡排序一样,因为效率问题并不实用,但也是我们必须会的。//默认null。...

追光少年的博客 2859

【BlueZ】编译产物详解:可执行文件/库文件/工具的生成路径与用途

BlueZ二次开发编译产物机制解析 摘要:在BlueZ蓝牙协议栈二次开发中,90%的报错源于对编译产物类型和路径的混淆。本文系统剖析BlueZ的三阶段编译机制:1)配置阶段生成Makefile;2)编译阶段在.libs目录下产生临时库和可执行文件(不可直接运行);3)安装阶段将产物部署到系统标准路径。重点解析守护进程、命令行工具、动态库的核心路径差异,并针对五大高频问题(如临时库运行崩溃、动态库不匹配、系统覆盖等)给出解决方案。

byte轻骑兵的技术小窝 1万+

数据结构与算法13——二叉树和二叉链表

一、二叉树的定义 —— 每个结点最多有两颗子树,所以二叉树中不存在度大于2的结点。 —— 左子树和右子树是有顺序的,次序不能颠倒。 —— 即使树中的某结点只有一颗子树,也要区分是左子树还是右子树。(就像人的左右手,左手拿碗,右手拿筷子) 二、二叉树的五种基本形态 空二叉树 只有一个根结点 根结点只有左子树 根结点只有右子树 根结点既有左子树又有右子树 对于很二的二叉树,由于要区分左右,所以...

Shallwen_Deng的博客 1716

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

数据结构与算法(13)--二叉树

二叉树的特点 每个节点最多有两颗子树 左右子树有顺序 特殊的树 斜树 满二叉树 完全二叉树 二叉树的顺序存储结构 二叉树的顺序存储结构就是用一组地址连续的存储单元依次自上而下、自左向右存储完全二叉树上的结点元素对于一般的二叉树,我们先转换为完全二叉树进行存储,用空值来代替。 二叉树的链式存储结构 叉树的链式存储结构就是 二叉树每个结点最多有两个孩子,所以设计二叉树的结点结构时,考虑两个指针...

小朱的博客 351

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

【数据结构与算法 13】二叉树(1)

/2. 如果当前结点的左子结点不为空,并且左子结点 就是要删除结点,就将this.left = null;//3.如果当前结点的右子结点不为空,并且右子结点 就是要删除结点,就将this.right= null;如果当前结点的左子结点不为空,并且左子结点 就是要删除结点,就将this.left = null;如果当前结点的右子结点不为空,并且右子结点 就是要删除结点,就将this.right= null;//1.如果删除的节点是叶子节点,则删除该节点。//4.我们就需要向左子树进行递归删除。

shenliba的博客 262

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

13、数据结构与算法 - 二叉树(三)链式存储二叉树

链式存储二叉树 #include <stdio.h> #include "string.h" #include "stdlib.h" #include "math.h" #include "time.h" #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 /* 存储空间初始分配量 */ #define MAXSIZE 100 /* Status是函数的类型,其值是函数结果状态代码,如OK等 */ typede.

shengdaVolleyball的博客 435

数据结构与算法 13 二叉树的遍历 前序遍历 中序遍历 后序遍历

树结构 数据存储结构 数组存储 下标访问,速度快,有序数组可以使用二分查找等算法加快查找速度 检索具体的值,或者按一定顺序插入值会整体移动,效率较低 插入元素:数组需要扩容,每次在底层都需要创建新的数组,要将原来的数据拷贝到新的数据并插入新的数据 链式存储 插入、删除效率较高(不需要拷贝整个数组) 数据查询效率较低,需要从头开始遍历 树存储 能够提高数据存储、读取的效率 比如利用二叉排序树,既可以保证数据的检索速度,也可以保证数据的插入、删除、修改速度 二叉树

shake_shark_pp 243

分治算法,二叉树例题《数据结构入门到精通N13-N15》

目录 分治算法 例一:相同的树 例二:单值二叉树 例三:二叉树的最大深度 作者新建立的社区:非科班转码社区-优快云社区云💖💛💙 期待hxd的支持哈🎉 🎉 🎉 分治算法 思想 思想就是大问题分成相同问题的子问题。 分治就是递归。 分治法在每一层递归上都有三个步骤: step1 分解:将原问题分解为若干个规模较小,相互独立,与原问题形式相同的子问题; step2 解决:若子问题规模较小而容易被解决则直接解,否则递归地解各个子问题 step3 合并:将各...

原来45的博客 1192

数据结构与算法-13.二叉树中第K小的元素

13、二叉搜索树中第K小的元素 题目 13.0、记录子树的节点数 就像名字一样,记录每个节点的子节点有多少个(包括自己),然后就可以判断目标在哪里了 这种方法其实挺鸡肋,完全可以中序遍历生成数组,方便频繁查询。 int kthSmallest0(TreeNode* root, int k) { MyBst myBst(root); return myBst.kthSmallest(k); } class MyBst { private: unordered_map&lt

h1429541165的博客 402

sdut-数据结构与算法pta-数和二叉树(5-13)

给定一棵二叉树的中序遍历和前序遍历,请你先将树做个镜面反转,再输出反转后的层序遍历的序列。所谓镜面反转,是指将所有非叶结点的左右孩子对换。这里假设键值都是互不相等的正整数。输入第一行给出一个正整数N(≤30),是二叉树中结点的个数。第二行给出其中序遍历序列。第三行给出其前序遍历序列。数字间以空格分隔。在一行中输出该树反转后的层序遍历的序列。数字间以1个空格分隔,行首尾不得有多余空格。在一个社区里,每个人都有自己的小圈子,还可能同时属于很多不同的朋友圈。

2302_81657110的博客 1042

研磨数据结构与算法-13删除二叉树节点

节点:/** 二叉树节点*/public class Node {//数据项public long data;//数据项public String sData;//左子节点public Node leftChild;//右子节点public Node rightChild;/** * 构造方法 * @param data */public Node(long data,S...

weixin_34117211的博客 98

数据结构+算法(第13篇):精通二叉树的“独门忍术”——线索二叉树(上)

一个二叉树通过如下的方法“穿起来”:所有原本为空的右(孩子)指针改为指向该节点在中序序列中的后继,所有原本为空的左(孩子)指针改为指向该节点的中序序列的前驱。从上面的线索二叉树的定义就可以看出,为了复用“空节点”指针,需要访问叶子节点,这个已经是遍历的一部分了,所以为了“不走重复路”,最经济的方法是边构造边遍历。接下来的文章将分别介绍“前序遍历”的线索二叉树的各种转换以及遍历算法、“后序遍历”的线索二叉树的各种转换以及遍历算法。为了节省篇幅,本文仅介绍“中序遍历”的线索二叉树的转换以及遍历算法。

smart_an的专栏 801

Day13.一刷数据结构算法(C语言版) 102二叉树的层序遍历;226翻转二叉树;101对称二叉树

这里是c语言版数据结构算法。本期主题是:二叉树的层序遍历;反转二叉树;对称二叉树。

m0_64336804的博客 978

二叉树的中序线索树_数据结构+算法(第13篇):精通二叉树的“独门忍术”——线索二叉树(上)...

点击上方“Java研发军团”,选择“置顶公众号”关键时刻,第一时间送达!阅读本文需要5分钟引言二叉树的叶子节点的孩子都是空节点(Null),如果展开显示,如下图:图 1 原始二叉树二叉树的遍历方法,有“前序遍历”“中序遍历”和“后序遍历”三种。“前序遍历”的规则:先访问当前节点,再访问其左子树,最后访问右子树;访问子树时,按照规则1递归执行。“中序遍历”的规则:先访问左子树,再访问当前节...

weixin_39619170的博客 191

数据结构与算法分析笔记与总结(java实现)--二叉树13:平衡二叉树

数据结构与算法分析笔记与总结(java实现)--二叉树13:平衡二叉树

小菜鸟也想飞的博客 451
上一篇: 【数据结构与算法 12】二分查找、插值查找、斐波那契查找
下一篇: 【计算机网络 22】基础知识总结
哪 吒
哪 吒 2022年度博客之星TOP 1 2022年度博客之星TOP 1 领域专家: 后端开发技术领域 领域专家: 后端开发技术领域
博客等级 码龄9年 59万+粉丝 2933原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哪 吒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值