栈的特征
栈和队列都是访问受限的线性表,栈的明显特征是先进后出(FILO)
栈的插入和删除操作只允许在栈顶(top)实现,不可操作的一端叫做栈底
栈也是递归的底层实现
基于数组实现栈
自己手动实现栈,可以用链表和数组实现栈,这里我们就用数组实现,但是数组实现栈要记得扩容
一般top有两种指向,有的地方是指向栈顶元素,有的是指向栈顶元素的上一个空区域,不同的指向插入和删除的方法也有一些不同
初始时候如果top=-1 就是指向栈顶元素,如果top=0,就是指向栈顶元素的上一个单元
如果是第一种,入栈push就要先加后存stack[++top]=elem,出栈pop就要先取后减stack[top--]=elem
如图,就是第二种。入栈就要先存后加 stack[top++]=elem,出栈就要先减后取 stack[--top]=elem;
代码如下:
#include <stdio.h>
#include <stdlib.h>
// 定义栈结构体
typedef struct {
int* items;
int top;
int capacity;
} Stack;
// 初始化栈
Stack* create_stack(int capacity)
{
Stack* stack = (Stack*)malloc(sizeof(Stack));
stack->items = (int*)malloc(sizeof(int) * capacity);
stack->top = -1;
stack->capacity = capacity;
return stack;
}
// 判断栈是否为空
int is_empty(Stack* stack)
{
return stack->top == -1;
}
// 判断栈是否已满
int is_full(Stack* stack)
{
return stack->top == stack->capacity - 1;
}
// 入栈
void push(Stack* stack, int item)
{
if(is_full(stack))
{
printf("栈已满,无法入栈\n");
return;
}
stack->items[++stack->top] = item;
}
// 出栈
int pop(Stack* stack)
{
if(is_empty(stack))
{
printf("栈为空,无法出栈\n");
return -1;
}
return stack->items[stack->top--];
}
// 返回栈顶元素
int peek(Stack* stack)
{
if(is_empty(stack))
{
printf("栈为空\n");
return -1;
}
return stack->items[stack->top];
}
// 返回栈的大小
int size(Stack* stack)
{
return stack->top + 1;
}
// 测试
int main()
{
// 创建一个容量为5的栈
Stack* stack = create_stack(5);
// 入栈
push(stack, 1);
push(stack, 2);
push(stack, 3);
// 打印栈顶元素
printf("peek: %d\n", peek(stack));
// 出栈
printf("pop: %d\n", pop(stack));
// 打印栈的大小
printf("size: %d\n", size(stack));
return 0;
}