1. 程式人生 > >棧(LIFO)

棧(LIFO)

棧頂指針 bsp 測試結果 棧的應用 一個數 匹配 一個 nbsp src

1 棧的定義

棧是限定在表尾進行插入和刪除操作的線性表。

2 棧的特點

1)棧是特殊的線性表,線性表也具有前驅後繼性;

2)棧的插入和刪除操作只能在表尾即棧頂進行;

3)後進先出。

3 棧的實現及關鍵點

3.1 順序棧

3.1.1 關鍵點

1)順序棧用數組實現,可以將棧底和索引為0的數組空間對齊以降低插入刪除操作的空間復雜度;

2)保持棧頂指針top和數組索引一致可降低操作復雜度,空棧的條件是-1 == top,滿棧的條件為 棧長-1 == top。

3.1.2 實現

 1 #ifndef SQUENCESTACK_H
 2 #define SQUENCESTACK_H
 3
4 typedef int ElemType; 5 6 class SquenceStack 7 { 8 private: 9 ElemType* m_pData; 10 int m_stackSize; //棧長 11 int m_top; //棧頂指針 12 13 public: 14 SquenceStack(int stackSize); 15 ~SquenceStack(); 16 void ClearStack() { m_top = -1; } //清空棧 17 bool Push(ElemType elem); //
壓棧 18 bool Pop(ElemType* pElem); //彈棧 19 bool VisitStack() const; //順序遍歷棧 20 bool EmptyStack() const { return -1 == m_top; } //判斷是否為空棧 21 }; 22 23 #endif
 1 #include "pch.h"
 2 #include "SquenceStack.h"
 3 #include <iostream>
 4 
 5 SquenceStack::SquenceStack(int stackSize)
6 { 7 m_stackSize = stackSize; 8 m_top = -1; 9 m_pData = new ElemType[stackSize]; 10 } 11 12 SquenceStack::~SquenceStack() 13 { 14 delete[] m_pData; 15 } 16 17 bool SquenceStack::Push(ElemType elem) //壓棧 18 { 19 if (m_stackSize - 1 == m_top) //滿棧 20 return false; 21 22 ++m_top; 23 m_pData[m_top] = elem; 24 25 return true; 26 } 27 28 bool SquenceStack::Pop(ElemType* pElem) //彈棧 29 { 30 if (EmptyStack()) //空棧 31 return false; 32 33 *pElem = m_pData[m_top]; 34 --m_top; 35 36 return true; 37 } 38 39 bool SquenceStack::VisitStack() const //順序遍歷棧 40 { 41 if (EmptyStack()) 42 { 43 std::cout << "The stack is Empty." << std::endl; 44 return false; 45 } 46 47 48 std::cout << "the element of stack: "; 49 for (int i = 0; i <= m_top; ++i) 50 std::cout << m_pData[i] << ; 51 std::cout << std::endl; 52 53 return true; 54 }

測試代碼:

 1 #include "pch.h"
 2 #include "SquenceStack.h"
 3 #include <iostream>
 4 
 5 using namespace std;
 6 
 7 int main()
 8 {
 9     SquenceStack stack(5);
10     stack.VisitStack();
11     stack.Push(0);
12     stack.Push(1);
13     stack.Push(2);
14     stack.Push(3);
15     stack.Push(4);
16     stack.VisitStack();
17     ElemType elem;
18     stack.Pop(&elem);
19     stack.Pop(&elem);
20     stack.VisitStack();
21 
22     return 0;
23 }

測試結果:

技術分享圖片

3.2 兩棧共享空間

3.2.1 適用條件

當兩個棧的空間需求有相反關系時,也就是一個棧增長的同時另一個棧在縮短。(增長收縮的快慢應該相同)

3.2.2 實現與關鍵點

用一個數組來存儲兩個棧。數組有兩個端點,兩個棧有兩個棧底,讓一個棧的棧底為數組的始端,即下標0處;另一個棧的棧底為數組的末端,即下標為數組長度n-1處。

那麽棧1為空時,top1等於-1;棧2為空時,top2等於n;棧滿的條件為top1 + 1 == top2。

3.3 鏈棧

3.3.1 關鍵點

1)單鏈表的頭指針是必須的,而棧的棧頂指針也是必須的,自然的,可以將頭指針和棧頂指針合二為一;

2)鏈棧為空的條件為nullptr == top,由於只在棧頂進行操作,所以在鏈表中為了統一操作的哨兵結點失去了作用。

3.3.2 實現

略。

4 棧的應用場景

4.1 四則運算表達式

規則:通過兩個棧來實現,其中一個保存操作數的棧,另一個保存運算符的棧。當我們從左到右遍歷表達式,當遇到數字,我們就直接壓如操作數棧;當遇到運算符,就與運算符棧的棧頂元素進行比較。如果比運算符棧頂元素的優先級高,就將當前運算符壓入棧;如果比運算符棧頂元素的優先級低或者相同,從運算符棧中取棧頂運算符,從操作數棧的棧頂取2個操作數,然後計算,再把計算完的結果壓入操作數棧,繼續比較;其中左括號直接進棧,遇到右括號時運算到匹配到左括號為止。

棧(LIFO)