Stack容器

一、Stack

(1)定義

棧是一種容器適配器,特別爲後入先出而設計的一種(LIFO ),那種數據被插入,而後再容器末端取出。ios

默認狀況下,若是沒有容器類被指定成爲一個提別的stack 類,標準的容器類模板就是deque 隊列。數據結構

堆棧是一個線性表,插入和刪除只在表的一端進行。這一端稱爲棧頂(Stack Top),另外一端則爲棧底(Stack Bottom)。堆棧的元素插入稱爲入棧,元素的刪除稱爲出棧。因爲元素的入棧和出棧總在棧頂進行,所以,堆棧是一個後進先出(Last In First Out)表(queue是FIFO),即 LIFO 表。函數

(2)底層實現

實現C++  STL,棧有兩個參數:spa

template < class T, class Container = deque<T> > class stack;

參數示意:設計

T: 元素類型
Container: 被用於存儲和訪問元素的的類型

C++ STL 的堆棧泛化是直接經過現有的序列容器來實現的,默認使用雙端隊列deque的數據結構。
code

固然,能夠採用其餘線性結構(vector 或 list等),只要提供堆棧的入棧、出棧、棧頂元素訪問和判斷是否爲空的操做便可。orm

因爲堆棧的底層使用的是其餘容器,所以,堆棧可看作是一種適配器,將一種容器轉換爲另外一種容器(堆棧容器)。對象

爲了嚴格遵循堆棧的數據後進先出原則,stack 不提供元素的任何迭代器操做,所以,stack 容器也就不會向外部提供可用的前向或反向迭代器類型。隊列

拓展:element

Q:爲何stack和queue沒有迭代器?讓這些容器具有迭代器豈不是更方便?

A:一個容器的方法與其自己特性密切聯繫,stack和queue分別是FILO和FIFO的線性表,不容許其餘的進出方式,爲了嚴格遵照這種原則,故不提供迭代器操做。deque是雙向隊列,提供迭代器。

(3)使用

stack堆棧容器的C++標準頭文件爲 stack ,必須用宏語句 "#include <stack>" 包含進來,纔可對 stack 堆棧的程序進行編譯。

二、成員函數

(1)建立 stack 對象

使用堆棧前,先要利用構造函數進行初始化,建立一個堆棧對象,以進行元素的入棧、出棧等操做。
1. stack()
默認構造函數,建立一個空的 stack 對象。
例如,下面一行代碼使用默認的 deque 爲底層容器,建立一個空的堆棧對象 s 。
stack<int>  s;
    
2. stack(const stack&)
複製構造函數,用一個 stack 堆棧建立一個新的堆棧。
例如,下面的代碼利用 s1 ,建立一個以雙向鏈表爲底層容器的空堆棧對象 s2 。
// stack<int, list<int> >   s1;
stack<int, list<int> >   s2(s1);

(2)元素入棧

stack堆棧容器的元素入棧函數爲push函數。

因爲 C++ STL 的堆棧函數是不預設大小的,所以,入棧函數就不考慮堆棧空間是否爲滿,均將元素壓入堆棧,從而函數沒有標明入棧成功與否的返回值。

以下是他的使用原型:

void  push(const value_type& x)
void push ( const T& x );

示例:

// stack::push/pop
#include <iostream>
#include <stack>
using namespace std;

int main ()
{
  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;

  return 0;
}
//output:Popping out elements... 4 3 2 1 0

(3)元素出棧

stack容器的元素出棧函數爲 pop 函數,因爲函數並無判斷堆棧是否爲空,才進行元素的彈出,所以,須要自行判斷堆棧是否爲空,纔可執行 pop 函數。

void pop()

示例:

下面的示例代碼,將堆棧的全部元素所有出棧
// stack<int>  s;
while(!s.empty())
{ 
   s.pop();// 出棧
}
// stack::push/pop
#include <iostream>
#include <stack>
using namespace std;

int main ()
{
  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;

  return 0;
}
//output:Popping out elements... 4 3 2 1 0


(4)取棧頂元素

value_type&  top()
value_type& top ( );
const value_type& top ( ) const;

示例:

// test_stack.cpp : 定義控制檯應用程序的入口點。

#include "stdafx.h"
#include <stack>
#include <vector>
#include <deque>
#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	stack<int> mystack;
	mystack.push(10);
	mystack.push(20);
	mystack.top()-=5;
	cout << "mystack.top() is now " << mystack.top() << endl;

	return 0;
}
//output:

mystack.top() is now 15

(5)堆棧非空判斷

隨着堆棧元素不斷出棧,堆棧可能會出現空的狀況,所以,通常須要調用 empty 函數判斷是否非空,才做元素出棧和取棧頂元素的操做

bool  empty()
//判斷堆棧是否爲空,返回 true 表示堆棧已空,false 表示堆棧非空。

示例:

// stack::empty
#include <iostream>
#include <stack>
using namespace std;

int main ()
{
  stack<int> mystack;
  int sum (0);

  for (int i=1;i<=10;i++) mystack.push(i);

  while (!mystack.empty())
  {
     sum += mystack.top();
     mystack.pop();
  }

  cout << "total: " << sum << endl;
  
  return 0;
}
//output:55

(6)訪問棧中的元素個數

堆棧的元素個數可用 size 函數得到。每次元素入棧前,先檢查當前堆棧的大小,超過某個界限值,則不容許元素入棧,以此可實現一個具備必定容量限制的堆棧。

size_type size ( ) const;
//計算棧對象元素個數

示例:

// stack::size
#include <iostream>
#include <stack>
using namespace std;

int main ()
{
  stack<int> myints;
  cout << "0. size: " << (int) myints.size() << endl;

  for (int i=0; i<5; i++) myints.push(i);
  cout << "1. size: " << (int) myints.size() << endl;

  myints.pop();
  cout << "2. size: " << (int) myints.size() << endl;

  return 0;
}
//output:

0. size: 0
1. size: 5
2. size: 4
相關文章
相關標籤/搜索