队列(Queue)

【数据结构】队列(顺序队列、循环队列、链队列) 文章目录 前言 一、队列的定义 二、队列的顺序存储结构 1.顺序队列的定义 2.循环队列定义 3.循环队列的基本操作 三、队列的链式存储结构 1.链队列的定义 2.链队列的基本操作 前言 队列也是一种线性表,其特殊性在于队列的基本操作是线性表的子集。队列按“先进先出”的规则进行操作,故称其为操作受限的线性表。 一、队列的定义 队列(queue)是只允许在一端进行插入操作,在另一端进行删除操作的线性表,简称“队”。 队列是一种先进先出(First In First Out)的 阅读详情
AI摘要

本文详细介绍了数据结构中的队列,包括其先进先出的特性,队列的顺序和链式实现,以及如何进行入队、出队、判空等操作。同时,讨论了顺序队列的假溢出问题,并引入了循环队列的概念和实现,以解决空间利用率的问题。此外,还展示了循环队列的初始化、入队、出队和遍历操作的代码实现。

一、队列的概念

队列是一个先进先出的数据结构。
联想一下链表,在单链表中,只能对表尾进行插入,对表头进行结点的删除,这样强限制性的链表,就是所说的队列。也就是说,队列是限定在表的一端进行插入,表的另一端进行删除的数据结构。

如图去买票排队,每一列队伍都有一个队尾和队首,先来的先买票,后来的后买,买好的就从队首出去,新来买票的就需要从队尾继续排队。

通常,称进数据的一端为队尾,出数据的一端为队首,数据元素进队列的过程称为入队,出队列的过程称为出队。

队列是一个线性的数据结构,并且这个数据结构只允许在一端进行插入,另一端进行删除,禁止直接访问除这两端以外的一切数据,且队列是一个先进先出的数据结构。

如上图,队列就像一个两端相通的水管,只允许一端插入,另一端取出,取出的球就不在水管里面了,而先放入管中的球就会先从管中拿出。

队列存储结构的实现有以下两种方式:
①顺序队列:在顺序表的基础上实现的队列结构。
②链队列:在链表的基础上实现的队列结构。

两者的区别仅是顺序表和链表的区别,即在实际的物理空间中,数据集中存储的队列是顺序队列,分散存储的队列是链队列。

二、队列的结点设计与初始化

队列只有链式的设计方法,其本身分为多种队列,如顺序队列和循环队列,还有衍生的优先队列等等,以顺序队列的设计为例。

首先是队列的结点设计,可以设计出两个结构体,一个结构体 Node 表示结点,其中包含有 data 域和 next 指针,如图:

其中 data 表示数据,其可以是简单的类型,也可以是复杂的结构体。next 指针表示,下一个的指针,其指向下一个结点,通过 next 指针将各个结点链接。

然后再添加一个结构体,其包括了两个分别永远指向队列的队尾和队首的指针,看到这里是不是觉得和栈很像?

主要的操作只对这两个指针进行操作,如图所示:

其结构体设计的代码可以表示为:

//结点定义
typedef struct node{ 
  int data;
  struct node *next;
}
  node;
//队列定义,队首指针和队尾指针
typedef struct queue{ 
  node *front;
//头指针 
  node *rear; 
//尾指针
}
  queue;

对于初始化需要初始化两个类型,一个是初始化结点,一个是初始化队列。代码中的描述,初始化队列有些不同,当初始化队列的时候,需要将头尾两个结点指向的内容统统置为空,表示是一个空队列,两个创建的函数代码可以表示为:

//初始化结点
node *init_node{
  node *n=(node*)malloc(sizeof(node)); 
  if(n==){
//建立失败,退出 
    exit(0);
  }
  return n;
}
//初始化队列
queue *init_queue { 
  queue *q=(queue*)malloc(sizeof(queue)); 
  if(q==) { 
//建立失败,退出 
    exit(0);
  } 
//头尾结点均赋值 
  q->front=;
  q->rear=; 
  return q;
}

三、判断队列是否为空

