五月好啊,各位,今天那,我们来聊聊C++中的stack和queue,知识点有点多,我打算分成两篇博客来讲,那么,开始发车喽~
1.1 stack的介绍和使用
在C++标准库中,std::stack
是一个容器适配器,它提供了一种后进先出(LIFO)的数据结构,类似于现实生活中的栈。栈的特点是只能在栈顶进行插入和删除操作,即最后进入栈的元素最先被取出。
特点:
- 栈是一种操作受限的数据结构,只允许在栈顶进行插入(push)和删除(pop)操作。
- 栈的插入和删除操作的时间复杂度均为常数时间(O(1))。
- 栈的访问操作通常也是在栈顶进行(top)。
使用示例:
#include <iostream>
#include <stack>
int main() {
std::stack<int> myStack;
// 将元素压入栈
myStack.push(10);
myStack.push(20);
myStack.push(30);
// 访问栈顶元素
std::cout << "栈顶元素: " << myStack.top() << std::endl;
// 从栈中弹出元素
myStack.pop();
std::cout << "弹出元素后的栈顶: " << myStack.top() << std::endl;
// 检查栈是否为空
if (myStack.empty()) {
std::cout << "栈为空。" << std::endl;
} else {
std::cout << "栈不为空。" << std::endl;
}
return 0;
}
代码解释:
- 首先包含了
<stack>
头文件,声明了一个整型的std::stack
对象myStack
。 - 使用
push
方法向栈中压入元素。 - 使用
top
方法访问栈顶元素。 - 使用
pop
方法从栈中弹出元素。 - 使用
empty
方法检查栈是否为空。
1.2 模拟实现stack
尽管标准库已经提供了现成的栈实现,但手动模拟实现栈有助于理解栈的基本原理和内部实现。
手动模拟栈实现
下面我们将手动实现一个简单的栈,包括压栈(push)、出栈(pop)、访问栈顶元素(top)和判断栈是否为空(empty)等基本操作。
#include <iostream>
#include <vector>
template <typename T>
class MyStack {
private:
std::vector<T> stack;
public:
void push(const T& element) {
stack.push_back(element);
}
void pop() {
if (!stack.empty()) {
stack.pop_back();
} else {
std::cout << "栈为空,无法执行出栈操作。" << std::endl;
}
}
T top() {
if (!stack.empty()) {
return stack.back();
} else {
throw std::out_of_range("栈为空,无法访问栈顶元素。");
}
}
bool empty() {
return stack.empty();
}
};
int main() {
MyStack<int> myStack;
myStack.push(10);
myStack.push(20);
myStack.push(30);
std::cout << "栈顶元素: " << myStack.top() << std::endl;
myStack.pop();
std::cout << "出栈后的栈顶元素: " << myStack.top() << std::endl;
return 0;
}
代码解释:
- 定义了一个模板类
MyStack
,内部使用std::vector
作为存储栈元素的容器。 push
方法用于压栈操作,将元素添加到栈顶。pop
方法用于出栈操作,弹出栈顶元素。top
方法返回栈顶元素。empty
方法判断栈是否为空。- 在
main
函数中,展示了如何使用自定义的栈类进行压栈、出栈和访问栈顶元素的操作。
2.1 queue的介绍和使用
在C++标准库中,std::queue
是一个容器适配器,提供了队列(FIFO)数据结构的功能。队列是一种常见的数据结构,遵循先进先出的原则,即最先进入队列的元素最先被取出。
队列的特点
- 队列中的元素按照插入顺序排列,最先插入的元素排在队列的前面,最后插入的元素排在队列的后面。
- 队列支持两种基本操作:入队(enqueue)和出队(dequeue)。
- 入队操作将元素添加到队列的末尾,出队操作从队列的头部移除元素。
- 队列的大小可以动态增长,没有固定的容量限制。
使用队列
在C++中,使用std::queue
可以方便地操作队列数据结构。以下是一个简单的示例代码,展示了如何使用std::queue
进行入队、出队和访问队首元素的操作。
#include <iostream>
#include <queue>
int main() {
std::queue<int> myQueue;
myQueue.push(10);
myQueue.push(20);
myQueue.push(30);
std::cout << "队首元素: " << myQueue.front() << std::endl;
myQueue.pop();
std::cout << "出队后的队首元素: " << myQueue.front() << std::endl;
return 0;
}
代码解释:
- 首先包含了
<queue>
头文件,引入了队列的相关功能。 - 创建了一个
std::queue
对象myQueue
,存储整型数据。 - 使用
push
方法将元素依次入队。 - 使用
front
方法访问队首元素。 - 使用
pop
方法将队首元素出队。
2.2 queue的模拟实现
虽然标准库已经提供了现成的队列实现,但了解如何手动模拟实现队列有助于理解队列的基本原理和内部实现。
手动模拟队列实现
下面我们将手动实现一个简单的队列,包括入队(enqueue)、出队(dequeue)、访问队首元素(front)和判断队列是否为空(empty)等基本操作。
#include <iostream>
#include <queue>
template <typename T>
class MyQueue {
private:
std::queue<T> q;
public:
void enqueue(const T& element) {
q.push(element);
}
void dequeue() {
if (!q.empty()) {
q.pop();
} else {
std::cout << "队列为空,无法出队。" << std::endl;
}
}
T front() {
return q.front();
}
bool empty() {
return q.empty();
}
};
int main() {
MyQueue<int> myQueue;
myQueue.enqueue(10);
myQueue.enqueue(20);
myQueue.enqueue(30);
std::cout << "队首元素: " << myQueue.front() << std::endl;
myQueue.dequeue();
std::cout << "出队后的队首元素: " << myQueue.front() << std::endl;
return 0;
}
代码解释:
- 首先定义了一个模板类
MyQueue
,内部使用了std::queue
作为成员变量。 enqueue
方法用于入队操作,将元素压入队列。dequeue
方法用于出队操作,弹出队首元素。front
方法返回队首元素。empty
方法判断队列是否为空。- 在
main
函数中,展示了如何使用自定义的队列类进行入队、出队和访问队首元素的操作。
好了,感谢大家看到这,如果觉得本篇文章对你有帮助的话,还请点个赞支持一下,有什么问题也可以评论区留言,在下一篇博客中,我将给大家讲解priority_queue和容器适配器的相关知识。那么我们下次再见了,Peace~