DAS7

图的深度优先搜索(DFS)

下图是是一个DFS的例子,它同样会生成一棵树,边也需要一些标记,以防止重复访问同一个结点。
在这里插入图片描述

在这里插入图片描述

这个DFS和BFS目前最直观的区别就是DFS有一个递归。当然正是因为多了这个递归,细节的处理就会很不一样。
在这里插入图片描述
DFS对于结点的处理更加的细致,而且真正用到了clock,如果邻边u已经被访问,邻边u的时间表大于v,那么标记此v到u的边为前向边,否则为CROSS。这个边区分如此细的原因以后会看到。
我们通过例子学习:在这里插入图片描述
选择a作为根,此时a被发现,第一次选择b,然后a->b的边入树。
在这里插入图片描述
然后是b标记为已发现,选择c,因为a已经被发现了,不可能选,在ce里面选,假设选择了c。
在这里插入图片描述
然后c发现f,右边的表格存的是clock。f进而发现H。在这里插入图片描述
然后发现G。在这里插入图片描述
然后发现J,J没有其它邻居了,可以访问J了。然后回溯回G,g的下一个邻居为I,I被发现。在这里插入图片描述
然后顺着I发现了D。D有个和G的边,这个是backward边,因为g还未被访问。
在这里插入图片描述
d->a的也是backward。
在这里插入图片描述
D没科发现的边了,于是D被访问,整体时间加1。接着回退到I。此时整体的时间已经到了12。
在这里插入图片描述
I也没有未被发现的邻居了,于是I被访问。回退到了G,G有一个到F的标记为backward,然后也被访问。
在这里插入图片描述
回退到了H。访问H。
在这里插入图片描述
回退到F,访问F。回退到C,访问C。
在这里插入图片描述
回退到B,发现e,访问e。回退到B。
在这里插入图片描述
B这条到A的边被记为BACKWARD。
在这里插入图片描述
然后访问B。
在这里插入图片描述
最后访问A。左边这列是顶点的dtime。右边为整体的时间ftime。
在这里插入图片描述
最后形成了DFS的支撑树。

有向图的DFS例子

在这里插入图片描述
黑色的框为已访问顶点,双边框为已发现。框左边为dtime,右边为ftime。ftime为顶点被访问的时间,dtime为被发现的时间。大写的字母为当前顶点。
在这里插入图片描述
之所以叫做forward边,是因为是祖先指向后代的。backward就是后代指向祖先的。backward的出现说明有环。
在这里插入图片描述
CROSS说明这个边的两个顶点没有直系关系。在这里插入图片描述
这个最后得到的是从a出发的一个可达域。但是d和e是到不了的。那么仿照BFS,再加一个循环即可。在这里插入图片描述
在这里插入图片描述
最后得到两个遍历树,或者一个遍历森林。
上面的DFS遍历访问的顺序其实比较像二叉树的后序遍历。

括号引理(嵌套引理)

dtime和ftime的用处何在呢?
在这里插入图片描述
这个括号引理很直观,因为子结点的发现时间肯定晚于父结点,而访问时间又肯定早于父结,因为父结点的活跃期包含子节点的,而子结点的活跃期必然包含于父结点,是充要的关系。这是判断两个结点是否有直系关系的O(1)的算法。如果u.dtime<v.dtime && u.ftime> v.ftime,则u为v的祖先。
这种嵌套引理是基于上述的DFS的(类似于后序遍历)。

二叉搜索树(BST)

在这里插入图片描述
前面我们学习了基础的向量和列表,以这两个为基础可以搭建栈,队列等结构。二叉树可以看作是二维的链表。向量的缺点是动态操作费时,而链表的缺点是查找操作费时,那么可不可以将向量和链表的优势结合,劣势互补呢?这就是BST了。BST有着链表的姓,向量的神。BST中主要用的是平衡二叉搜索树(BBST)。在这里插入图片描述

循关键码访问

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
也就是说二叉搜索树的根的左子树的所有结点都小于等于根,而右子树的结点的关键字大于等于根。这个性质递归进行。
这个和任意结点均不小于左孩子和不大于右孩子不等效。
比如
2
1 4
1 3
不是一个二叉搜索树,因为3只是保证了不小于1,而不保证不大于2。