这是一个既简单也很要紧的操作,判断队列是否为空直接就是判断队列头指针是否是空值即可。其代码可以表示为:

//队列判空
int empty(queue *q) { 
  if(q->front==) { 
    return 1; 
//1--表示真,说明队列非空 
  }else{
    return 0;
//0--表示假,说明队列为空 
  }
}

或者直接利用返回值进行更简单的判断也可以,代码如下:

int empty (queue *q) { 
  return q->front==;
}

四、入队操作

入队操作变化图:

进行入队(push)操作的时候,同样的,首先需要判断队列是否为空,如果队列为空的话,需要将头指针和尾指针一同指向第一个结点,代码如下:

front=n;
rear=n;

如图:

如果队列不为空的时候,这时只需要将尾结点向后移动,通过不断移动 next指针指向新的结点构成队列即可。如图:

其代码可以表示为:

//入队操作
void push(queue *q,int data) { 
  node *n =init_node;
  n->data=data;
  n->next=; 
//采用尾插入法 //if(q->rear==){ 
//使用此方法也可以 
  if(empty(q)) { 
    q->front=n; q->rear=n; 
  }else{ 
    q->rear->next=n; 
//n成为当前尾结点的下一结点 
    q->rear=n; 
//让尾指针指向n 
  }
}

五、出队操作

出队操作变化图:

出队(pop)操作,是指在队列不为空的情况下进行的一个判断,当然在此也一定要进行队列判空的操。

如图,如果队列只有一个元素了,也就是说头尾指针均指向了同一个结点,那么直接将头尾两指针置空,并释放这一个结点即可,如图:

当队列含有以上个元素时,需要将队列的头指针指向头指针当前指向的下一个元素,并释放掉当前元素即可,如图:

其代码可以表示为:

//出队操作
void pop(queue *q) { 
  node *n=q->front;
  if(empty(q)){
    return ; 
//此时队列为空,直接返回函数结束 
  } 
  if(q->front==q->rear){ 
    q->front=; 
//只有一个元素时直接将两端指向置为空即可 
    q->rear=; free(n); 
//记得归还内存空间 
  }else{ 
    q->front=q->front->next; free(n);
  }
}

六、打印队列元素(遍历)

打印队列的全部元素可以帮助调试,看到队列中具体的数据,在队列不为空的情况下,通过结点的 **next **指向依次遍历并输出元素既可。其代码可以表示为:

