(鏈)棧的基本操作 C++
阿新 • • 發佈:2019-01-11
#include "iostream" using namespace std; //=====================棧(後進先出)==================== /*棧也是線性表,限定在棧頂進行插入&刪除,時間複雜度均為O(1) 棧:最大儲存大小+資料*/ //=================棧的順序儲存================== const int MAXSIZE = 20; //棧的資料結構: struct Sqstack { int data[20]; int top; Sqstack(int x) :top(x){}; }; /*棧的遍歷:*/ bool StackVisit(const Sqstack *S) { if (S->top == -1) return false; else { for (int i = 0; i <= S->top; i++) cout << S->data[i] << " "; cout << endl; return true; } } /*進棧操作push: 1.棧頂指標 S->top 先自增1,給需要進棧的元素騰出記憶體空間。 2.再賦值。就是給對應的陣列元素賦值:S->data[S->top]=e */ bool myPush(Sqstack *S, int elem) { if (S->top == MAXSIZE - 1) { cout << "棧已滿!" << endl; return false; } else { S->top++; S->data[S->top] = elem; return true; } } /*出棧操作pop: 先把要出棧的元素獲取到,然後再指標自減,把空間釋放出來。 */ bool MyPop(Sqstack *S) { if (S->top == -1) { cout << "空棧!" << endl; return false; } else { S->top--; return true; } } /*獲取順序棧的棧頂元素:*/ bool GetTop(Sqstack *S, int &elem) { if (S->top == -1) { cout << "空棧!" << endl; return false; } else { elem = S->data[S->top]; return true; } } //判斷是否為空棧 bool StackEmpty(Sqstack *S) { if (S->top == -1) return true; else return false; } //置空棧 bool ClearStack(Sqstack *S) { S->top = -1; return true; } //兩棧共享空間 //======================================= //=============棧的鏈式儲存============ /*鏈棧也是一種單鏈表,棧頂指標即為單鏈表頭指標,不需要頭結點,不存在慢棧情況。空棧即top==NULL 鏈棧:top指標+節點(資料)*/ struct StackNode //鏈棧節點 { int val; StackNode *next; StackNode(int x) :val(x), next(NULL){}; }; typedef struct LinkStack //頭結點 { StackNode *top; int count;//記錄棧中元素個數 }; LinkStack* InitLinkStack() { LinkStack *p = new LinkStack; p->count = 0; p->top = NULL; return p; } //鏈棧的進棧操作Push /*1.處理新結點s的後繼,這個後繼就是原本的棧頂結點。 2.將棧頂指標 top 重新指向新結點s就行了。 */ bool myLinkPush(LinkStack *S, int data) { StackNode *p = new StackNode(data); p->next = S->top; S->top = p; S->count++; return true; } //鏈棧的出棧操作Pop: /*1.首先設定一個工作結點 p,並且將棧頂結點賦值給它。 2.然後將棧頂指標下移一位,指向下一結點。程式碼表示為 S->top=S->top->next; 3.最後把結點 p delete掉,count--。*/ bool myLinkPop(LinkStack *S) { if (S->top == NULL) { cout << "空棧!" << endl; return false; } else { StackNode *p = S->top; S->top = S->top->next; delete p; return true; } } //鏈棧的遍歷: bool VisitLinkStack(LinkStack *S) { if (S->top==NULL) { cout << "空棧!" << endl; return false; } else { StackNode *p = S->top; while (p != NULL) { cout << p->val << " "; p = p->next; } cout << endl; return true; } } //判斷鏈棧是否為空 bool LinkStackEmpty(LinkStack *S) { if (S->count == 0) return true; else return false; } //鏈棧置空:方法是設定兩個工作結點,開始迴圈。在釋放p之前,讓q成為p的後繼。 bool ClearLinkStack(LinkStack *S) { if (S->top == NULL) return true; else{ StackNode *p, *q; p = S->top; while (p) { q = p; p = p->next; delete q; } S->count = 0; S->top = NULL; return true; } } //============================================= //遞迴:定義必須至少有一個條件,滿足時遞迴不再進行,即不再引用自身而是返回值退出 //斐波那契的遞迴函式 int Fbi(int i) { if (i < 2) return i == 0 ? 0 : 1; else return Fbi(i - 1) + Fbi(i - 2); } //將中綴表示式轉化為字尾表示式: /*從左到右遍歷中綴表示式的每個數字和符號,若是數字就輸出,即成為字尾表示式的一部分; 若是符號,則判斷其與棧頂符號的優先順序,是右括號或優先順序低於找頂符號(乘除優先加減)則棧頂元素依次出找並輸出, 並將當前符號進棧,一直到最終輸出字尾表示式為止*/ int main() { //==============棧的順序儲存=========== // Sqstack *S = new Sqstack(-1); // int n = 0; // while (cin >> n) // myPush(S, n); // // MyPop(S); // StackVisit(S); //============鏈棧=================== LinkStack *S = InitLinkStack(); int n; while (cin>>n) myLinkPush(S, n); //myLinkPop(S); ClearLinkStack(S); VisitLinkStack(S); system("pause"); return 0; }