二叉搜索树的中序遍历是不降序的。
在这里插入图片描述
这个必要性很好证明,因为根的左子树的关键字都小于等于根,因为是中序遍历,那么最后得到的序列一定为不降序,数学归纳法即可。
这个充分性其实也差不多,如果一颗二叉树的中序遍历为非降序,那么根结点的左子树必然小于等于根,右边大于等于根。也是递归的证明。
其实中序遍历还有简单的得到方式就是直接投影,不过这个需要结点画的很好。

接口

在这里插入图片描述

查找

在这里插入图片描述

有点二分查找那种感觉了。
在这里插入图片描述
在这里插入图片描述

插入

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
x= new那一行完成了两个操作,一个是让_hot结点的左孩子指针,或者右孩子指针赋值为x,第二个是让x的父结点指针为_hot。这是因为x传递的是引用。
这样查找和插入的复杂度均为O(h)或者O(logn)。
对比向量的插入为O(n),查找为O(1)
列表插入为O(1),查找为O(n)。
这算是进行了折中。但是这种O(logn)是在满二叉树意义下的。普通的BST的高度无法控制。

删除

在这里插入图片描述

单分支

在这里插入图片描述
只需用唯一的孩子代替删除的结点。
在这里插入图片描述
如果左右孩子皆为空,那么返回的succ就是null,下面的操作也是正确的。
因为有(succ)的非空判断。

双分支

这里是取的是右边的中序遍历后继者,这个是succ()函数实现的。
这个是通过进入该结点的右孩子,然后左链遍历的最后一个结点。从投影的角度很好理解。
在这里插入图片描述
这个后继必然只有右孩子后者无孩子。所以就是单分支的情况。
在这里插入图片描述
我感觉其实还有另外一种处理方式,就是和36和27交换。
这样得到的其实也是BST。
在这里插入图片描述
这个代码先交换x和w的关键字,这时候需要处理被删除的结点了,现在它是w了。u为w的父亲指针,如果u不等于x,那么应该把w的右孩子的指针给u的左孩子的指针,就是上面的例子,如果u==x
也就是被删除的结点的后继为右孩子,此时右子树无左链。
那么此时只有右链。
也就是
20
21
22
这种。
BST的删除操作需要用到succ,它的复杂度也是O(h)。于是删除的复杂度为O(h)。

平衡与等价(复杂度分析)

在这里插入图片描述

BST完全可能退化为一条单链,这样它的高度也为n了,这样是很不好的。

随机生成

在这里插入图片描述
比如123右6中全排列,那么可以有6种二叉搜索树。平均高度为O(logn)。
我们来分析一下,如果高度为2,那么肯定是1或者3在序列的起始位置。
概率为2/3。
而深度为1时,是其它的方式。为1/3。这种必然为非极值为根。
期望为5/3。
事实上,这个期望高度为O(logn)。证明:
https://blog.csdn.net/qq_42146775/article/details/102983081
和https://blog.csdn.net/weixin_43913867/article/details/86557400
X k = 1 + m a x ( X k − 1 , X n − k ) X_{k}=1+max(X_{k-1},X_{n-k}) Xk=1+max(Xk1,Xnk)
是一给递推式。

n=1时, E Y n < = c n 3 EY_n<=cn^3 EYn<=cn3显然成立,第二数学归纳法:
在这里插入图片描述
n=2的话也是显然成立,只要C足够大。
那么假设n=k时,小于k的都成立,由积分的放缩得到
E ( Y k ) ≤ 4 n c n 4 4 = c n 3 E(Y_k)\leq\frac{4}{n}\frac{cn^4}{4}=cn^3 E(Yk)n44cn4=cn3
于是这个得证。
然后用琴声不等式 2 E ( X n ) ≤ E ( 2 X n ) = E ( Y n ) ≤ C n 3 2^{E(X_n)}\leq E(2^{X_n})=E(Y_n)\leq Cn^3 2E(Xn)E(2Xn)=E(Yn)Cn3
于是 E ( X n ) ≤ C 1 l o g n E(X_n)\leq C_1logn E(Xn)C1logn
这个过程有点厉害我只能说。