//打印队列元素
void print_queue(queue *q){ 
node *n = init_node; 
n=q->front; 
if(empty(q)){ return ; 
//此时队列为空,直接返回函数结束 } 
while (n!=){ 
printf("%d\t",n->data); 
n=n->next; 
} 
printf("\n");
 //记得换行}

遍历操作还有很多别的表示方法,比如说进行计算队列中含有多少元素,代码如下:

int calac(queue *q){ 
node *n = init_node; 
n=q->front; 
int cnt=0; 
//计数器设计 
if(empty(q)){ 
return 0; 
//此时队列为空,直接返回函数结束 
} 
while (n!=) {
 n=n->next; cnt++; 
} 
return cnt;
}

七、顺序队列的假溢出

什么是假溢出?这里需要考虑到顺序队列有什么缺点,对于顺序队列而言,其存在已经足够解决大多时候的设计问题了,但是其依旧存在一些缺陷和不足。

从上面的解析中看到,入队和出队操作均是直接在其后面进行结点的链接和删除,这种操作会造成其使用空间不断向出队的那一边偏移,产生假溢出。

来打一个比方,先看图:

上图所示,有一个顺序队列,这个队列的大小为5,其已经包含了四个元素 data1 , data2 , data3 , data4。

接着,对这个队列进行出队操作,出队2个元素,队列就变成了这个样子,如图:

从图上看到似乎没有什么问题,但是当接着再进行入队操作,比如入队2个元素,分别是 data5和** data6**。

此时已经发现问题了,尾指针移动到可以进行队列操作的范围之外去了,有没有发现?

这种现象称呼作为队列用的存储区还没有满,但队列却发生了溢出,把这种现象称为假溢出。如图:

那么有什么办法解决这个问题呢?这就要涉及到循环队列的性质了!

八、循环队列的概念

可能这个时候会产生一个疑问,学习的队列不是使用链表实现的动态队列么?没有空间的时候会开辟空间,这难道还会产生假溢出么?的确,当进行动态创建队列的时候,也只不过是向后继续不断的申请内存空间;即使前面出队操作释放掉了前面的空间,但是指针依旧会向后进行移动,直到达到系统预留给程序的内存上界被强行终止;这对于极为频繁的队列操作和程序而言是致命的,这时候,就需要对我们的队列进行优化,使用更为优秀的结构——循环队列。

循环队列就是将队列存储空间的最后一个位置转而绕到第一个位置,形成逻辑上的环状空间,以此来供队列循环使用,如图:

循环队列就是给定队列的大小范围,在原有队列的基础上,只要队列的后方满了,就从这个队列的前面开始进行插入,以达到重复利用空间的效果;由于循环队列的设计思维更像一个环,因此常使用一个环图来表示,但我们需要注意,实际上循环队列不是一个真正的环,它依旧是单线性的。

九、循环队列的结构设计

由于循环对列给定了数据范围的大小,所以不需要使用链式的动态创建方法了。因为如果使用链式存储,会无法确定何时再回到队头进行插入操作,所以采用模拟的方法,如图:

其中,data 表示一个数据域,int 为类型,其可以修改为任意自定义的类型,比如说简单的 char,float 类型等等,也可以是复杂的结构体类型。

  • maxsize表示循环队列的最大容纳量,其表示队列的全部可操作空间。

  • rear代表尾指针,入队时移动。

  • front代表头指针,出队时移动。

其代码可以表示为:

#define maxsize 10 
//表示循环队列的最大容量
//循环队列的结构设计
typedef struct cir_queue{ 
int data[maxsize]; 
int rear; 
int front;
}
cir_queue;

十、循环队列的初始化

循环队列的初始化核心就在于申请空间,并且将 front 指针和 rear 指针内容赋值为0,即指向第0个元素即可,这里要注意第 0个元素内容为空,如图:

其代码可以表示为:

//初始化
cir_queue *init{ 
cir_queue *q = (cir_queue*)malloc(sizeof(cir_queue)); 
if(q==){ exit(0); 
//申请内存失败,退出程序 
} 
q->front=0; 
q->rear=0; 
return q;
}

十一、循环队列的入队操作

入队操作同顺序队列的方法,直接将 rear 向后移动即可。但是要注意判断,如果 rea r达到了队列的空间上线,将要从头继续开始移动。这里推荐使用余数法,即无论如何求余都是在这片空间内进行操作,防止一次错误执行就直接整体崩溃,而且也相对而言更为简洁,不推荐使用 if 语句,这样显得比较累赘。

注意进行加一移动位置操作的时候,不能直接 **q->rear++ **这样的操作,这样计算机判断优先级会产生让自己意想不到的后果。此外这里还需要进行一次是否队列已满的判断,当我们 rear 指针的下一个位置就是front的位置的时候,即改循环队列已满。如图:

其代码可以表示为:

//入队操作
pushvoid push(cir_queue *q,int data){ 
if((q->rear+1)%maxsize==q->front){ 
printf("溢出,无法入队\n"); 
return; 
}else{ 
q->rear=(q->rear+1)%maxsize;
 q->data[q->rear]=data; 
}
}

十二、循环队列的出队操作

如果顺序队列的出队操作,直接将 front 进行后移一位即可。

这里上面很多地方都提过了,有一个需要留意的地方,即队列是否为空,当队列为空的时候是无法进行出队操作的。

其代码可以表示为:

//出队操作
popvoid pop(cir_queue *q){ 
if(q->rear==q->front){ 
printf("队列为空,无法出队\n"); 
return; 
}else{ 
q->data[q->front]=0; 
q->front=(q->front+1)%maxsize;
 }
}

十三、循环队列的遍历操作

遍历操作需要借助一个临时变量储存位置 front 的位置信息,利用i逐步向后移动,直到 i 到达了 rear 的位置即可宣告遍历的结束。

//遍历队列
void print(cir_queue *q){ 
int i=q->front; 
while(i!=q->rear){ i=(i+1)%maxsize; 
printf("%d\t",q->data[i]);  
} 
printf("\n"); 
//记得换行
}
队列——queue Hello,这是你们的苦力怕。今天我去医院做核酸检测,排了老长的队,wait了半个多小时才做完,真是把我整无语死了,但是我在wait的过程中突然想到了一个问题:啥数据结构跟排队很像?对了,就是大名鼎鼎的队列。...... 阅读详情

相关推荐

C++ 队列 queue 用法简述

本篇文章主要简介队列的原理以及实现,便于学习和查阅。 队列的原理 queue 队列容器是一个先进先出(First In First Out,FIFO)的线性存储表,元素的插入只能在队尾,元素的删除只能在队首,如图是一个队列容器数据结构示意图。 队列的实现 1.头文件 #include 用队列时记得要写上这个头文件。 2.定义 queue name; Data_ty

算法笨蛋 5731

数据结构之队列

不会吧不会吧,不会有人不会队列吧......

weixin_74772510的博客 4368

Thinkphp8 Redis队列与消息队列Queue

Thinkphp8 Redis队列与消息队列Queue

wzc1220yyds的博客 1353

【数据结构入门】队列(Queue)详解(定义、销毁、入队、出队等)| 图解数据结构,超详细哦~

文章目录(1)前言1)队列的概念2)队列的结构(2)队列的实现(链式结构)1)队列的定义2)队列的初始化3)队列的销毁4)入队(尾插)5)出队(头删)6)获取队列元素个数7)获取队头元素8)获取队尾元素9)检查队列是否为空 数据结构系列文章: 【数据结构入门】顺序表(SeqList)详解(初始化、增、删、查、改) 【数据结构入门】无头单向非循环链表(SList)详解(定义、增、删、查、改) | 图解链表,超生动详细哦~ 【数据结构入门】带头双向循环链表(List)详解(定义、增、删、查、改) | 配有大量图

