C++ 优先级队列(运用绑定器实现大小根堆)

【C++】大根堆(优先队列 priority_queue)与 小根堆 而在这个例子中,我们使用了STL自带的小根堆,因此需要将。是指底层容器的类型,而。是指比较函数对象的类型。 阅读详情

C++ 优先级队列(运用绑定器实现大小根堆)

1. 概要

在C++的优先级队列priority_queue中,其实是使用大小根堆实现的(默认是大根堆)。
在这里,我们使用了函数绑定器functional绑定了一根函数对象来自定义的实现大小根堆。

另外,对于实现一个大小根堆,有两个重要的操作需要考虑:

  • 入堆操作
  • 出堆操作

1. 1 入堆操作

对于入堆,一开始其实把入堆的元素放到数组的最后面。放在最后的这个元素在二叉树里面相当于就在叶子结点中。

但是,对于大根堆来说,每个节点的父节点是需要大于它的孩子节点的。刚插入的、放在叶子节点中的这个节点可能比它的夫节点还要大,因此需要进行上浮操作。

1. 2 出堆操作

对于出堆,首先需要记录数组的第一个元素(相当于堆顶元素)的值,然后用最后一个值覆盖第一个元素。再把最后一个元素给pop掉。

这时新的堆顶元素不一定能符合父节点大于两个孩子节点的条件,因此需要进行下沉操作。

2. 代码实现

#include <iostream>
#include <vector>
#include <functional>
#include <algorithm>
#include <assert.h>
#include <time.h>
using namespace std;

class priorityQueue {
public:
	using Cmp = function<bool(int, int)>;
	priorityQueue(Cmp cmp = greater<int>()) : cmp_(cmp) {}

	void push(int val) {
		if (this->empty()) {
			src_.push_back(val);
		} else {
			src_.push_back(val);
			siftUp();
		}
	}

	void pop() {
		assert(!this->empty());
		
		if (src_.size() == 1) {
			src_.pop_back();
		} else {
			swap(src_[0], src_[this->size() - 1]);
			src_.pop_back();
			siftDown();
		}
	}

	int top() {
		assert(!this->empty());
		return src_.front();
	}

	bool empty() {
		return src_.size() == 0;
	}

	int size() {
		return src_.size();
	}

private:
	// 上浮操作
	void siftUp() {
		int i = src_.size() - 1;
		while (i > 0) {
			int fatherIndex = (i - 1) / 2;
			// 当前结点大于父节点
			if (cmp_(src_[i], src_[fatherIndex])) {
				swap(src_[i], src_[fatherIndex]);
				i = fatherIndex;
			} else {
				break;
			}
		}
	}
	// 下沉操作
	void siftDown() {
		int i = 0;
		while (i < src_.size() / 2) {
			int lson = i * 2 + 1;
			int rson = i * 2 + 2;

			int largestIndex = i;
			if (lson < src_.size() && cmp_(src_[lson], src_[largestIndex])) {
				largestIndex = lson;
			}
			if (rson < src_.size() && cmp_(src_[rson], src_[largestIndex])) {
				largestIndex = rson;
			}

			if (i != largestIndex) {
				swap(src_[i], src_[largestIndex]);
				i = largestIndex;
			} else {
				break;
			}
		}
	}
	
private:
	vector<int> src_;
	Cmp cmp_;
};


int main() {
	priorityQueue maxHeap;
	srand(time(nullptr));
	int size = 20;
	for (int i = 0; i < size; ++i) {
		int val = rand() % 100;
		maxHeap.push(val);
	}

	while (!maxHeap.empty()) {
		int val = maxHeap.top();
		cout << val << " ";
		maxHeap.pop();
	}

	return 0;
}
初学C++【6】:priority_queue的使用 区别于普通队列的先进先出,优先队列是优先级最大的先出队。其实把它理解成一个大根堆来使用就行。(C++中默认为大根堆,而Python中的堆为小根堆) 首先引入一下堆的概念: 大根堆,其根结点的值大于其任一子结点的值。小根堆则反之。 由这个概念我们可知,其左右子结点的大小顺序是没有规定的。因此我们要引入堆排序,使得堆中有序。(因为实际上写代码里我们也是可以让左节点小于或大于右节点的) 让我们来回忆一下堆排序: 以小根堆为例,我们输出堆顶元素(最小值)之后,使得剩余n-1个数重建成一个堆,则可得到这n个 阅读详情

相关推荐

C++简单排序:堆排序

当需要用自定义的数据类型时才需要传入这三个参数,使用基本数据类型时,只需要传入数据类型,默认是大根堆。优先队列具有队列的所有特性,包括基本操作,只是在这基础上添加了内部的一个排序,它本质是一个堆实现的。, 它和queue不同的就在于我们可以自定义其中数据的优先级, 让优先级高的排在队列前面,优先出队。要学堆排序,首先要会优先队列。优先队列我就不打了,你们自己看以下内容。第一个是小根堆,是int类型。这里就定义了两个优先队列。是保证最小值在队列最前面,