随机组成

和第一种不同的是,我们寻求的是不同拓扑结构的期望。
和随机生成不同的是 2 1 3 和 2 3 1现在算作一种,概率下调,因此,随机组成的期望高度会高一些。
在这里插入图片描述

随即组成就是在堆积木。总数为 c a t a l a n ( n ) = C 2 n n n + 1 catalan(n)=\frac{C_{2n}^n}{n+1} catalan(n)=n+1C2nn
这个道理并不难想,仿照栈混洗的思路,最后的拓扑结构为左子树的结构乘以右子树的结构,和栈混洗的递推式一模一样。
这个期望有点难求。据说是 n \sqrt{n} n 。这种统计是比较可信的,那么复杂度就不是很乐观。

平衡二叉搜索树

BST的高度少为logn,事实上满二叉树的高度最低,但很难满足。完全二叉树的高度也不错,但也很难。单也很难。
那么是否可以在渐进意义下为O(logn)吗?在这里插入图片描述
在这里插入图片描述
但是BBST可能操作一次就不再是BBST,就像BST删除后可能不是BST。那么我们该如何把它拉回到BBST呢?拉回到BBST的意义在于降低树高,以降低后续操作的复杂度。

等价BST

在这里插入图片描述
同一中序遍历结果可能对应不同的BST,称为等价BST,它们的上下可能变,但左右不可变,因为要保证投影的顺序不变。
有两种基本的变换.zig为绕v顺时针旋转,zag为逆时针旋转。
下图为v的左子树绕着v顺时针转,zag为逆时针。
在这里插入图片描述
BBST根据适度平衡方法的不同分为不同的树,比如AVL树,红黑树等。
等价变换组合的准则:
1.局部性,每次等价变换局限在常数规模的局部,计算时间O(1)
2 从失衡的BST到BBST的次数控制在O(logn)次。

AVL-BBST

CBT(完全二叉树)的高度固然很低,但是从BST回到CBT成本也很高,于是我们不用理想平衡,而是用适度平衡的BBST,这种树的高度为O(logn),而且重平衡的过程也只需O(logn)。
在这里插入图片描述
BBST的两要素:

  1. 适度平衡规则
  2. 重平衡的技巧

每个结点的平衡因子为左子树高度减去右子树的高度。

AVL树的适度平衡为对于树中任意结点的平衡因子在-1到1之间。
在这里插入图片描述

CBT也完全符合AVL的定义,然而显然有些AVL不是CBT。
AVL最差的情况应该是形如
1
1 1
1
然后是
1
1 1
1 1 1
1
要证明AVL的高度为O(logn)。
https://blog.csdn.net/sidnee/article/details/105759266
在这里插入图片描述
这个递推式太熟悉了。
最后会得到以 5 + 1 2 \frac{\sqrt{5}+1}{2} 25 +1为底的对数。
在这里插入图片描述
在这里插入图片描述

接口

在这里插入图片描述
重点是插入和删除的重平衡操作。在这里插入图片描述
插入一个结点可能会影响所有祖先结点的高度,因此可能所有祖先结点都会失衡。
删除操作至多导致父结点的失衡。因为如果父结点失衡, 必然是原来短的子树被删除了一个结点,导致平衡因子为-2或者2,这不影响父结点的高度,因为高度由最长的子树决定。
然而,反而是插入操作的重平衡简单,虽然插入操作可能牵一发而动全身,但是有多个结点需要修复,在逐个修复的过程中,也是这样,那么可能就会相互抵消,很少的次数就可以平衡。
删除的修复就很麻烦,因为它只有一个需要修复,但是修复这一个的过程会影响其它的平衡,这样可能没完没了。

插入
单旋