codewinter的博客 2万+

python3 - Queue队列

Python的Queue模块提供一种适用于多线程编程的FIFO实现。它可用于在生产者(producer)和消费者(consumer)之间线程安全(thread-safe)地传递消息或其它数据,因此多个线程可以共用同一个Queue实例。Queue的大小(元素的个数)可用来限制内存的使用。+ Basic FIFO Queue Queue类实现了一个基本的先进先出(FIFO)容器,使用put()将元...

GeekLee的博客 3万+

利用ArcMap实现遥感图像语义分割标注的完整流程解析

本文详细解析了利用ArcMap进行遥感图像语义分割标注的完整工作流。从工程创建、数据导入、SHP文件创建,到实战勾画地物、要素转栅格,再到最终的裁剪对齐,提供了每一步的关键操作与避坑指南。该方法特别适合处理大尺寸、带地理坐标的遥感影像,能高效产出精准对齐的图像-标签对,为后续深度学习模型训练奠定可靠的数据基础。

gpu4optimizer的博客 1208

<C++>:队列queue(STL queue)用法

前言 队列Queue 只能访问 queue 容器适配器的第一个和最后一个元素。只能在容器的末尾添加新元素,只能从头部移除元素。也就是传说中的“出队入队”操作,先进先出(FIFO) 下图展示了一个 queue 容器及其一些基本操作: queue 的生成方式和 stack(栈) 相同,下面展示如何创建一个保存字符串对象的 queue: std::queue<std::string> words; 也可以使用拷贝构造函数: std::queue<std::string>

W_Oilpicture的博客 1万+

别再瞎猜了!Fluent瞬态计算时间步长到底设多少?一个公式+实战案例搞定

本文详细解析了Fluent瞬态计算中时间步长的设置方法,通过黄金公式和实战案例,帮助工程师准确确定时间步长,避免计算发散和资源浪费。文章还介绍了动态调整策略和典型工程场景的参数优化,提升仿真效率和精度。

