手拆STL

vector

vectorvectorvector,动态数组。
先来看一下它的一些基本操作及其拆后残渣。
1.a.push_back(x),将xxx加入动态数组aaa的末尾。
实现:a[++cnt]=x
2.a.size(),查询动态数组aaa中元素的数量。
实现:cnt
3.a.pop_back(),将动态数组aaa末尾的元素删除。
实现:cnt--
4.a.erase(a.begin()+x),删除动态数组aaa中第x+1x+1x+1个元素。
实现:for(int i=x+1;i<=--cnt;i++)a[i]=a[i+1];
5.a.clear(),清空动态数组aaa
实现:cnt=0
总体实现:

int a[N];
int cnt;
void Push_back(int x){
	a[++cnt]=x;
}
int Size(){
	return cnt;
}
void Pop_back(){
	cnt--;
}
void Erase(int x){
	for(int i=x+1;i<=--cnt;i++)a[i]=a[i+1];
}
void Clear(){
	cnt=0;
}

queue

queuequeuequeue,队列。
队列常用的操作:
1.q.push(x),向队列qqq中加入一个元素xxx
实现:q[++tail]=x
2.q.pop(),弹出队列qqq的队首。
实现: head++
3.q.front(),查询队列qqq的队首。
实现:q[head+1]
4.q.back(),查询队列qqq的队尾。
实现:q[tail]
5.q.empty(),判断队列qqq是否为空。
实现:(head==tail)
6.q.size(),查询队列qqq的元素个数
实现:tail-head
手写的思想:两个变量headheadheadtailtailtailheadheadhead存队头前一个元素的下标,tailtailtail存队尾的下标。
总体实现:

int q[N];
int head,tail;
void Push(int x){
	q[++tail]=x;
}
void Pop(){
	head++;
}
int Front(){
	return q[head+1];
}
int Back(){
	return q[tail];
}
bool Empty(){
	return head==tail;
}
int Size(){
	return tail-head;
}

deque

dequedequedeque,双端队列。
一些基本操作:
1.q.push_back(x),在双端队列qqq的队尾加入一个元素xxx
实现:q[++tail]=x
2.q.push_front(x),在双端队列qqq的队头加入一个元素xxx
实现:q[head--]=x
3.q.front(),查询双端队列qqq的队头。
实现:q[head+1]
4.q.back(),查询双端队列qqq的队尾。
实现:q[tail]
5.q.pop_back(),弹出双端队列qqq的队尾。
实现:tail--
6.q.pop_front(),弹出双端队列qqq的队头。
实现:head++
手写的思想:两个变量headheadheadtailtailtail,开双倍的数组空间NNN,将headheadheadtailtailtail都初始化为N2\frac{N}{2}2Nheadheadhead存队头前一个元素的下标,tailtailtail存队尾的下标。
总体实现:

int q[N];
int head=N/2,tail=N/2;
void Push_back(int x){
	q[++tail]=x;
}
void Push_front(int x){
	q[head--]=x;
}
int Front(){
	return q[head+1];
}
int Back(){
	return q[tail];
}
void Pop_back(){
	tail--;
}
void Pop_front(){
	head++;
}

priority_queue

priority_queuepriority\_queuepriority_queue,优先队列。
要拆优先队列,首先得明白优先队列的运行规则。
优先队列实际上是在维护一个二叉堆
二叉堆就是一颗完全二叉树,那么要维护这个二叉堆的什么状态呢?
答案是维护二叉堆的每一个非叶子节点的值都大于等于(或者小于等于)它的两个儿子的值。
那么……开拆。(大根堆)
优先队列的常用操作:
1.q.push(x),将元素xxx加入优先队列qqq
对于一个元素,从左至右依次加入二叉堆,如果父亲节点有了这个儿子之后就违法了,那么它就当父亲了,父亲自然成了儿子。
例如向下面这个二叉堆加入一个元素777
在这里插入图片描述

实现:

void Push(int x){
	q[++cnt]=x;
	int p=cnt;
	while(p>1&&q[p/2]<q[p])swap(q[p/2],q[p]),p/=2;//维护单调性
}

2.q.top(),返回优先队列qqq中的最值
实现:由于时刻都在维护二叉堆的单调性,所以最值就是q[1]
3.q.pop(),弹出优先队列qqq的队头(最值)。
实现:

void Pop(){
	q[1]=q[cnt--];
	q[cnt+1]=0;
	int p=1;
	while(p<=cnt&&q[p]<max(q[p*2],q[p*2+1])){//维护
		//判断左儿子和右儿子哪一个更大
		if(q[p*2]>q[p*2+1])swap(q[p],q[p*2]),p*=2;
		else swap(q[p],q[p*2+1]),p=p*2+1;
	}
}

思想:维护一个二叉堆。
总体实现:

int q[N];
int cnt;
void Push(int x){
	q[++cnt]=x;
	int p=cnt;
	while(p>1&&q[p/2]<q[p])swap(q[p/2],q[p]),p/=2;
}
int Top(){
	return q[1];
}
void Pop(){
	q[1]=q[cnt--];
	q[cnt+1]=0;
	int p=1;
	while(p<=cnt&&q[p]<max(q[p*2],q[p*2+1])){
		if(q[p*2]>q[p*2+1])swap(q[p],q[p*2]),p*=2;
		else swap(q[p],q[p*2+1]),p=p*2+1;
	}
}

stack

stackstackstack,栈。
栈的基本操作:
1.t.push(x),将元素xxx加入栈ttt中。
实现:t[++cnt]=x
2.t.pop(),弹出栈ttt的栈顶。
实现:cnt--
3.t.top(),查询栈ttt的栈顶元素。
实现:t[cnt]
4.t.empty,判断栈ttt是否为空。
实现:(!cnt)
5.t.size(),查询栈ttt的元素个数。
实现:cnt
总体实现:

int t[N];
int cnt;
void Push(int x){
	t[++cnt]=x;
}
void Pop(){
	cnt--;
}
int Top(){
	return t[cnt];
}
bool Empty(){
	return !cnt;
}
int Size(){
	return cnt;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值