堆栈(Stack)可以认为是具有一定约束的线性表,插入和删除操作都作用在一个称为栈顶(Top)的端点位置。
堆栈的基本操作:
- Stack CreateStack(int MaxSize)
- bool IsFull(Stack S)
- bool Push(Stack S, ElementType X)
- bool IsEmpty(Stack S)
- ElementType Pop(Stack S)
1. 栈的顺序存储实现
typedef int Position;
typedef struct SNode * PtrToSNode;
struct SNode{
ElementType * Data; /* 存储元素的数组 */
Position Top; /* 栈顶指针 */
int MaxSize; /* 堆栈最大容量 */
};
typedef PtrToSNode Stack;
- 当 Top 指向 -1 时,表示空栈;当 Top 指向 MaxSize-1 时,表示满栈。
1.1 初始化栈
Stack CreateStack(int MaxSize){
Stack S = (Stack)malloc(sizeof(struct SNode));
S->Data = (ElementType *)malloc(MaxSize * sizeof(ElementType));
S->Top = -1;
S->MaxSize = MaxSize;
return S;
}
1.2 入栈操作 Push
bool IsFull(Stack S){
return(S->Top == S->MaxSize-1);
}
bool Push(Stack S, ElementType X){
if(IsFull(S)){
printf("堆栈满");
return false;
}
else{
S->Data[++(S->Top)] = X;
return true;
}
}
1.3 出栈操作 Pop
bool IsEmpty(Stack S){
return(S->Top == -1);
}
ElementType Pop(Stack S){
if(IsEmpty(S)){
printf("堆栈空");
return ERROR; /*ERROR 是ElementType 的特殊值,标志错误 */
}
else
return(S->Data[(S->Top)--]);
}
1.4 双堆栈
用一个数组实现两个堆栈,要求最大可能地利用数组空间。
typedef int Position;
typedef struct SNode * PtrToSNode;
struct SNode{
ElementType * Data; /* 存储元素的数组 */
Position Top1; /* 堆栈1的栈顶指针 */
Position Top2; /* 堆栈2的栈顶指针 */
int MaxSize; /* 堆栈最大容量 */
};
typedef PtrToSNode Stack;
bool Push(Stack S, ElementType X, int Tag){
/* Tag 作为区分两个堆栈的标志,取值为1和2*/
if(S->Top2 - S->Top1 == 1){
printf("堆栈满\n");
return false;
}
else{
if(Tag == 1)
S->Data[++(S->Top1)] = X;
else
S->Data[--(S->Top2)] = X;
return true;
}
}
ElementType Pop(Stack S, int Tag){
if(Tag == 1){
if(S->Top1 == -1){
printf("堆栈1空\n");
return ERROR;
}
else return S->Data[(S->Top1)--];
}
else{
if(S->Top2 == S->MaxSize){
printf("堆栈2空\n");
return ERROR;
}
else return S->Data[(S->Top2)++];
}
}
2. 堆栈的链式存储实现
栈的链式存储结构(链栈)与单链表类似,但其操作受限制,插入和删除操作只能在链栈的栈顶进行。
栈顶指针Top就是链表的头指针。有时为了简便算法,链栈也可以带一空的表头结点,表头结点后面的第一个结点就是链栈的栈顶结点,栈中的其他结点通过他们的指针Next链接起来,栈底结点的Next 为NULL。