小天狼星_布莱克 的博客 2064

C++ 优先队列priority_queue,如何定义大小根堆

1. 代码如下(示例): priority_queue < int >默认构建的是一个大根堆,所以每次从头取数据得到的是一个从大到小的队列排序. priority_queue< int> 实际上等价于 priority_queue<int, vector, less< int>>。 #include <iostream> #include <queue> using namespace std; void common_sort

wenrenfudi的博客 1万+

C++堆(优先队列)priority_queue

堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆(大根堆);每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆(小根堆)。从堆的概念可知,堆是一棵完全二叉树,因此可以使用层序的规则采用顺序的方式来高效存储。完全二叉树,我的理解:任何节点的子节点只有以下三种情况:一,没有孩子。二,有两个孩子。三,只有左孩子。不会出现只有右孩子,没有左孩子的情况。根节点的编号1,根节点的左孩子编号2,根节点的右孩子编号3。2的孩子编号为:4,5。3的孩子编号:6,7。

闻缺陷则喜何志丹 1497

c++priority_queue的默认排序规则及自定义排序详解

也可以定义为小根堆 即priority_queue默认先按q.top().first从大到小,相同的时候按q.top().second从大到小进行排序。priority_queue中如果储存pair类型的话。默认的优先队列中是按照从大到小的方式排序就是大根堆。重载之后他的排序方式就跟咱们定义结构体排序的相反。对于优先队列中开了结构体自定义排序规则的时候。我们重载运算符后的排序。

m0_62909934的博客 4033

GEE进行Theil-Sen Median斜率估计和Mann-Kendall检验

Python实现Theil-Sen Median斜率估计和Mann-Kendall检验// 定义时间范围//NDVI图像集合// 定义每年的开始和结束日期// 加载NDVI数据集,按日期过滤,并计算最大值.max()}));// 计算Sen斜率并剪裁// 可视化Sen斜率Map.addLayer(senSlope.select('slope'), vis, "Sen斜率 ");// MK检验// 创建一个列表,包含年度NDVI图像的list。

qq_44894692的博客 965

仿人型机械臂逆运动学避坑指南:当末端三关节平行时如何处理奇异点

本文深入探讨了6R仿人型机械臂在末三轴平行结构下的逆运动学求解策略,重点分析了运动学逆解中的奇异点问题及其处理方法。通过MATLAB实现展示了D-H参数建模、几何解析法求解流程以及奇异点规避策略,为工业机器人开发提供了实用的数值算法方案和工程优化技巧。

sss66的博客 882

让priority_queue实现小根堆三种方法

作者:自为风月马前卒 个人博客http://attack204.com// 出处:http://zwfymqz.cnblogs.com/ 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 ...

hys__handsome的博客 651

MIC卡的OFED驱动安装

 IB网络和OFED驱动安装 IB InfiniBand是一个统一的互联结构,可以处理存储I/O、网络I/O和进程间通信(IPC)。它可以将磁盘阵列、SANs、LANs、服务器和集群服务器进行互联,也可以连接外部网络(比如WAN、VPN、互联网)。设计InfiniBand的目的主要是用于企业数据中心,大型的或小型的。目标主要是实现高的可靠性、可用性、可扩展性和高的性能。Inf

beglorious的专栏 5106

优先队列(大根堆 小根堆)

priority_queue 容器适配器为了保证每次从队头移除的都是当前优先级最高的元素,每当有新元素进入,它都会根据既定的排序规则找到优先级最高的元素,并将其移动到队列的队头;表示形式:priority_queue 或priority_queue(默认形式)特点 : 堆顶为该优先队列中值最大的 整个队列按照降序排序 (该方式也是优先队列的默认方式)} */ 普通的成员函数是不允许的。注意: < 参数1,vector ,比较方式>

muTr321的博客 931

从AMCL到SLAM Toolbox:在Nav2中实现高精度纯定位的实践指南

本文详细介绍了从AMCL迁移到SLAM Toolbox纯定位模式的实践指南,帮助开发者在Nav2中实现高精度定位。通过对比AMCL与SLAM Toolbox的性能差异,提供环境配置、参数调优、Nav2集成等关键步骤,显著提升机器人在动态环境中的定位精度和重定位效率。

weixin_29292535的博客 148

UE5 Mass交通规则设计指南:从Stop Sign到智能红绿灯的进阶配置

本文详细解析了UE5 Mass框架下的交通规则设计,从基础Stop Sign到智能红绿灯的进阶配置。通过UMassTrafficIntersectionSpawnDataGenerator等核心组件,实现动态响应、自然流畅的交通行为系统,提升虚拟城市的真实感与游戏性。

weixin_30500105的博客 502

优先队列使用

【代码】优先队列使用。

lichengyang的博客 113

AD2428与SigmaStudio:从节点自动配置与EEPROM存储实战

