1. 定义
具有一定约束的线性表(后入先出表)
2. 实现
2.1 顺序存储
# include "stdio.h"
#include "stdlib.h"
#include <stdbool.h>
typedef int ElementType;
typedef int Position;
typedef struct SNode *PtrToSNode;
typedef PtrToSNode Stack;
struct SNode {
ElementType *Data; // 存储元素的数组
Position Top; // 栈顶指针
int MaxSize; // 栈堆的最大容量
};
// 创建一个给定容量的空堆栈
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;
}
// 判断栈是否已满
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;
}
}
// 判断栈是否空
bool IsEmpty(Stack S){
return (S->Top == -1);
}
// 出栈
bool Pop(Stack S){
if(IsEmpty(S)){
printf("堆栈空");
return false;
}
else return S->Data[(S->Top)--];
}
// 打印栈里所有内容
void PrintStack(Stack S){
for(int i = 0 ;i<=S->Top;i++)
printf("%d",S->Data[i]);
printf("\n");
}
int main(){
Stack s1;
s1 = CreateStack(3);
Push(s1,1);
Push(s1,2);
Push(s1,3);
PrintStack(s1);
Pop(s1);
PrintStack(s1);
Pop(s1);
PrintStack(s1);
Pop(s1);
PrintStack(s1);
Pop(s1);
}
一个数组实现两个堆栈
# include "stdio.h"
#include "stdlib.h"
#include <stdbool.h>
typedef int ElementType;
typedef int Position;
typedef struct SNode *PtrToSNode;
typedef PtrToSNode Stack;
struct SNode {
ElementType *Data; // 存储元素的数组
Position Top1; // 栈顶指针
Position Top2; // 栈顶指针
int MaxSize; // 栈堆的最大容量
};
// 创建一个给定容量的空堆栈
Stack CreateStack(int MaxSize) {
Stack S = (Stack) malloc(sizeof(struct SNode));
S->Data = (ElementType *) malloc(MaxSize * sizeof(ElementType));
S->Top1 = -1;
S->Top2 = MaxSize;
S->MaxSize = MaxSize;
return S;
}
// 判断栈是否已满
bool IsFull(Stack S) {
return (S->Top2 - S->Top1 == 1); //堆栈满 MaxSize-Top2+Top1=MaxSize-1
}
// 入栈
bool Push(Stack S, ElementType X, int Tag) {
if (IsFull(S)) {
printf("堆栈满,无法插入");
return false;
} else {
if (Tag == 1) // 对第一个堆栈操作
S->Data[++(S->Top1)] = X;
else
S->Data[--(S->Top2)] = X;
return true;
}
}
// 判断栈是否空
bool IsEmpty(Stack S) {
return (S->Top1 == -1 && S->Top2 == S->MaxSize);
}
// 出栈
bool Pop(Stack S, int Tag) {
if (IsEmpty(S)) {
printf("堆栈空");
return false;
} else {
if (Tag == 1)
return S->Data[(S->Top1)--];
else
return S->Data[(S->Top2)++];
}
}
// 打印栈里所有内容
void PrintStack(Stack S, int Tag) {
if (Tag == 1) {
for (int i = 0; i <= S->Top1; i++)
printf("%d\t", S->Data[i]);
} else {
for (int j = S->MaxSize - 1; j >= S->Top2; j--)
printf("%d\t", S->Data[j]);
}
printf("\n");
}
int main() {
Stack s1;
s1 = CreateStack(6);
Push(s1, 1,1);
Push(s1, 2,1);
Push(s1, 3,1);
PrintStack(s1,1);
Pop(s1,1);
PrintStack(s1,1);
Push(s1, 10,2);
Push(s1, 20,2);
Push(s1, 30,2);
PrintStack(s1,2);
Pop(s1,2);
PrintStack(s1,2);
}
2.2 链式存储:插入和删除只能在堆栈的栈顶进行
# include "stdio.h"
# include "stdlib.h"
# include <stdbool.h>
typedef int ElementType;
typedef struct SNode *PtrToSNode;
typedef PtrToSNode Stack;
struct SNode {
ElementType Data; // 存储元素的数组
PtrToSNode Next;
};
// 创建一个堆栈的头结点,返回该结点的指针
Stack CreateStack() {
Stack S;
S = (Stack) malloc(sizeof(struct SNode));
S->Next = NULL;
return S;
}
// 判断栈是否空,空返回1,不空返回0
bool IsEmpty(Stack S) {
if (S->Next == NULL) {
printf("堆栈空");
return 1;
} else {
return 0;
}
}
// 入栈
bool Push(Stack S, ElementType X) {
Stack New;
New = (Stack) malloc(sizeof(struct SNode));
New->Data = X;
New->Next = S->Next;
S->Next = New;
return true;
}
// 出栈
Stack Pop(Stack S) {
Stack FirstCell;
if(IsEmpty(S)){
printf("堆栈空");
return NULL;
} else{
FirstCell = S->Next;
S->Next = FirstCell->Next;
free(FirstCell);
return S;
}
}
// 打堆栈里所有内容
void PrintStack(Stack S) {
// 跳过空头结点读取
while (S->Next) {
S = S->Next;
printf("%d\t", S->Data);
}
printf("\n");
}
int main() {
Stack s1;
s1 = CreateStack();
Push(s1, 3);
Push(s1, 30);
Push(s1, 323);
Push(s1, 34);
// PrintStack(s1);
Pop(s1);
Pop(s1);
PrintStack(s1);
}