特点:先进后出 Last In First Out (LIFO),特殊的线性表,只能在栈的一端进行操作
术语:进栈,出栈,栈顶元素,栈顶,栈顶元素,栈顶,空栈
1. 栈(栈顶指针指向-1)
1. 1 结构体
# define MaxSize 10
typedef struct {
int data[MaxSize];
int top; // 额外的空间来存储栈顶指针,指向栈顶元素
} SqStack; // SequeStack
1.2 初始化栈
void InitStack(SqStack* S) {
S->top = -1; // 初始化栈顶指针,如果栈顶指针指向null是爆错的
}
1.3 判空操作
bool EmptyStack(SqStack* S) {
return (S->top == -1);
}
1.4 进栈
一定要先移动指针,确保指针指向栈顶,再进行其他操作
bool Push(SqStack* S, int x){
// MaxSize=10, 如果S->top栈顶指针指向索引9,则表示栈满
if (S->top == MaxSize-1) { return false; }
// 以下两步等价于:S->data[++S->top] = x;
S->top = S->top + 1; // 指针向前,top永远指向栈顶
S->data[S->top] = x; // 存放元素
return true;
}
1.5 出栈
先取值,再移动指针
bool Pop(SqStack* S, int* x){
// 栈空,无法出栈元素
if (S->top == -1) { return false; }
// 先取值,再top指针-1,以下两步等价于:*x = s->data[S->top--]
*x = S->data[S->top]; // 将栈顶元素取出,赋值给x变量
S->top = S->top - 1; // 逻辑上减少该值,实际内存没有删除该变量
return true;
}
1.6 取栈顶元素
和出栈类似,出栈是取值且移动栈顶指针,而取栈顶元素不需要将指针进行后移,也就是不需要删除栈内元素
bool GetTop(SqStack* S, int* x){
if (S->top == -1) { return false; } // 栈空
*x = S->data[S->top];
return true;
}
1. 栈(栈顶指针指向0)
1. 1 结构体
# define MaxSize 10
typedef struct {
int data[MaxSize];
int top; // 额外的空间来存储栈顶指针,指向栈顶元素
} SqStack; // SequeStack
1.2 初始化栈
void InitStack(SqStack* S) {
S->top = 0; // 初始化栈顶指针,这里指向0索引
}
1.3 判空操作
bool EmptyStack(SqStack* S) {
return (S->top == 0);
}
1.4 进栈
bool Push(SqStack* S, int x){
// 栈满
if (S->top == MaxSize) { return false; }
// 以下两步等价于:S->data[S->top++] = x;
S->data[S->top] = x; // 存放元素
S->top = S->top + 1; // 指针向前,top永远指向栈顶
return true;
}
1.5 出栈
先取值,再移动指针
bool Pop(SqStack* S, int* x){
// 栈空,无法出栈元素
if (S->top == 0) { return false; }
// 先取值,再top指针-1,以下两步等价于:*x = s->data[--S->top]
S->top = S->top - 1; // 逻辑上减少该值,实际内存没有删除该变量
*x = S->data[S->top]; // 将栈顶元素取出,赋值给x变量
return true;
}
1.6 取栈顶元素
和出栈类似,出栈是取值且移动栈顶指针,而取栈顶元素不需要将指针进行后移,也就是不需要删除栈内元素
bool GetTop(SqStack* S, int* x){
if (S->top == -1) { return false; } // 栈空
*x = S->data[S->top];
return true;
}
3. 两种方式对比
3.1 入栈
3.2 出栈
4. 链栈
链栈其实就是单链表,在单链表中不断进行头插法,就是链栈中的进栈,在单链表中每次在头节点进行后删操作,就是出栈操作。
// 链栈节点结构体
typedef struct {
int data;
struct LinkNode* next;
} LinkNode;
// 链栈结构体
typedef struct {
LinkNode* top;
} LiStack;
// 创建一个空链栈
LiStack* createStack() {
LiStack* stack = (LiStack*)malloc(sizeof(LiStack));
stack->top = NULL; // 初始化栈顶指针为空
return stack;
}