棧和隊列
棧的定義:棧是限定僅在表尾進行插入或刪除操作的線性表。表尾端稱為棧頂 表頭端稱為棧底 不含元素的空表稱為空棧
特點:棧的修改是按后進先出的原則進行的
順序棧的表示和實現
定義:順序棧是指利用順序存儲結構實現的棧。即利用一組地址連續的存儲單元依次存放自棧底到棧頂的數據元素,以top指示棧頂元素指針 以base指示棧底元素指針
空棧:當top和base相等時表示空棧。
棧中元素個數:top-base;
原理:當插入新棧頂元素時,指針top增加1,刪除棧頂元素時指針top減1。棧非空時,top始終指向棧頂元素的上一個位置。
`//////--------順序棧的存儲結構------------
#define Maxsize 100 ////順序棧存儲空間的初始分配量
typedef struct
{ SElemType *base; //棧底指針
SElemType *top; //棧頂指針
int stacksize; //棧可用的最大容量
} SqStack;`
`///----------順序棧的初始化------------
Status InitStack(SqStack &s)
{ ///構造一個空棧
S.base=new SElemType [MAXSIZE]; //為順序棧動態分配一個最大容量為MAXSIZE的數組空間
if(!S.base) exit(OVERFLOW); ///存儲分配失敗
S.top=S.base; ///top初始為base,空棧
S.stacksize=MAXSIZE; //stacksize置為棧的最大容量MAXSIZE
return ok;
}`
`///-------順序棧的入棧操作----------
Status Push(SqStack &s,SElemType e)
{ ///插入元素e為新的棧頂元素
if(S.top-S.base==S.stacksize) return error; ///棧滿
*S.top=e;
S.top++; ///元素e壓入棧頂 棧頂指針加一
return ok;
} `
`///-------順序棧的出棧操作----------
Status Pop(SqStack &s,SElemType &e)
{ ///刪除棧頂元素用e返回其值
if(S.top==S.base) return error; ///棧空
S.top--;
e=*S.top; ///棧頂指針減一,將棧頂元素賦給e
return ok;
} `
`////------取順序棧的棧頂元素-----------
SElemType GetTop(SqStack S)
{ ///返回S的棧頂元素 不修改棧頂指針
if(S.top!=S.base) ///棧非空
return *(S.top-1); ///返回棧頂元素的值 棧頂指針不變
}`
鏈棧的表示和實現
定義:鏈棧指采用鏈式存儲結構實現的棧 通常鏈棧用單鏈表表示
`////-------鏈棧的存儲結構------
typedef struct StackNode
{
ElemType data; ////鏈棧的數據域
struct StackNode *next; ///鏈棧的指針域
}StackNode,*LinkStack;`
`/////------鏈棧的初始化--------
Status InitStack(LinkStack &s)
{ ///構造一個空棧S,棧頂指針置空
S=NUll;
return ok;
}`
`//////-------鏈棧的入棧-----
Status Push (LinkStack &s,SElemType e)
{ ///在棧頂插入元素e
p=new StackNode; //生成新節點
p->data=e; ///將新結點數據域置為e
p->next=S; ///將新結點插入棧頂
S=p; ///修改棧頂指針為p
return ok;
}`
`/////--------鏈棧的出棧--------
Status Pop(LinkStack &s,SElemType &e)
{ //刪除S的棧頂元素,用e返回其值
if(S==NULL) return error; //棧空
e=S->data; //將棧頂元素賦給e
p=S; //用p臨時保存棧頂元素空間,以備釋放
S=S->next; ///修改棧頂指針
delete p; /// 釋放原棧頂元素的空間
return ok;
}`
`////------取鏈棧的棧頂元素-------
SElemType GetTop(LinkStack S)
{ //返回S的棧頂元素,不修改棧頂的指針
if(S!=NULL) //棧非空
return S->data; //返回棧頂元素值,棧頂指針不變
}`
棧與遞歸
1.認識遞歸:棧的重要應用是在程序設計語言中實現遞歸,所謂遞歸指若在一個函數過程或者數據結構定義的內部又直接(或間接)出現定義的本身的應用稱它們時遞歸的或者是遞歸定義的。
利用棧將遞歸轉換為非遞歸的方法步驟:
(1)設置一個工作棧存放遞歸工作記錄(包括實參 返回地址及局部變量)
(2) 進入非遞歸調用入口將調用程序傳來的實在參數和返回地址入棧
(3) 進入遞歸調用入口:當不滿足遞歸結束條件時 逐層遞歸將實參返回地址及局部變量入棧 這一個過程可以用循環語句實現
(4)遞歸結束條件滿足 將到達遞歸出口的給定常數作為當前的函數值
(5) 在棧不空的情況下,逐層計算當前的函數值,直至棧空為止。