top 从 −1 起,入栈先加后存、出栈先取后减;n 个元素入栈的出栈序列数 = 卡特兰数 C(2n,n)/(n+1)。栈是只允许在一端(栈顶)进行插入和删除的线性表。
#define MaxSize 50
typedef struct {
ElemType data[MaxSize];
int top; // 栈顶指针(下标)
} SqStack;
void InitStack(SqStack *S) { S->top = -1; }
bool StackEmpty(SqStack S) { return (S.top == -1); }
bool Push(SqStack *S, ElemType x) {
if (S->top == MaxSize - 1) return false; // 栈满
S->data[++S->top] = x; // 先加后存
return true;
}
bool Pop(SqStack *S, ElemType *x) {
if (S->top == -1) return false; // 栈空
*x = S->data[S->top--]; // 先取后减
return true;
}
bool GetTop(SqStack S, ElemType *x) {
if (S.top == -1) return false;
*x = S.data[S.top]; return true;
}
top 指向栈顶元素:栈空 $top==-1$,栈满 $top==MaxSize-1$,元素个数 $top+1$。#define MaxSize 50
typedef struct { ElemType data[MaxSize]; int top1, top2; } ShStack;
void InitShStack(ShStack *S) { S->top1 = -1; S->top2 = MaxSize; }
typedef struct LinkNode {
ElemType data;
struct LinkNode *next;
} LinkNode, *LiStack;
void InitLiStack(LiStack *S) { *S = NULL; } // 不带头结点
void Push(LiStack *S, ElemType x) { // 头插法
LinkNode *p = (LinkNode *)malloc(sizeof(LinkNode));
p->data = x; p->next = *S; *S = p;
}
bool Pop(LiStack *S, ElemType *x) {
if (*S == NULL) return false;
LinkNode *p = *S; *x = p->data; *S = p->next; free(p); return true;
}
| 特性 | 顺序栈 | 链栈 |
|---|---|---|
| 存储方式 | 连续 | 离散 |
| 栈满判断 | $ top==MaxSize-1 $ | 无(动态分配) |
| 空间复杂度 | 固定 | 动态 |
| 入栈出栈 | O(1) | O(1) |
元素 1,2,3 依次入栈,合法出栈序列:1,2,3 / 1,3,2 / 2,1,3 / 2,3,1 / 3,2,1。不可能 3,1,2(3 出栈时 1,2 在栈中且 2 在 1 上)。
入栈 1,2,3,4,5,判断 4,3,5,1,2:入 1,2,3,4→出 4→出 3→入 5→出 5→需出 1 但 2 在 1 上 → 不合法。
n 个不同元素入栈,出栈序列数 = $ C(2n,n)/(n+1) $。
data[++top] vs data[top--]。↑ 以上为站内 HTML 相对链接(纯网页可浏览);本页右上「在 Obsidian 中打开」跳回源笔记。