本文详细介绍了AD2428 A2B收发器与SigmaStudio开发环境的集成应用,重点讲解从节点自动配置与EEPROM存储的实战流程。通过硬件连接、属性配置、数据导出及嵌入式系统集成等步骤,实现设备上电自启动,提升汽车音频系统的可靠性与部署效率。

g8f9d0s1a2的博客 650

c++实现小根堆

但是priority_queue 默认为大根堆。头文件是#include。实现小根堆可以重载运算符。

m0_46241225的博客 400

【优化求解】基于matlab粒子群算法PSO确定最佳开关角对称级联多层逆变器【含Matlab源码 13080期】

粒子群算法PSO确定最佳开关角对称级联多层逆变器 完整代码,包运行;可提供运行操作视频!适合小白!

订阅付费专栏Matlab(奶茶价版),可赠送奶茶价版付费专栏指定代码1份; 97

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

C/C++优先队列std::priority_queue实现大顶堆和小顶堆

C/C++优先队列std::priority_queue实现大顶堆和小顶堆

UUUUTaossienUUUU的专栏 3305

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

c++ 优先队列根据结构体属性创建大根堆,小根堆

方式1:重载”<“运算符 值得注意的是,无论是大根对还是小根堆的创建,只需要重载<即可(默认less,less需要<),区别在于return部分。 //大根堆 struct NodeDistCloser { float d; int id; NodeDistCloser(float d, int id) : d(d), id(id) {} bool operator<(const NodeDistCloser&a

weixin_42051691的博客 1147

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

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

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

priority_queue 大/小根堆互换

c++的priority_queue相当于一个大(小)根堆。 priority_queue默认是大根堆,即top元素对队列中最大的元素。那么怎么将其变成小根堆呢?下面以int类型为例子。 priority_queue<int,vector<int>,greater<int> > p; //小根堆, //默认大根堆为less<int> struct...

qq_37724465的博客 768

【数据结构初阶】——第八节.优先级队列(小根堆的模拟实现)

今天我们将进入到有关堆的有关内容的学习,以及有关优先级队列的相关使用,要对堆的概念,性质,操作有很熟悉的认识和了解,接下来就让我们进入到今天的学习当中吧!!!!!!

未央的博客哟 6264

c/c++ | 优先队列 | 大根堆、小根堆

#大根堆 #小根堆

ttxiaoxiaobai的博客 2371

C++数据结构---priority_queue(优先队列,堆)

C++数据结构---priority_queue(优先队列,堆)1. 什么是priority_queue(优先队列,堆)2. 如何使用 1. 什么是priority_queue(优先队列,堆) 普通的队列的性质是先进先出,元素在队列尾加入,在队头弹出。但是在优先队列中,元素被赋予优先级。当访问元素时,具有最高优先级的元素最先删除。优先队列具有最高级的元素先出的行为特征。 优先队列的其他用法在此不作解释,此处只解释其作为堆的用法。 优先队列含有三个参数:Type, Container, Functional

cloud的博客 868

【STL】 C++常用容器介绍系列(二)----(queue、优先队列 priority_que、deque)

大根堆(max heap): 在大根堆中,父节点的值始终大于或等于其子节点的值。因此,大根堆的堆顶元素是整个堆中的最大值。其实就是一个类似完全二叉搜索树的结构,调用函数top()调用最上层节点,然后大根堆最上层节点是整颗树的最大值。小根堆(min heap): 在小根堆中,父节点的值始终小于或等于其子节点的值。因此,小根堆的堆顶元素是整个堆中的最小值。其他与大根堆类似,只不过小根堆上层是整颗树最小值。

2301_77961281的博客 1919

用PriorityQueue优先队列实现大根堆和小根堆

通常用优先队列来实现小根堆和大根堆 //默认为小根堆(看成升序排列) Queue<Integer> minHeap =new PriorityQueue<Integer>() 假如要实现大根堆,可以用lambda 写法来构建比较规则 //默认为小根堆(看成升序排列) Queue<Integer> minHeap =new PriorityQueue<Integer>((a, b) -> { return (b - a); ..

新手第一练:输出梯形 709

数据接口之--------优先队列(小根堆大根堆)

例如:向优先级队列中插入两个自定义的学生类型的数据。

阿也的博客 950

C/C++ 堆和优先队列

如果完全二叉树中的根节点存储的值为当前树中所有值的最大值,在任意一个三元组(父节点,左子树,右子树),父节点的值永远是最大的,就叫。从后向前依次扫描拥有子节点的节点,然后对该节点三元组进行向下调整, 比较高效;依次把每个元素插入到堆中, 比较低效;2.将此操作看做是堆顶元素弹出操作;3.按照头部弹出以后的策略调整堆;1.将堆顶元素与堆尾元素交换;时间复杂度O(n);

yonpiguxiao的博客 657
上一篇: 海量数据TopK问题
下一篇: 有向图、无向图相关数据结构
zsiming
博客等级 码龄7年 43粉丝 74原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值