基本特徵:後進先出(LIFO)
基本操作:壓入(push),彈出(pop)
實現要點:初始化內存空間,棧頂指針,判空判滿
缺點:容易造成空間浪費,且易受初始化空間的侷限
一般而言,棧的重要程度要大於隊列,棧的用途非常廣泛,除了表達式求值,在深度優先遍歷、保存現場等問題中經常出現。,
舉例1:基於數組的堆棧
//堆棧
typedef struct ZHLStack{
int *array;
size_t cap;//容量
size_t top;//棧頂
}ZHLSTACK;
//分配內存,並初始化爲空堆棧
void stackInit(ZHLSTACK *stack,size_t cap){
stack->array = (int *)malloc(cap * sizeof(int));
stack->cap = cap;
stack->top = 0;
}
//釋放內存並恢復到初始狀態
void stackDelete(ZHLSTACK *stack){
free(stack->array);
stack->array = NULL;
stack->cap = 0;
stack->top = 0;
}
//判斷堆棧是否滿
int stackFull(ZHLSTACK *stack){
return stack->top >= stack->cap;
}
//判斷堆棧是否爲空
//top爲零
int stackEmpty(ZHLSTACK *stack){
return !stack->top;
}
//push
void stackPush(ZHLSTACK *stack,int data){
stack->array[stack->top ++] = data;
}
//pop
int stackPop(ZHLSTACK *stack){
return stack->array[-- stack->top];
}
//獲取容量
size_t stackSize(ZHLSTACK *stack){
return stack->top;
}
//獲取棧頂元素
int stackTop(ZHLSTACK *stack){
return stack->array[stack->top - 1];
}
int main() {
ZHLSTACK stack;
stackInit(&stack, 6);
int i = 0;
while (!stackFull(&stack)) {
stackPush(&stack, i ++);
}
printf("size = %zu\r\n",stackSize(&stack));
while (! stackEmpty(&stack)) {
printf("%d\r\n",stackPop(&stack));
}
stackDelete(&stack);
return 0;
}
舉例2:基於鏈表的堆棧
//節點
typedef struct stackListNode{
int data;//value
struct stackListNode *next;//後指針
} SLNode;
//堆棧
typedef struct MyStack{
SLNode *top;//棧頂
} MYStack;
//創建節點
static SLNode* createNode(SLNode *next,int val){
SLNode *node = malloc(sizeof(SLNode));
node->data = val;
node->next = next;
return node;
}
//銷燬節點
static SLNode *destroyNode(SLNode *node){
SLNode *next = node->next;
free(node);
return next;
}
//並初始化爲空堆棧
void stackInit(MYStack *stack){
stack->top = NULL;
}
//釋放剩餘節點並恢復到初始狀態
void stackDelete(MYStack *stack){
while (stack->top) {
stack->top = destroyNode(stack->top);
}
}
//判斷堆棧是否爲空
int stackEmpty(MYStack *stack){
return ! stack->top;
}
//push
void stackPush(MYStack *stack,int data){
stack->top = createNode(stack->top,data);
}
//pop
int stackPop(MYStack *stack){
int value = stack->top->data;
stack->top = destroyNode(stack->top);
return value;
}
//獲取容量
size_t stackSize(MYStack *stack){
size_t size = 0;
SLNode *node = NULL;
for (node = stack->top; node; node = node->next) {
++ size;
}
return size;
}
//獲取棧頂
int stackTop(MYStack *stack){
return stack->top->data;
}