weixin_42638178的博客 424

java queue 队列_队列(Queue)

在“队列”(Queue)这种数据结构中,数据项是先进先出(FIFO:first in first out)。队列的容量可以有限,也可以是无限的。一、基于数组的Queue实现一般情况下,对于Queue而言,最核心的操作是:插入队列(enqueue)、移出队列(dequeue)。因为在队列中,插入操作是插入到队列的最后,而移出操作是移出队列的头部元素。因此我们通常会使用两个变量front(队头指针)和...

weixin_32591455的博客 880

Geant4学习——入门(基本概念、Geant4工具包的结构、强制类、可选类)

Geant4是由欧洲核子研究组织基于C++面向对象技术开发的蒙特卡罗应用软件包,用于模拟粒子在物质中输运的物理过程。由于具有良好的通用性和扩展能力,Geant4在涉及微观粒子与物质相互作用的诸多领域获得了广泛应用。 第一部分 Geant4的基本概念 HEP中的模拟是“虚拟现实”。仿真既可用于在研发阶段帮助设计探测器,又可用于物理研究中了解探测器的响应。为了创建这样的虚拟现实,我们需要对粒子间的相互作用,几何形状和材料进行建模,以便将基本粒子传播到检测器中。我们还需要描述检测器生成原始数据的灵敏度。 Gea

M_M-铭的博客 2万+

从零组装电赛送药小车:OpenMV视觉核心+STM32控制,我的软硬件联调全记录

本文详细记录了从零构建电赛智能送药小车的全过程,重点解析了OpenMV视觉识别与STM32控制的深度协同方案。通过硬件选型对比、通信协议设计、PID调参等实战经验,解决了巡线精度、十字路口识别等核心问题,最终实现稳定可靠的送药小车系统,助力电子设计竞赛取得优异成绩。

weixin_42641741的博客 447

C++队列queue的用法

C++队列queue模板类的定义在头文件中,queue 模板类需要两个模板参数,一个是元素类型,一个容器类型,元素类型是必要的,容 器类型是可选的,默认为deque 类型。 C++队列Queue是一种容器适配器,它给予程序员一种先进先出(FIFO)的数据结构。 C++队列Queue类成员函数如下: back() 返回最后一个元素 empty() 如果队列空则返回真 front() 返回第...

邹氏情歌cium的博客 5405

pytorchDataLoader中调整数据长度不一致问题(lstm等)

数据长度不一致 用pytorch做rnn的时候,如果输入数据不一样长,可以用两种方式解决。 一种是自定义collate方法, #自定义collate_fn dataloader.DataLoader(dataset,4,True,collate_fn=my_collate) 然后里面写数据和标签载入方式即可 def my_collate(batch): data = [item[0] for item in batch] target = [item[1] for item in batc

weixin_48174100的博客 7770

C++ queue(队列)

C++ queue(队列)原理和方法总结

qq_44955826的博客 1368

网络系统管理专栏-配套练习+知识点详解

网络系统管理专栏-配套练习+知识点详解

bfq05234214的博客 681

一个 ABAP 工具,能打印系统里某个用户对 BSP 应用的浏览历史记录

只要一个用户在 SAP ABAP 系统里浏览过 BSP 页面,会留下浏览历史记录。本工具会解析出这些记录,打印出该用户浏览的历史事件,和浏览过的页面名称。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 545

队列queue

队列Queue 3种Queue类型 FIFO:class Queue.Queue(maxsize=0) FIFO 即 First in First Out,Queue 提供了一个基本的 FIFO 容器,使用方法很简单,maxsize 是个整数,指明了队列中能存放的数据个数的上限。一旦达到上限,插入会导致阻塞,直到队列中的数据被消费掉。如果maxsize小于或者等于0,队列大小没有限制。 L...

lvchen_1113的博客 268

innovus:如何在init design之后新增参考库(lib/lef)

如题,在PR过程中经常会遇到这种问题,时序无法收敛,需要新增一套lvt或者hpc的库,怎么办?

