基本特征:后进先出(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;
}