數據結構:順序棧的實現
1、快速開始
棧是一種遵循元素后進(Push)先出(Pop)規則的線性表,即最后加入的元素最先出來,它的實現可以用數組或者鏈表。

它的特點如下:
- 后入先出,先入后出。
- 除了頭尾節點之外,每一個元素有一個前驅,有一個后繼。
2、實現棧
我們已經說過了,棧是一種線性表,故其底層是基於數組或者鏈表的。那么,我們的重點是維護一種規則,即后進先出。
我們始終要有一個變量L來記錄最后一個元素的位置:
- 當壓入時,將新元素插入到L位置之后,然后更新L,即L+1.
- 當彈出時,將L位置元素進行刪除,然后更新L,即L-1。
也正是因為,我們使用的是線性表,正好可以利用其尺寸來表示L,即線性表的大小可以表示最后一個元素的位置。
2.1、棧的實現
class MyStack {
private List<Integer> data; // 存儲元素
public MyStack() {
data = new ArrayList<>();
}
/**插入一個元素到棧中. */
public void push(int x) {
data.add(x);
}
/**檢查是否為空 */
public boolean isEmpty() {
return data.isEmpty();
}
/**到達棧頂. */
public int top() {
return data.get(data.size() - 1);
}
/** 刪除一個元素. 操作成功返回true. */
public boolean pop() {
if (isEmpty()) {
return false;
}
data.remove(data.size() - 1);
return true;
}
};
3、C語言版本實現
3.1、對棧的結構定義:
typedef struct
{
int *base;
int *top;
int stacksize;
}SqStack;
說明:
1.base表示棧底指針,在判斷出棧、初始化和重新分配空間的時候需要用到。
2.top表示棧頂指針,是棧最關鍵和核心的組成,入棧時top向上移動,出棧時top向下移動。
3.此處的stacksize並不表示當前的棧中的元素數量,而是表示棧的容量,也就是能裝多少個元素。
3.2、初始化棧:
int initStack(SqSatck *S)
{
S->base=(int*)malloc(100*sizeof(int));
if(!S)
return 0; //0代表操作失敗
S->top=S->base;
stacksize=100;
return 1; //1代表操作完成
}
說明:
1.順序棧初始化無非就是給棧分配連續的內存空間,base是棧底指針,在上面提到過,它用來指示一段連續的內存空間的首地址,也就是用來初始化。
2.分配空間不意味着一定會有那么多空間,所以判斷也不可缺少。
3.分配空間后,base和top的地址應該一致,此時top還沒有移動。
3.3、壓棧
int push(SqStack * S,int elem)
{
if(S->top-S->base>=S->stacksize)
{
S->base=(SElemType *)
realloc(S->base,(S->stacksize+10)*sizeof(SElemType)); //10代表增量,你可以使用宏定義,方便后續修改。
if(!S->base)
return 0;
S->top=S->base+S->stacksize;
S->stacksize+=10
}
*S->top++=elem;
return 1;
}
說明:
1.壓棧是棧的核心操作,關鍵步驟無非是*S->top++=elem;但是在進行此步操作時,一定要判斷棧是否超出容量。
2.如果棧超出容量,則要在進行原空間的基礎上重新分配空間,realloc是關鍵的命令。
realloc
原型:extern void *realloc(void *mem_address, unsigned int newsize);
用法:#include <stdlib.h> 有些編譯器需要#include <alloc.h>
功能:改變mem_address所指內存區域的大小為newsize長度。
說明:如果重新分配成功則返回指向被分配內存的指針,否則返回空指針NULL。
當內存不再使用時,應使用free()函數將內存塊釋放。
3.分配空間以后,在修改stacksize之前,top應該保持在容量頂端,S->top=S->base+S->stacksize;
2.4出棧
int pop(SqStack *q)
{
if(S->top==S->base)
return 0;
return *S->--top;;
}
說明:
1.出棧是簡單操作,其實這里並沒有完美的實現這個效果,你應該考慮到如果在擴容后又迅速減小,會造成大量的空間浪費。
2.5遍歷棧
int printfStack(SqStack *S)
{
int *p=S->base;
puts("輸出棧");
for(p;p!=S->top;p++)
{
printf("***%d",*p);
}
}

