NO.46十六届蓝桥杯备战|栈stack和队列queue|创建|进栈|出栈|栈顶|判空|有效元素个数|入队|出队|队头|队尾|stack|queue(C++)

栈的概念

栈是⼀种只允许在⼀端进⾏数据插⼊和删除操作的线性表。

  • 进⾏数据插⼊或删除的⼀端称为栈顶,另⼀端称为栈底。不含元素的栈称为空栈。
  • 进栈就是往栈中放⼊元素,出栈就是将元素弹出栈顶。
    栈其实是⼀个⽐较简单的数据结构。学习的重点在于⽤栈去解决问题,这也是难点
    如果定义了⼀个栈结构,那么添加和删除元素只能在栈顶进⾏。不能随意位置添加和删除元素,这是栈这个数据结构的特性,也是规定

栈的模拟实现

创建
  1. 本质还是线性表,因此可以创建⼀个⾜够⼤的数组,充当栈结构
  2. 再定义⼀个变量 n ,⽤来记录栈中元素的个数,同时还可以标记栈顶的位置
    ![[Pasted image 20250317193342.png]]
const int N = 1e6 + 10;  

int n;  
int stk[N];
进栈

这⾥依旧舍弃下标为0 的位置,有效元素从1开始记录。
进栈操作,那就把元素放在栈顶位置即可
![[Pasted image 20250317193628.png]]

![[Pasted image 20250317193641.png]]

// 进栈  
void push(int x)  
{  
	stk[++n] = x;  
}

时间复杂度:
显然是O(1)

出栈

不⽤真的删除元素,只⽤将元素个数减1 ,就相当于删除栈顶元素
![[Pasted image 20250317193800.png]]

![[Pasted image 20250317193809.png]]

// 出栈  
void pop()  
{  
	n--;  
}

时间复杂度:
显然是O(1)

栈顶元素

查询栈顶元素。
这⾥要注意,因为栈特殊的规定,不⽀持遍历整个栈中的元素。因此,需要查找栈中元素的时候,只能查找到栈顶元素
![[Pasted image 20250317193800.png]]

// 栈顶元素  
int top()  
{  
	return stk[n];  
}

时间复杂度:
显然是O(1)

判空

判断栈是否为空
![[Pasted image 20250317193628.png]]

// 判空  
bool empty()  
{  
	return n == 0;  
}

时间复杂度:
显然是O(1)

有效元素的个数

![[Pasted image 20250317193800.png]]

// 栈中元素个数  
int size()  
{  
	return n;  
}

时间复杂度:
显然是O(1)

所有测试代码
#include <iostream>  
using namespace std;  
const int N = 1e5 + 10;  
// 创建栈  
int stk[N], n;  
// 进栈 - 本质就是顺序表⾥⾯的尾插  
void push(int x)  
{  
	stk[++n] = x;  
}  
// 出栈 - 顺序表的尾删操作  
void pop()  
{  
	n--;  
}  
// 查询栈顶元素  
int top()  
{  
	return stk[n];  
}
// 判断是否为空  
bool empty()  
{  
	return n == 0;  
}  
// 查询有效元素的个数  
int size()  
{  
	return n;  
}  
int main()  
{  
	for(int i = 1; i <= 10; i++)  
	{  
		push(i);  
	}  
	// 当栈不为空的时候  
	while(size()) // while(!empty())  
	{  
		cout << top() << endl;  
		pop();  
	}  
	return 0;  
}

stack

创建

stack<T> st;
T 可以是任意类型的数据

size/empty
  1. size :返回栈⾥实际元素的个数;
  2. empty :返回栈是否为空。
    时间复杂度:O(1)
push/pop
  1. push :进栈;
  2. pop :出栈。
    时间复杂度:O(1)
top
  1. top :返回栈顶元素,但是不会删除栈顶元素。
    时间复杂度:O(1)
所有测试代码
#include <iostream>  
#include <stack>  
using namespace std;  
int main()  
{  
	stack<int> st;  
	// 先讲 1~10 进栈  
	for(int i = 1; i <= 10; i++)  
	{  
		st.push(i);  
	}  
	while(st.size()) // !st.empty()  
	{  
		cout << st.top() << endl;
		st.pop();  
	}  
	return 0;  
}

队列的概念

