栈是一种逻辑结构,是特殊的线性表,特殊在只能在固定一端操作
只要满足上述条件,那么这种特殊的线性表就会呈现出一种"后进先出"的逻辑,这种逻辑就被称为栈,栈在生活中到处可见,比如堆叠的盘子、电梯中的人等等。
-
栈顶 : 可以进行插入删除的一端
-
栈底:栈顶的对端
-
入栈: 将节点插入栈顶之上,也称为压栈,函数名通常为push()
-
出栈:将节点从栈顶剔除,也称为弹栈,函数名通常额外pop()
-
取栈顶: 取得栈顶元素,但不出栈,函数名通常为top()
存储方式
栈只是一种数据逻辑,如何将数据存储于内存则是另外一回事,一般而言,可以采用顺序存储形成顺序栈,或者采用链式存储形成链式栈。
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef int dataType;
// 声明栈管理结构体
typedef struct seqStack
{
dataType *data; // 指向数组首元素地址
int size; // 数组空间
int top; // 栈顶
} seqStack;
// 初始化顺序栈
struct seqStack *init_seqStack(int cap)
{
seqStack *st = malloc(sizeof(seqStack));
if (st == NULL)
return NULL;
st->data = calloc(cap, sizeof(dataType));
if (st->data == NULL)
return NULL;
st->size = cap;
st->top = -1; // 栈顶,其实就是数组的下标
return st;
}
// 判断栈是否满
bool isFull(seqStack *st)
{
if (st->top == st->size - 1)
return true;
return false;
}
// 入栈
bool push(seqStack *st, dataType data)
{
if (isFull(st))
return false;
st->data[++st->top] = data;
return true;
}
// 判断栈是否空
bool isEmpty(seqStack *st)
{
return st->top == -1;
}
// 去栈顶元素不出栈
bool top(seqStack *st, dataType *data)
{
if (isEmpty(st))
return false;
// 取栈顶元素
*data = st->data[st->top];
return true;
}
// 出栈
int pop(seqStack *st, dataType *data)
{
// 访问栈顶元素并取出,如果无法访问表示栈顶没有元素可取
if (!top(st, data))
return -1;
st->data[st->top] = 0;
st->top--;
return 1;
}
void show_stack(struct seqStack *st)
{
printf("当前栈:");
for (int i = 0; i < 5 && st->data[i] != 0; i++)
{
printf("%d\t", st->data[i]);
}
printf("\n");
}
int main(int argc, char const *argv[])
{
// 初始化栈
seqStack *st = init_seqStack(5);
if (st == NULL)
{
printf("init stack failed:\n");
return -1;
}
// // 入栈
// push(st, 1);
// push(st, 2);
// push(st, 3);
while (1)
{
dataType data;
if (0 == scanf("%d", &data))
{
while (getchar() != '\n')
{
if (isEmpty(st))
{
printf("栈空\n");
continue;
}
pop(st, &data);
printf("%d\n", data);
show_stack(st);
break;
};
}
else
{
if (isFull(st))
{
printf("栈满\n");
continue;
}
push(st, data);
show_stack(st);
}
}
return 0;
}