一、棧相關(guān)定義(棧的順序存儲結(jié)構(gòu)(最常用))
官方定義:棧是一個后進先出的線性表,它要求只在表尾進行刪除插入操作(特殊線性表,只能在表尾操作)
棧頂:表尾棧底:表頭棧的插入操作:叫做進棧(入棧,壓棧),類似子彈放入彈夾的動作棧的刪除操作:叫做出棧(彈棧),如同子彈出夾空棧:棧中不含任何數(shù)據(jù),此時棧頂就是棧底,然后數(shù)據(jù)從棧頂進入,頂?shù)追蛛x,棧容量變大。數(shù)據(jù)出棧時從棧頂彈出,棧頂下移,棧容量減小
二、(一幅圖理解棧頂指針和棧底指針分別指向的位置(當然這個指向只是我這里使用的方法))
typedef struct{ ElemType *base; //棧底指針 ElemType *top; //棧頂指針 int maxsize; //當前可使用最大容量}sqStack;三、創(chuàng)建一個棧
#define stacksize 100 //初始化棧是100個空間initStack(sqStack *s){ s->base=(ElemType *)malloc(stacksize * sizeof(ElemType));//申請空間 if(!s->base) //看是否申請成功 exit(0); s->top=s->base; //最開始棧頂就是棧底 s->maxsize=stacksize;//可用空間100}四、入棧操作(向棧中存放數(shù)據(jù))(在棧頂進行,每次向棧中壓入一個數(shù)據(jù),top指針+1,直到棧滿)
void Push(sqStack *s,ElemType e){ if(s->top-s->base>=s->maxsize){//判斷是否棧大小大于最大容量 return; } *(s->top)=e;//放入數(shù)據(jù) s->top++; //棧頂容量增加}五、出棧操作(棧頂取出數(shù)據(jù),棧頂指針下移,容量減1)
void Pop(sqStack *s,ElemType *e){ if(s->top==s->base){//棧已空了 return; } *e=*--(s->top); //先將指針s->top減1(位置的變化)后再取出具體數(shù)據(jù)內(nèi)容,再賦值給e。。。因為top指針指的位置是棧頂(可以想象本來棧頂和棧底指向同一位置,然后一個元素進入頂?shù)追蛛x,棧頂指向的位置是沒有元素的,因為最后一步總要s->top++,所以這里要取最后一個元素,首先得讓棧頂top指向這個元素,所以向前移動以為即--)}五、清空一個棧(就是將元素全部報廢,不是銷毀)(只要將s->top的內(nèi)容賦值為s->base即可s->top等于s->base就表明棧空了)
ClearStack(sqStack *s)(這個操作其實里面數(shù)據(jù)還是存在,只是我們看不到了,因為我們改變了指針的指向){ s->top=s->base;}六、銷毀一個棧
DestroyStack(sqStack *s){ int i,len; len=s->maxsize;//先得到這個棧的容量 for(i=0;i<len;i++){ //迭代一個一個釋放掉內(nèi)存,free用到stdlib.h頭文件 free(s->base); s->base++; } s->base=s->top=NULL; s->maxsize=0;}七、計算棧的當前容量(就是計算棧中元素的個數(shù),因此只要返回s.top-s.base即可)(注意:S.top-s.base(不是指針指針是->)兩個地址相減就是中間元素的個數(shù),但不能相加)(注意:棧的最大空間s.maxsize是該棧占據(jù)內(nèi)存空間的大小,與棧的當前容量(當前存放了多少數(shù)據(jù))不是一個概念)int StackLen(sqStack s){ return(s.top-s.base);}八、實例:二進制轉(zhuǎn)化為十進制(棧的思想,后進先出)
/************************************************************************* > File Name: 棧.c > Author: geeker > Mail: 932834897@QQ.com > Created Time: 2017年02月04日 星期六 20時16分15秒 ************************************************************************/#include<stdio.h>#include <stdlib.h>#include "math.h"#define stacksize 20typedef char ElemType;//如果int就會把輸入的數(shù)據(jù)當成整型,char可以以ASCII存在typedef struct{ ElemType *base; ElemType *top; int maxsize;}sqStack;void InitStack(sqStack *s)//初始化{ s->base=(ElemType *)malloc(stacksize * sizeof(ElemType)); if(!s->base) exit(0); s->top=s->base; s->maxsize=stacksize;}void Push(sqStack *s,ElemType e)//壓棧{ if(s->top-s->base>=s->maxsize) return; *(s->top)=e; s->top++;}void Pop(sqStack *s,ElemType *e)//出棧{ if(s->top==s->base) return; *e=*--(s->top);}int StackLen(sqStack s)//(看清s不是指針),計算當前容量{ return(s.top-s.base);//點是結(jié)構(gòu)不是指針}int main(){ ElemType c; sqStack s; int len,i,sum=0; InitStack(&s); PRintf("請輸入二進制數(shù),輸入#符號表示結(jié)束!/n"); scanf("%c",&c); while(c!='#'){//遇見#停止 Push(&s,c);//函數(shù)Push中s是指針,所以這里傳地址 scanf("%c",&c); } getchar();//把‘/n’從緩沖區(qū)去掉 len=StackLen(s); printf("棧的當前容量是%d/n",len); for(i=0;i<len;i++){ Pop(&s,&c);//Pop函數(shù)中元素形參用指針,所以我們這里c傳地址給Pop sum+=(c-48)*pow(2,i); } printf("轉(zhuǎn)化為十進制數(shù)是:%d/n",sum); return 0;}
新聞熱點
疑難解答