在这里插入图片描述
灰色部分为假设插入的结点,这两个为或的关系。我们看到它会使得g失衡。
g是失衡结点中深度最深的。g的高度变化的子节点为p,p的高度变化的子节点为v。
这个g最深的情况也就是插入结点的祖父辈了。因为父结点不可能因为x的插入而失衡。
这种情况假设插入的是T2,要想解决失衡问题,这时候的想法是g的右子树上移,左子树下移,这等于是绕g做逆时针旋转。但是还得保证投影的关系。

我们此时可以做zag操作,将p的左子树给g,作为其右子树,此时,p没有了左子树,将g作为其左子树,将p设为g的父结点,将局部子树的根转移为p。这样p就平衡了,祖先们也是平衡的。这种操作就是整体将pv拉高,然后g的左边拉低,g拉低的话它不能为局部的根节点,那么它的右子树需要补充,而pv拉高正好要去掉p的左子树。一拍即合。

这是g.p,v构成右链(zag)的情况,修复操作叫做zagzag。而如果g,p,v形成左链,则为zigzig。
那么有zigzag和zagzig吗?有的。

双旋

下面是zigzag的例子,因为pv为左链,是zig,gp为右链是zag。
在这里插入图片描述
在这里插入图片描述
zigzag先进行zig操作,将v的右子树给p作为左子树,然后v作为p的父结点,局部树的根设为v。这里是g的右子树需要拉高,而左子树要拉低,如果按照zag(g)的话,有一个问题就是p此时的左子树是v,不可能给g了,总不能把g变成p的右孩子。所以改变思路,先zig§,把p的左子树拉高,右子树拉低。
v需要拉高,作为p的父结点,那么p为v的右孩子,v的右孩子就给了p作为左孩子。此时T1已经在中间线上了,而T2还在最下面的线上,T3在最下面的线上。也就是g的右子树需要拉高。左子树拉低,于是接下来zag(g)。v和p拉高,g作为v的左孩子,那么v原来的左孩子要给g作为右孩子,完毕。
在这里插入图片描述
局部的根转移到v。这样g的父结点也无需调整了。
zagzig对称。以上覆盖了所有的插入情况。
插入重平衡需要O(1)复杂度。
在这里插入图片描述
不过这个考察是否失衡需要遍历父结点(如果不影响平衡因子的话)。如果影响到了平衡因子,最早在x的祖父结点停止遍历。

删除
单旋

在这里插入图片描述
假如删除的是T3下面的一个结点,T0和T1最下面的灰色至少存在一个。T2下面的可存在可不存在。
失衡结点最多一个,失衡的原因只可能是短的子树更短了。这个失衡点可能为x的父结点。
上图删除了之后,g的左子树需要上提,右子树下放,于是zig一下,pv上提,g为p的右孩子,p的原来的右孩子给g作为左孩子。
这样这个局部子树的失衡解决了,然而如果T3下面的灰色部分无结点,那么这个子树的高度变了,这可能导致祖先结点的失衡,这种失衡是因为修正后代结点的失衡导致的。可能为O(logn)次。

删除双旋

在这里插入图片描述

删除T3一个结点,g又失衡了,按照上面的思想需要左提高,右拉低,但是p已经有了右孩子v了,那么只能先对p左拉低,右提高,也就是zag。v的左子树给p当右子树,p为v的左孩子,这样之后T2拉到线1,T0为线3,T1还在线3,这样g仍然失衡,至少此时T2拉高了,下一步需要拉高T1。此时zig(g)。
结果的话改变了子树的高度,减去了一,这可能导致多米诺骨牌效应。在这里插入图片描述

3+4重构

