棧(順序棧,鏈棧)
阿新 • • 發佈:2018-11-08
順序棧
順序棧是指利用順序儲存結構實現的棧,即利用一組地址連續的儲存單元依次存放自棧底到棧頂的資料元素。
程式碼實現如下:
#include <iostream> #include <stdio.h> #include <malloc.h> using namespace std; typedef int SElemType; typedef int Status; #define INIT_SIZE 100 #define STACKINCREMENT 10 #define Ok 1 #define Error 0 #define True 1 #define False 0 typedef struct { SElemType *base;///棧底指標 SElemType *top;///棧頂指標 int stacksize;///棧可用的最大容量 }SqStack; Status InitStack(SqStack *s)///初始化棧 { s->base = (SElemType *)malloc(INIT_SIZE * sizeof(SElemType));///將順序棧動態分配一個最大容量為INIT_SIZE的陣列空間 if(!s->base)///儲存分配失敗 { puts("儲存空間分配失敗!"); return Error; } s->top = s->base;///top初始為base,空棧 s->stacksize = INIT_SIZE;///stacksize置為棧的最大容量為INIT_SIZE return Ok; } ///if(base==NULL) 棧結構不存在 ///棧非空時,top指向棧頂元素的上一位置 Status Push(SqStack *s, SElemType e)///壓棧(插入元素e為新的棧頂元素) { if(s->top - s->base >= s->stacksize)///棧滿 { s->base = (SElemType *)realloc(s->base, (s->stacksize + STACKINCREMENT) * sizeof(SElemType));///改變棧的記憶體大小 if(!s->base) { puts("儲存空間分配失敗!"); return Error; } s->top = s->base + s->stacksize;///修改棧頂位置 s->stacksize += STACKINCREMENT;///修改棧長度 } *s->top++ = e; return Ok; } Status Pop(SqStack *s, SElemType *e)///彈棧 {///刪除棧頂元素,用e返回其值 if(s->top == s->base) return Error;///棧空時,無法進行操作 --s->top;///棧頂指標減1 *e = *(s->top);///將棧頂元素賦給e return Ok; } Status GetTop(SqStack *s, SElemType &e)///獲得棧頂元素 { if(s->top == s->base) return Error;///棧底指標和棧頂指標相同時,棧為空 e = *(s->top - 1);///棧非空時,top始終指向棧頂元素的上一個位置 return Ok; } Status visit(SElemType c) { printf("%d ",c); return Ok; } Status StackTraverse(SqStack *s,Status(*visit)(SElemType))///遍歷棧 { SElemType *b = s->base;///此處不能直接用base或top移動,即不能改變原棧的結構 SElemType *t = s->top; while(t > b) { visit(*b++); } printf("\n"); return Ok; } Status ClearStack(SqStack *s)///清空棧 { s->top = s->base; return Ok; } Status StackEmpty(SqStack *s)///棧是否為空 { if(s->top == s->base) return True;///棧底指標和棧頂指標相同時,棧為空 else return False; } Status Destroy(SqStack *s)///銷燬棧 { free(s->base); s->base = NULL; s->top = NULL; s->stacksize = 0; return Ok; } int main() { cout<< "1. 進棧" << endl; cout<< "2. 出棧" << endl; cout<< "3. 取棧頂元素" << endl; cout<< "4. 遍歷棧" << endl; cout<< "0. 退出" << endl << endl; SqStack a;///定義一個棧,命名為a SqStack *s = &a;///s為棧的指標 SElemType e; InitStack(s); int n; puts("請輸入要進棧的個數:"); scanf("%d", &n); while(n--) { int m; scanf("%d", &m); Push(s, m); } int choose = -1; while(choose != 0) { cout<< "請選擇:"; cin>> choose; switch(choose) { case 1: { cin>> e; Push(s,e); } break; case 2: { if(StackEmpty(s)) { printf("該棧以空,無法進行該操作\n"); return 0; } Pop(s, &e); printf("出棧的元素是:%d\n", e); printf("元素出棧後事實上並沒有清除,依然存在於記憶體空間,所謂的出棧只是指標移動,出棧的元素是%d\n\n", *s->top); //判斷出棧後元素是否還存在於記憶體中 } break; case 3: { if(StackEmpty(s)) { printf("該棧以空,無法進行該操作\n"); return 0; } GetTop(s, e); printf("棧頂元素為:%d\n\n",e); } break; case 4: { StackTraverse(s, visit);///遍歷該棧 puts(""); } break; } } Destroy(s); return 0; }
程式執行:
鏈棧
鏈棧是指採用鏈式儲存結構實現的棧,通常用單鏈表來表示。
程式碼實現如下:
#include <bits/stdc++.h> using namespace std; #define OK 1 #define ERROR 0 typedef long long ll; typedef unsigned long long ull; typedef int SElemType; typedef int Status; typedef struct StackNode///鏈棧的儲存結構 { SElemType data; struct StackNode *next; }StackNode, *LinkStack; Status InitStack(LinkStack &S)///鏈棧的初始化 {///構建一個空棧S,棧頂指標置空 S = NULL;///鏈棧的初始化操作就是構造一個空棧,因為沒必要設頭結點,所以直接將棧頂指標置空。 return OK; } Status Push(LinkStack &S, SElemType e) {///在棧頂插入元素(將元素插入到首元結點) LinkStack p; p = new StackNode; ///生成新結點 p->data = e; ///將新結點指標插入棧頂 p->next = S; ///將新結點資料域插入棧頂 S = p; ///修改棧頂指標為p return OK; } Status Pop(LinkStack &S, SElemType &e) {///刪除棧頂元素,用e返回其值 LinkStack p; if(S==NULL) return ERROR;///棧空 e = S->data; ///將棧頂元素賦給e p = S; ///用p臨時儲存棧頂元素空間 S = S->next; ///修改棧頂指標 delete p; ///釋放原棧頂元素的空間 return OK; } Status GetTop(LinkStack S, SElemType &e)///取棧頂元素 { if(S==NULL) return ERROR;///棧空 e = S->data; return OK; } Status StackTraverse(LinkStack S) { LinkStack p; if(S==NULL) return ERROR; p = S; while(p) { cout<< p->data << " "; p = p->next; } cout<< endl; return OK; } int main() { cout<< "1. 進棧" << endl; cout<< "2. 出棧" << endl; cout<< "3. 取棧頂元素" << endl; cout<< "4. 遍歷棧" << endl; cout<< "0. 退出" << endl << endl; LinkStack S;///定義一個棧,命名為a SElemType e; InitStack(S); int n, m; puts("請輸入要進棧的個數:"); scanf("%d", &n); while(n--) { int m; scanf("%d", &m); Push(S, m); } int choose = -1; while(choose != 0) { cout<< "請選擇:"; cin>> choose; switch(choose) { case 1: { cin>> e; Push(S,e); } break; case 2: { if(S==NULL) { printf("該棧以空,無法進行該操作\n"); return 0; } Pop(S,e); printf("出棧的元素是:%d\n", e); printf("元素出棧後已經釋放空間,出棧的元素是%d\n\n", e); } break; case 3: { if(S==NULL) { printf("該棧以空,無法進行該操作\n"); return 0; } GetTop(S, e); printf("棧頂元素為:%d\n\n",e); } break; case 4: { StackTraverse(S);///遍歷該棧 puts(""); } break; } } return 0; }