stack堆棧容器
堆棧是一個線性表,插入和刪除只在表的一端進行。這一端稱為棧頂(Stack Top),另一端則為棧底(Stack Bottom)。堆棧的元素插入稱為入棧,元素的刪除稱為出棧。由於元素的入棧和出棧總在棧頂進行,因此,堆棧是一個后進先出(Last In First Out)表,即 LIFO 表。
C++ STL 的堆棧泛化是直接通過現有的序列容器來實現的,默認使用雙端隊列deque的數據結構,當然,可以采用其他線性結構(vector 或 list等),只要提供堆棧的入棧、出棧、棧頂元素訪問和判斷是否為空的操作即可。由於堆棧的底層使用的是其他容器,因此,堆棧可看做是一種適配器,將一種容器轉換為另一種容器(堆棧容器)。
為了嚴格遵循堆棧的數據后進先出原則,stack 不提供元素的任何迭代器操作,因此,stack 容器也就不會向外部提供可用的前向或反向迭代器類型。
stack堆棧容器的C++標准頭文件為 stack ,必須用宏語句 "#include <stack>" 包含進來,才可對 stack 堆棧的程序進行編譯。
創建 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);
元素入棧
stack堆棧容器的元素入棧函數為 push 函數。由於 C++ STL 的堆棧函數是不預設大小的,因此,入棧函數就不考慮堆棧空間是否為滿,均將元素壓入堆棧,從而函數沒有標明入棧成功與否的返回值。
如下是他的使用原型:
void push(const value_type& x)
元素出棧
stack容器的元素出棧函數為 pop 函數,由於函數並沒有判斷堆棧是否為空,才進行元素的彈出,因此,需要自行判斷堆棧是否為空,才可執行 pop 函數。
void pop()
下面的示例代碼,將堆棧的所有元素全部出棧
// stack<int> s;
while(!s.empty())
{
s.pop();// 出棧
}
取棧頂元素
stack容器的棧頂元素的讀取函數為 pop 函數,將取出最后入棧的元素,如下是它的使用原型
value_type& top()
堆棧非空判斷
隨着堆棧元素不斷出棧,堆棧可能會出現空的情況,因此,一般需要調用 empty 函數判斷是否非空,才作元素出棧和取棧頂元素的操作。
bool empty()
判斷堆棧是否為空,返回 true 表示堆棧已空,false 表示堆棧非空。
1 //----------------------------------------- 讀取堆棧的棧頂元素 2 #include <stack> 3 #include <iostream> 4 using namespace std; 5 int main() 6 { 7 // 創建堆棧對象 8 stack<int> s; 9 // 元素入棧 10 s.push(3); 11 s.push(19); 12 s.push(23); 13 s.push(36); 14 s.push(50); 15 s.push(4); 16 17 // 元素依次出棧 18 while(!s.empty()) 19 { 20 // 打印棧頂元素,打印出:4 50 36 23 19 3 21 cout << s.top() << endl; 22 // 出棧 23 s.pop(); 24 } 25 26 return 0; 27 }
1 /* 堆棧的大小 2 堆棧的元素個數可用 size 函數獲得。每次元素入棧前,先檢查當前堆棧的大小,超過某個界限值,則不允許元素入棧,以此可實現一個具有一定容量限制的堆棧。 3 size_type size() 4 返回當前堆棧的元素個數 5 6 下面的示例程序,將堆棧的大小設置為 100 個 int 元素,而且使用 list 雙向鏈表做堆棧的底層容器,每次壓入元素時均判斷堆棧的大小是否超過100個元素的界限,從而實現具有容量限制的堆棧。 7 */ 8 9 ----------------------------------------- 限制堆棧的大小 10 #include <stack> 11 #include <list> 12 #include <iostream> 13 #define STACK_SIZE 100 // 堆棧最大容量 14 using namespace std; 15 int main() 16 { 17 // 用雙向鏈表作堆棧的底層結構 18 stack<int, list<int> > s; 19 // 堆棧未滿,元素才能入棧 20 if (s.size() < STACK_SIZE) 21 s.push(68); 22 if (s.size() < STACK_SIZE) 23 s.push(1); 24 if (s.size() < STACK_SIZE) 25 s.push(17); 26 // 元素出棧 27 while (!s.empty()) 28 { 29 // 打印 17 1 68 30 cout << s.top() << endl; 31 s.pop(); 32 } 33 34 return 0; 35 }
----------------------- stack 小結
堆棧是一種應用非常廣泛的數據結構。C++ STL 將這種數據結構和它若干受限制操作用泛型類 stack 容器封裝出來,包括堆棧初始化、元素入棧、取棧頂元素、元素出棧、判斷堆棧是否非空和取得當前堆棧大小等,應用起來十分容易。
stack的元素出棧操作是不返回棧頂元素的,需要另外通過取棧頂函數獲得。這種分離實現是考慮到出棧函數若直接返回棧頂元素,將會導致返回值的數據引用安全問題或不必要的低效復制函數的調用。
從 stack 內部實現看,stack 堆棧是不設最大容量的,但可通過 size 函數獲取當前堆棧的大小,以判斷是否允許繼續讓元素入棧,實現具有最大容量限制的堆棧。