此處的堆棧僅僅指數據結構中的堆棧,而非在程序存儲時的堆和棧。
堆棧(Stack)可以認爲是一種有一定約束的線性表。插入和刪除操作都只能在棧頂進行。比如在洗碗時放碗的時候,新洗完的碗都放在頂部,取走碗時也是從頂部取走。
因爲堆棧有此特性,所以將其稱爲“後入先出”(Last In First Out)表。
一、堆棧的抽象數據類型描述
數據對象集:一個有多個或零個元素的有窮線性表
操作集:生成空堆棧、判斷堆棧是否已滿、壓入堆棧、判斷堆棧是否爲空、刪除並返回棧頂元素
二、棧的順序存儲(順序棧)
棧的順序存儲結構通常是由一個一維數組和一個記錄棧頂元素位置的變量組成的。Top指向-1時表示空棧,Top指向Maxsize-1時表示滿棧。
typedef struct{
ElementType Data[MaxSize];
int Top;
}Stack;
(1)入棧(Push)
操作步驟:
判斷棧是否已滿
若不滿,Top加1
將新元素放入Data數組的Top分量中
代碼實現:
void Push(Stack *PtrS, ElementType item)
{
if ( PtrS -> Top == MaxSize - 1) //判斷棧是否已滿
{
printf("堆棧已滿") ;
return ;
}
else
{
PtrS -> Data[ ++ ( PtrS -> Top )] = item; //將新元素放入對應的Data數組中
return ;
}
}
(2)出棧(Pop)
操作步驟:
判斷棧是否爲空
若不空返回Data[Top],同時將Top減1
代碼實現:
void Pop(Stack *PtrS)
{
if ( PtrS -> top == -1) //判斷棧是否爲空
{
printf("堆棧空");
return ERROR;
}
else
{
PtrS -> Data[ ( PtrS -> Top ) --]; //將棧頂元素刪除
return;
}
}
三、堆棧的鏈式存儲(鏈棧)
鏈棧與單向鏈表相似,只是操作受限,只能在鏈棧的棧頂進行插入或刪除操作。有時爲了方便鏈棧也可以附帶一個空的表頭結點,表頭結點後面的第一個結點就是鏈棧的棧頂結點,棧中其他結點通過他們的指針next鏈接起來,棧底結點的next爲NULL
代碼實現:
typedef struct SNode *PtrToSNode;
struct SNode {
ElementType Data;
PtrToSNode Next;
};
typedef PtrToSNode Stack;
Stack CreateStack( )
{ /* 構建一個堆棧的頭結點,返回該結點指針 */
Stack S;
S = (Stack)malloc(sizeof(struct SNode));
S->Next = NULL;
return S;
}
bool IsEmpty ( Stack S )
{ /* 判斷堆棧S是否爲空,若是返回true;否則返回false */
return ( S->Next == NULL );
}
bool Push( Stack S, ElementType X )
{ /* 將元素X壓入堆棧S */
PtrToSNode TmpCell;
TmpCell = (PtrToSNode)malloc(sizeof(struct SNode));
TmpCell->Data = X;
TmpCell->Next = S->Next;
S->Next = TmpCell;
return true;
}
ElementType Pop( Stack S )
{ /* 刪除並返回堆棧S的棧頂元素 */
PtrToSNode FirstCell;
ElementType TopElem;
if( IsEmpty(S) ) {
printf("堆棧空");
return ERROR;
}
else {
FirstCell = S->Next;
TopElem = FirstCell->Data;
S->Next = FirstCell->Next;
free(FirstCell);
return TopElem;
}
}