虽然上面介绍了单旋双旋,但是实际上的重平衡过程并不是如此。就像魔方,你可能知道很多的技巧,但是将其全部拆分再凭借不失为一种快捷的方法。
在这里插入图片描述
我们会找到gpv三个顶点,四个子树(可能有空的)。
在这里插入图片描述
根据BST的不变性,可以将3个顶点,4个子树构成上面的拓扑结构。3+4重构兼具效率性,通用性和鲁棒性(代码简洁易维护和debug)。在这里插入图片描述
这里需要判断的就是gpv的顺序,以便给出3+4中3和4的顺序。
在这里插入图片描述
接着不需要管它单旋还是双旋,只要进行3+4重构就完事了。
我们通过例子理解一下:
在这里插入图片描述
这个插入操作使得g失衡,那么肯定是长的子树更长了导致的。对于插入操作而言,插入的一定在v的子树里面。如果是zagzag,说明p的高度由v决定,而且g的高度由p决定,还是借助需要提高g的右子树的思想,那么p和v要上提了,g作为p的左孩子。这样的道理在于原来gpv是逐渐降低的三级关系,而现在失衡的原因就是有些子树太低了,那么需要均衡为两级的关系。
在这里插入图片描述
zigzag也是一样,gpv这样的三级关系导致了插入失衡,如果改为二级关系,则可以提高长的子树,拉低短的子树,降低平衡因子的绝对值。对于插入而言,v总是在最下面,所以3+4重构总能提高v的地位,让长的子树拉高。
在这里插入图片描述
删除的话,最深的失衡结点(也是唯一一个),为g,g的高度肯定没变,只是短的子树更短了,这个短的子树必然直接挂在g上,不会是p或者v的子树。
同时g不可能在中间的位置,也就是b,那么g必然会被拉下来,其它长的子树被抬高,于是可以重平衡。
在这里插入图片描述
AVL树的各种效率不能令人满意。

高级搜索树

伸展树

AVL树要求平衡因子的绝对值小于等于1,这种条件还是过于苛刻,这种苛刻导致了一系列的问题。
在这里插入图片描述
自适应链表的思想,如果一个元素刚被访问,则根据局部性,将它放到头部,依次类推。我认为这算是一种蒙特卡洛过程,将元素被访问的概率由大到小的顺序排列,当然这只是理想执行无限次的结果。这个调整元素位置的操作可以叫做训练。
实际的调整只能有限次,会出现假如某个元素先被访问4次,那么它现在在头,而另一个元素只被访问一次,它现在在头,但是训练结束了,所以会出现概率小的在概率大的前面的情况。
在这里插入图片描述
仿照这种思想,我们访问完一个结点后,那么就将它放到离根近的位置,这样它的访问深度不会太大。在这里插入图片描述
上升的过程会伸展https://www.bilibili.com/video/BV1db411L71m?p=248
于是叫做伸展。
这种一步一步向上爬的策略。
在这里插入图片描述
这种一步一步上升的策略的分摊复杂度达不到要求,而不是splay树的问题。

双层伸展

在这里插入图片描述
也是gpv三个结点,有四种结构。
在这里插入图片描述

这样v就上升了两层。这个可能用3+4重构实现。这样看起来也没高级多少,但这只是引出点睛之笔的前戏而已。在这里插入图片描述
首先对于zigzig或者zagzag,逐层调整的方式是上面的,而新的调整方式是先进行3+4重构,再将v调整到顶点,这种方法的结果和上面的只是v的右子树不同而已,但是正是这种不同,带来了巨变。

点睛之笔

在这里插入图片描述
这种调整现在看来最大的好处是可以降低树的高度。每次调整大概都能降到一半。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这个分弹性证明见:https://www.cnblogs.com/Mr-Spade/p/9715203.html
在这里插入图片描述

实现

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这个t就是hot,插入成功需要先查找失败,然后把v插入。上面的插入应该是认为v是大于等于hot的(这里我觉得有点问题),完全可能v<=t。这里应该加以判断。
在这里插入图片描述
m可以取v的中序后继succ和前驱。伸展树可以说用了齐夫定律。在这里插入图片描述
这个k个为我们常用的数据。伸展树好比我们把k放入固态硬盘,n保留在机械硬盘。
参考https://www.cnblogs.com/Iking123/p/13502882.html

B树

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
内存绝对容量在加大,然而相比数据量的增长速度还是太弱了。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

结构

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
B树未必是二叉树,所有底层结点的深度是一样的。B树比二叉树更短,更宽。