队列也是⼀种访问受限的线性表,它只允许在表的⼀端进⾏插⼊操作,在另⼀端进⾏删除操作

  • 允许插⼊的⼀端称为队尾,允许删除的⼀端称为队头。
  • 先进⼊队列的元素会先出队,故队列具有先进先出(First In First Out)的特性

队列的模拟实现

创建
  • ⼀个⾜够⼤的数组充当队列;
  • ⼀个变量 h 标记队头元素的前⼀个位置;
  • ⼀个变量 t 标记队尾元素的位置。
    两个变量 (h, t] 是⼀种左开右闭的形式,这样设定纯属个⼈喜好,因为后续的代码写着⽐较舒服
    当然,也可以 h 标记队头元素的位置。只要能控制住代码不出现 bug ,想怎么实现就怎么实现
    ![[Pasted image 20250317195217.png]]
const int N = 1e6 + 10;  

int h, t; // 队头指针,队尾指针  
int q[N]; // 队列
⼊队
  • 将x这个元素放⼊到队列中。
    注意,我们这⾥依旧从下标为1的位置开始存储有效元素
    ![[Pasted image 20250317195318.png]]

![[Pasted image 20250317195331.png]]

// ⼊队  
void push(int x)  
{  
	q[++t] = x;  
}

时间复杂度:
显然是O(1)

出队
  • 删除队头元素
    ![[Pasted image 20250317195923.png]]

![[Pasted image 20250317195939.png]]

// 出队  
void pop()  
{    
	h++;  
}
队头
  • 返回队列⾥⾯的第⼀个元素。
    这⾥要注意,不是h所指的位置,⽽是h所指的下⼀个位置
    ![[Pasted image 20250317200431.png]]
// 队头元素  
int front()  
{  
	return q[h + 1];  
}

时间复杂度:
显然是O(1)

队尾
  • 返回队列⾥⾯的最后⼀个元素
    ![[Pasted image 20250317200431.png]]
// 队尾元素  
int back()  
{  
	return q[t];  
}

时间复杂度:
显然是O(1)

判空
  • 判断队列是否为空
    ![[Pasted image 20250317200604.png]]
// 队列是否为空  
bool empty()  
{  
	return t == h;  
}

时间复杂度:
显然是O(1)

元素个数
  • 返回队列⾥⾯元素的个数
    ![[Pasted image 20250317200431.png]]
// 队列的⼤⼩  
int size()  
{  
	return t - h;  
}

时间复杂度:
显然是O(1)

所有测试代码
#include <iostream>  
using namespace std;  
const int N = 1e5 + 10;  
// 创建  
int q[N], h, t;  
// ⼊队  
void push(int x)  
{  
	q[++t] = x;  
}  
// 出队  
void pop()  
{  
	h++;  
}  
// 查询队头元素  
int front()  
{  
	return q[h + 1];  
}  
// 查询队尾元素  
int back()  
{  
	return q[t];  
}  
// 判断是否为空  
bool empty()  
{
	return h == t;  
}  
// 有效元素的个数  
int size()  
{  
	return t - h;  
}  
int main()  
{  
	// 测试  
	for(int i = 1; i <= 10; i++)  
	{  
		push(i);  
	}  
	while(size()) // while(!empty())  
	{  
		cout << front() << " " << back() << endl;  
		pop();  
	}  
	return 0;  
}

queue

创建

queue<T> q;
T可以是任意类型的数据

size/empty
  1. size :返回队列⾥实际元素的个数;
  2. empty :返回队列是否为空。
    时间复杂度:O(1)
push/pop
  1. push :⼊队;
  2. pop :出队。
    时间复杂度:O(1)
front/back
  1. front :返回队头元素,但不会删除;
  2. back :返回队尾元素,但不会删除。
    时间复杂度:O(1)
所有测试代码
#include <iostream>  
#include <queue>  
using namespace std;  
typedef pair<int, int> PII;  
int main()  
{  
	// 测试 queue  
	queue<PII> q;  
	for(int i = 1; i <= 10; i++)  
	{  
		q.push({i, i * 10});  
	}  
	while(q.size()) // while(!q.empty())  
	{  
		auto t = q.front();  
		q.pop();
		cout << t.first << " " << t.second << endl;  
	}  
	return 0;  
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值