百度百科:棧(stack)又名堆棧,它是一種運算受限的線性表。限定僅在表尾進行插入和刪除操作的線性表。這一端被稱爲棧頂,相對地,把另一端稱爲棧底。向一個棧插入新元素又稱作進棧、入棧或壓棧,它是把新元素放到棧頂元素的上面,使之成爲新的棧頂元素;從一個棧刪除元素又稱作出棧或退棧,它是把棧頂元素刪除掉,使其相鄰的元素成爲新的棧頂元素。
前言:以下代碼僅供參考。若你也在學數據結構,那麼你可以參考我的學習方法:
1.理解對應數據結構
2.準備紙和筆,在紙上把對應操作的實現,用圖畫的形式推演一篇。
3.打開IDE,依據第二步的思路,編寫代碼。
4.測試代碼
5.對照書本實現。
棧的抽象數據類型
來源《大話數據結構》
ADT Stack(棧)
Data
同線性表。元素具有相同的類型,相鄰的元素具有前驅和後驅關係。
Operation:
InitStack(*S);初始化操作,建立一個空棧
DestroyStack(*S);若棧存在,銷燬
ClearStack(*S);若存在,清空
StackEmpty(*S);若空棧返回true,否則false
GetTop(*S, *e);若存在,獲得棧頂元素
Push(*S, e);若存在,入棧
Pop(*S, *e);若存在,出棧
StackLength(S);若存在,返回元素個數.
EndADT
棧的順序存儲結構實現——C語言描述
棧的定義:
typedef struct
{
int data[MAXSIZE];
int top;
}Stack;
Operation: 初始化棧空間
//初始化棧空間
bool InitStack(Stack* s)
{
s->data[MAXSIZE - 1] = { 0 };
s->top = -1;
return OK;
}
Operation: 入棧
//push,入棧操作
int Push(Stack* s, int e)
{
//判斷棧空間是否滿了
if (s->top == MAXSIZE - 1 || !s)
return ERR;
s->data[++s->top] = e;
return OK;
}
Operation: 彈棧
//pop,彈棧操作
int Pop(Stack* s, int* e)
{
//判斷棧是否爲空,或不存在
if (s->top == -1 || !s)
return ERR;
*e = s->data[s->top--];
return OK;
}
Operation: 銷燬
//若棧存在,銷燬
int DestroyStack(Stack* s)
{
if (!s)
return ERR;
free(s);
s = NULL;
return OK;
}
Operation: 清空棧
//清空棧
bool ClearStack(Stack* s)
{
if (!s || s->top == -1)
return ERR;
s->data[MAXSIZE - 1] = { 0 };
s->top = -1;
return OK;
}
Operation: 獲取棧頂元素
//獲取棧頂元素
int GetTopElem(Stack* s, int *e)
{
if (!s || s->top == -1)
return ERR;
*e = s->data[s->top];
return OK;
}
Operation: 返回棧的元素個數
//返回棧的元素個數
int StackLength(Stack* s, int* length)
{
if (!s)
return ERR;
*length = s->top + 1;
return OK;
}
順序存儲結構的雙棧共享空間
棧的長度是固化的,是定義棧時就必須指定的。這勢必造成一定棧空間得不到有效利用。例如如果一個棧能夠容納4K,而我們經常用的只是前2K,這就造成了後2K的利用率低下,而有效棧空間的內存是及其有限的且十分重要的,比如內核棧空間。因此棧空間的利用率從棧底往後延伸利用率不斷降低。
爲了解決這個問題也是爲了提高棧空間的利用率,因此出現了同一個棧空間兩個棧頂指針,分居棧空間兩端。
棧的定義:
typedef struct
{
int data[MAXSIZE];
int topLeft;
int topRight;
}Stack;
Operation: 初始化棧空間
bool InitStack(Stack* s)
{
if (!s)
return ERR;
s->data[MAXSIZE - 1] = { 0 };
s->topLeft = -1;
s->topLeft = MAXSIZE - 1;
return OK;
}
Operation: 入棧
int Push(Stack* s, int e, int StackNum)
{
//判斷棧空間是否滿了,或爲空
if (s->topLeft + 1 == s->topRight || !s)
return ERR;
if (StackNum == 1)
{
s->data[++s->topLeft] = e;
}
else if (StackNum == 2)
{
s->data[--s->topRight] = e;
}
else
{
return ERR;
}
return OK;
}
Operation: 彈棧
int Pop(Stack* s, int* e, int StackNum)
{
//判斷棧是否爲不存在
if (!s)
return ERR;
if (StackNum == 1 && s->topLeft != -1)
{
*e = s->data[s->topLeft--];
}
else if (StackNum == 2 && s->topRight != MAXSIZE)
{
*e = s->data[s->topRight++];
}
else
{
return ERR;
}
return OK;
}
Operation: 銷燬
//若棧存在,銷燬
int DestroyStack(Stack* s)
{
if (!s)
return ERR;
free(s);
s = NULL;
return OK;
}
Operation: 清空棧
//清空棧
bool ClearStack(Stack* s)
{
if (!s)
return ERR;
s->data[MAXSIZE - 1] = { 0 };
s->topLeft = -1;
s->topRight = MAXSIZE;
return OK;
}
Operation: 獲取棧頂元素
int GetTopElem(Stack* s, int* e, int StackNum)
{
if (!s)
return ERR;
if (StackNum == 1 && s->topLeft != -1)
{
*e = s->data[s->topLeft];
}
else if (StackNum == 2 && s->topRight != MAXSIZE)
{
*e = s->data[s->topRight];
}
else
{
return ERR;
}
return OK;
}
棧的鏈式存儲結構——C語言描述
此時解決了順序存儲結構長度固化的缺點,並且棧的長度將不受限制。
棧的定義:
#define MAXSIZE 100
#define OK 1
#define ERR 0
typedef struct SNode
{
int val;
struct SNode* next;
}StackNode;
typedef struct LinkStack
{
StackNode* top;
int count;
} LinkStack, *LinkStackPtr;
Operation: 初始化棧空間
//初始化
bool InitLinkStack(LinkStack* s)
{
if (!s)
return ERR;
s->top = NULL;
s->count = 0;
return OK;
}
Operation: 入棧
int Push(LinkStack* s, int e)
{
//因鏈表結構通常動態變化,沒有長度限制,因此沒有基於鏈表棧,棧滿這一說
if (!s)
return ERR;
StackNode* p = (StackNode*)malloc(sizeof(StackNode));
if (!p)
return ERR;
memset(p, 0, sizeof(StackNode));
p->val = e;
p->next = s->top;
s->top = p;
s->count++;
return OK;
}
Operation: 彈棧
int Pop(LinkStack* s, int* e)
{
if (!s || !s->top)
return ERR;
StackNode* p = s->top;
*e = s->top->val;
s->top = s->top->next;
s->count--;
free(p);
p = NULL;
return OK;
}
Operation: 銷燬
//若棧存在,銷燬
int DestroyLinkStack(LinkStack* s) //
{
if (!s)
return OK;
while (s->top)
{
StackNode* p = s->top;
s->top = s->top->next;
free(p);
p = NULL;
}
free(s);
s = NULL;
return OK;
}
Operation: 清空棧
//清空棧
int ClearLinkStack(LinkStack* s)
{
if (!s)
return OK;
while (s->top)
{
StackNode* p = s->top;
s->top = s->top->next;
free(p);
}
s->count = 0;
return OK;
}
Operation: 獲取棧頂元素
int GetTop(LinkStack* s, int* e)
{
if (!s)
return ERR;
*e = s->top->val;
return OK;
}
Operation 判斷是否爲空
bool IsStackEmpty(LinkStack* s)
{
return (!s->top || !s) ? OK : ERR;
}
Operation 返回元素個數
int StackLength(LinkStack* s)
{
return s->count;
}
聲明:代碼是本人敲的,除非表明出處。
參考:《大話數據結構》