多路平衡

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
m阶B树的要求为,不超过m-1个关键码,最多为m-1个,内部结点的分支数最少为m/2的ceil个。不过根节点除外,根节点可以为2个。在这里插入图片描述
在这里插入图片描述
m阶B树可以有n个关键码和n+1个分支,既然长度相对固定,那么考虑用向量存储。o是关键码,x是结点。
在这里插入图片描述

实现

结点的实现:
在这里插入图片描述
给出了两种构造函数。第二种先初始化一个关键码,两个分支。在这里插入图片描述

查找

B树的内容很多,内存存不下,所以假设B树在外存中。
在这里插入图片描述
同时假设根节点在内存中。对内存中的关键码进向量进行顺序查找,如果没找到,那么会有一个引用,可以找到一个分支,把分支对应的的结点放进内存,再查找,以此类推,最后会到达外部结点,外部结点可能为空,也可能为其它B树的根节点。在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这里借助了向量的顺序查找接口,因为它可以实现查找失败时返回的是不大于查找值得最大结点,但是分支是r+1,看图很容易理解,其实二分查找得最后一个版本也能实现这样的语义。
I/O操作其实会占到主要的时间,它是最慢的。而结点在内存中的操作会快很多。每个结点最好和页面的大小匹配,一个页面大概就是KB量级,大约100个关键码。这种量级证明顺序查找的效率高于二分查找(这)。
在这里插入图片描述
可想而知,I/O操作的次数应该是O(logn),但是这个常系数为多少呢?可以想象比BST要小很多。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

插入

在这里插入图片描述

插入必然是在最下层的叶字结点插入。因为查找必然失败。
这样的操作可能导致关键码的个数或者分支数超过规定,这种情况叫做上溢,我们需要处理,处理的方式叫做分裂。
在这里插入图片描述
如果父结点也上溢呢?那么继续分裂。
在这里插入图片描述
根节点的处理可以使得中位数作为根节点,这样B树的高度上升了1。
每次插入重平衡做的操作为O(h)。
假4阶B树,分支数为[2,4],关键码为[1,3]个。
不过分裂到根的概率是非常低的。

删除在这里插入图片描述

删除操作比较有意思,删除操作首先应该先找到了结点,不过这个结点不一定为叶结点。处理办法是将它和一个叶子结点互换。和哪个互换呢?和中序遍历的后继互换,这样即使删除了也不符合中序遍历。然后从叶子结点删除。从叶子结点删除时因为比较好入手。
在这里插入图片描述
旋转操作是先看左右兄弟有没有可以借出也不下溢的。如果有,那么可以旋转。如果左边的兄弟可以借,那么还需要进行调整以保证中序遍历,调整方式为将父亲结点插入v的左边,而左边兄弟的最右关键码移到父节点的位置处。
如果没有左右兄弟能借出。那么左右兄弟应该都处于下界。在这里插入图片描述
这样可能导致父结点下溢,那么继续进行。

先看一个例子:5阶B树,分支数范围为[3,5],关键码数为[2,4]。在这里插入图片描述
假设删除249,右兄弟可以借。在这里插入图片描述
结束。.假设又删除619。这时候左兄弟不存在,右兄弟借不了,那就只能合并了。不过我感觉可以先右右兄弟借给右兄弟,然后再借给它,不过这样不稳定,因为假设遍历之后都无法借出,最后还是得合并。合并为稳妥的做法。
在这里插入图片描述

现在父节点下溢了,无左兄弟和右兄弟,只能继续合并。
在这里插入图片描述
现在B树的高度减1,也是B树下降高度的唯一可能。不过这种可能性很小。

为何都要转化为叶节点删除呢?在这里插入图片描述
假设现在删除196,那么麻烦的是它的左右子树的引用无处可去。而如果先将它和266交换,从叶子结点删除就没有这样的问题。
在这里插入图片描述

B树操作可以做到内存和外存的操作时间相当。向量的查找再内存进行,访问结点在磁盘进行,但是磁盘的速度很慢,那么它的操作次数应该少一些,而内存的操作多一些,这样可以达到某种平衡,使得速度最快。
而光的折射亦是如此,光追求的是最小光程或者最短时间,所以它在折射的时候会调整在不同介质中的光程,快的介质多走点,满得少走点。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值