赞
踩
栈(stack)
又称堆栈,是一种被限定仅在表尾进行插入和删除操作的线性表。
对于栈来说,能进行插入和删除操作的一段称为栈顶(top)
,另一端称为栈底(bottom)
,且栈的修改操作是按照“后进先出”
(Last In First Out, LIFO)的原则进行的。栈的示意图如下所示:
与vector和list不同的是,stack是一种容器适配器。
函数说明 | 接口说明 |
---|---|
explicit stack (const container_type& ctnr) | 用已有的cntr容器构造 |
empty() | 检测stack是否为空 |
size() | 返回stack中元素的个数 |
top() | 返回栈顶元素的引用 |
push (const value_type& val) | 将元素val压入stack中 |
pop() | 将stack中尾部的元素弹出 |
比较常用的有两种构造,一是构造空栈,二是用已经定义好的其他容器来构造。
stack的构造使用代码演示:
void TestStack1()
{
deque<int> mydeque(3, 100);
vector<int> myvector(2, 200);
stack<int> first; //空栈
stack<int> second(mydeque); //堆栈初始化为双端队列的副本
stack<int, vector<int>> third; //使用vector适配
stack<int, vector<int>> fourth(myvector);
}
栈的使用接口是非常少的,比较常用的是在栈顶push和pop。
stack的修改使用代码演示:
void TestStack2()
{
stack<int> mystack;
for (int i = 0; i < 5; ++i) mystack.push(i);
cout << "Popping out elements...";
while (!mystack.empty())
{
cout << ' ' << mystack.top();
mystack.pop();
}
cout << endl;;
}
运行结果:
栈的模拟实现非常简单,它不需要写迭代器。
template<class T, class Con = deque<T>> class stack { public: void push(const T& x) { _c.push_back(x); } void pop() { _c.pop_back(); } T& top() { return _c.back(); } const T& top() const { return _c.back(); } size_t size() const { return _c.size(); } bool empty() const { return _c.empty(); } private: Con _c; };
有了栈的介绍后,队列就很好理解了。它只允许在队尾插入,队头删除,即“先进先出”
(First In First Out, FIFO)的原则,它的示意图如下所示:
函数说明 | 接口说明 |
---|---|
explicit queue (const container_type& ctnr) | 用已有的cntr容器构造 |
empty() | 检测queue是否为空 |
size() | 返回queue中有效元素的个数 |
front() | 返回队头元素的引用 |
back() | 返回队尾元素的引用 |
push (const value_type& val) | 在队尾将元素val入queue中 |
pop() | 将队头元素出队列 |
void TestQueue1()
{
deque<int> mydeck(3, 100);
list<int> mylist(2, 200);
queue<int> first; // 空队列
queue<int> second(mydeck); // 队列初始化为双端队列的副本
queue<int, list<int>> third; // 以链表作为基础容器的空队列
queue<int, list<int>> fourth(mylist);
}
void TestQueue2() { queue<int> myqueue; int myint; cout << "Please enter some integers (enter 0 to end):\n"; do { cin >> myint; myqueue.push(myint); } while (myint); cout << "myqueue contains: "; while (!myqueue.empty()) { cout << ' ' << myqueue.front(); myqueue.pop(); } cout << endl; }
运行结果:
template<class T, class Con = deque<T>> class queue { public: void push(const T& x) { _c.push_back(x); } void pop() { _c.pop_front(); } T& back() { return _c.back(); } const T& back() const { return _c.back(); } T& front() { return _c.front(); } const T& front() const { return _c.front(); } size_t size() const { return _c.size(); } bool empty() const { return _c.empty(); } private: Con _c; };
上面我们介绍了stack和queue两种容器适配器,他们的底层容器默认都是deque,那么deque到底是什么东西,下面我们简单了解一下。
deque是一种支持在序列的两端进行高效的插入和删除操作的容器,为了实现这一点,它在底层采用了分段存储的方式。下面是deque的底层结构示意图:
+---+ +---+ +---+ +---+ +---+
| | -> | B | -> | C | -> | D | -> | E |
+---+ +---+ +---+ +---+ +---+
map | | | |
V V V V
+-------+ +-------+ +-------+ +-------+
| A0 | | B0 | | C0 | | D0 |
| A1 | | B1 | | C1 | | D1 |
| A2 | | B2 | | C2 | | D2 |
| A3 | | B3 | | C3 | | D3 |
| A4 | | B4 | | C4 | | D4 |
+-------+ +-------+ +-------+ +-------+
在这个示意图中:
map
中的每个指针指向相应的缓冲区。deque
允许在两端高效地进行插入和删除操作。当在前端插入元素时,如果前一个缓冲区已满,会分配一个新的缓冲区并更新map。在后端插入元素时,同样的机制适用。deque
首先计算元素所在的缓冲区,然后访问缓冲区中的具体位置。这使得它能够在常数时间内访问任意元素。deque
根据需要动态分配和释放缓冲区。内存管理由标准库处理,用户无需手动干预。优点:
vector
更多,因为它需要管理多个缓冲区。Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。