m0_61544122的博客 5000

STL初步——队列Queue

『写在前面的一些基础语法』 1.定义 和 使用 queue&lt;int&gt; a; 2.Queue的一些特性  操作原则:先进先出(First In First Out),简称为FIFO表。 ¨只允许在一端进行插入,而在另一端进行删除的运算受限的线性表。 ¨允许删除的一端称为队头(Front)。 ¨允许插入的一端称为队尾(Rear)。 ¨当队列中没有元素时称为空队列。 ¨ ...

Miserable_ccf的博客 4528

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

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

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

C++ 队列queue的用法

 转自:http://www.169it.com/article/2718050585107790752.html  C++队列queue模板类的定义在&lt;queue&gt;头文件中,queue 模板类需要两个模板参数,一个是元素类型,一个容器类型,元素类型是必要的,容器类型是可选的,默认为deque 类型。     C++队列Queue是一种容器适配器,它给予程序员一种先进先出(F...

cindywry的博客 10万+

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

python队列queue不堵塞_python队列Queue

QueueQueue是python标准库中的线程安全的队列(FIFO)实现,提供了一个适用于多线程编程的先进先出的数据结构,即队列,用来在生产者和消费者线程之间的信息传递基本FIFO队列class Queue.Queue(maxsize=0)FIFO即First in First Out,先进先出。Queue提供了一个基本的FIFO容器,使用方法很简单,maxsize是个整数,指明了队列中能存放的...

weixin_39518840的博客 1067

visio安装包

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

队列queue函数_使用queue :: size()函数检查队列是否为空

队列queue函数There is a function queue::empty() that can be used to check whether queue is empty or not – it returns 1 (true) if queue is empty else returns 0 (false). 有一个函数queue :: empty()可用于检查队列是否为空–如...

cumtb2009的博客 4315

Python queue队列

队列是一种先进先出的数据结构,与之对应的是堆栈这种后进先出的结构。但是在python中,它内置了一个queue模块,它不但提供普通的队列,还提供一些特殊的队列。具体如下: queue.Queue :先进先出队列 queue.LifoQueue :后进先出队列 queue.PriorityQueue :优先级队列 queue.deque :双向队列 Queue:先进先出队列 这是最常用也是最普遍的队列,先看一个例子。 import queue q = queue.Queue(maxsize) q.put(

weixin_44777680的博客 449

034创建队列Queue

目录 Queue 类 构造函数 属性 方法 创建队列 Queue 类 https://docs.microsoft.com/zh-cn/dotnet/api/system.collections.queue?view=netcore-3.1 表示对象的先进先出集合。 构造函数 Queue() 初始化Queue类的新实例,该实例为空,具有默认初始容量并使用默认增长因子。 Queue(ICollection) 初始化Queue类的新实例,该实例...

复行数十步 504

C# 队列(Queue)

队列(Queue)代表了一个先进先出的对象集合。当您需要对各项进行先进先出的访问时,则使用队列。当您在列表中添加一项,称为入队,当您从列表中移除一项时,称为出队。 Queue 类的方法和属性 下表列出了 Queue 类的一些常用的 属性: 属性 描述 Count 获取 Queue 中包含的元素个数。 下表列出了 Queue 类的一些常用的 方法: 序号 方法名 &...

xulong5000的专栏 1068

队列Queue

定义 队列Queue也是Collection的一个子接口,它也是常用的数据结构。 可以将队列看成特殊的线性表,队列限制对线性表的访问方式: 只能从一端添加(offer)元素,从另一端取出(poll)元素。 队列遵循先进先出(FIFO )的原则,实现类LinkedList也实现了该接口,选择此类实现Queue的原因在于Queue经常要进行添加和删除操作,而LinkedList在这方面效率比较高。 应...

WQY992的博客 491
上一篇: Java 链表
下一篇: Future 模式
JFS_Study
博客等级 码龄6年 363粉丝 359原创
评论 9
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

打赏作者

JFS_Study

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

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

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

打赏作者

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

抵扣说明:

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

余额充值