1 数组实现栈的示意图
栈的表示如下:
进行入栈操作(尾插):
进行出栈操作(尾删):
2 数组实现栈
2.1 头文件及定义
定长的静态栈的结构
#include<stdio.h>
#include<stdlib.h>
typedef int STDataType;
//数组为静态数组,无法进行扩容
#define N 10
typedef struct Stack
{
STDataType a[N];
int top; // 栈顶
}Stack;
支持动态增长的栈
#include<stdio.h>
#include<stdlib.h>
typedef int STDataType;
typedef struct Stack {
STDataType* data; //数组
int top; //栈顶指针
int capacity; //数组的容量
};
因为定长的静态栈使用受到容量的限制,实际中不常使用,故下面将使用动态增长的栈来进行接口的实现。
2.2 栈的初始化
void stackInit(Stack* st) {
if (st == NULL)
return;
st->data = NULL;
//栈中没有存储任何元素,栈顶指向-1
st->top = -1;
st->capacity = 0;
}
2.3 检查数组容量,若数据已满则进行扩容
void checkCapacity(Stack* st) {
if (st == NULL)
return;
//若数组存储满了,则进行扩容
if (st->top == (st->capacity) - 1) {
int newCapacity = st->capacity == 0 ? 1 : st->capacity * 2;
//将st->data数组扩容到sizeof(STDataType)*newCapacity个字节大小
st->data = (STDataType*)realloc(st->data, sizeof(STDataType)*newCapacity);
st->capacity = newCapacity;
}
}
2.4 入栈
void stackPush(Stack* st, STDataType val) {
if (st == NULL)
return;
//检查栈是否满了
checkCapacity(st);
//进行入栈,栈顶+1 ,存入数据
st->top++;
st->data[st->top] = val;
}
2.5 出栈
void stackPop(Stack* st) {
//若栈中无数据则进行返回
if (st == NULL || st->top == -1) {
return;
}
//栈顶-1
st->top--;
}
2.6 获取栈顶元素
//获取栈顶元素
STDataType stackTop(Stack* st) {
//前提是栈中有有效元素
return st->data[st->top];
}
2.7 获取栈中的有效元素个数
//获取栈中的有效元素个数
int stackSize(Stack* st) {
if (st == NULL)
return 0;
return (st->top) + 1;
}
2.8 检测栈是否为空
//检测栈是否为空,如果为空返回非零结果,如果不为空返回0
int stackEmpty(Stack* st) {
if (st == NULL || st->top == -1)
return 1;
return 0;
}
2.9 销毁栈
//销毁栈
void stackDestroy(Stack* st) {
free(st->data);
st->data = NULL;
st->top = -1;
st->capacity = 0;
}
3 验证栈的接口
void test1() {
Stack st;
stackInit(&st);
//入栈
stackPush(&st, 0);
stackPush(&st, 1);
stackPush(&st, 2);
stackPush(&st, 3);
//栈为0 1 2 3
STDataType s = stackTop(&st);
printf("%d ", s);
stackPop(&st);
//出栈,栈为0 1 2
printf("%d ", stackSize(&st));//打印栈的大小--3
printf("%d ", stackEmpty(&st));//0表示栈不为空
stackDestroy(&st);//销毁栈
printf("%d ", stackEmpty(&st));
}
int main() {
test1();
return 0;
}
运行结果如下图:
4 栈顶指针
顶指针是在栈操作过程中,有一个专门的栈指针(习惯上称它为TOP),指出栈顶元素所在的位置。
通常情况下,栈顶指针指向:
(1)栈的最后一个元素;
(2)栈的最后一个元素的下一个位置;
(1)栈顶指针指向栈的最后一个元素
入栈操作:
top++ ;
data[top] = val ;
出栈操作:
val = data[top];
top-- ;
(2)栈顶指针指向栈的最后一个元素的下一个位置
入栈操作:
data[top] = val ;
top++ ;
出栈操作:
top-- ;
val = data[top];