数据结构与算法分析—栈的数组实现(C语言)
栈(也叫堆栈,还有一个数据结构叫做堆,注意区分),也是一种线性表,但是有一个限制,就是插入和删除操作都只能在一个位置上进行,就是在表的末端,叫做栈顶,有两种主要操作,Push(进栈)与Pop(出栈),即插入与删除,用Top来访问栈顶元素,即最后一个插入的元素,要注意在调用Pop Top函数时一定要先判断是否为空栈,在调用Push函数时一定要判断是否为满栈,由于栈是先插入的元素,后被访问,故栈又叫做(LIFO)先进后出表。
栈可以用链表实现,也可以用数组实现,用链表实现时需要用到指针,在插入和删除时会使用到malloc与free,大量的插入和删除开销会非常大,采用数组实现的话,需要提前声明一个数组的大小,在典型的应用程序中,任意一时刻元素的实际个数并不会太大,声明一个数组足够大而不至于浪费太多的空间通常并没有什么困难,所以采用数组实现更好些。
栈有许多经典的应用,在写程序时都会进行函数调用,就用到了栈,特别是递归。另外还有平衡符号的检测,中缀与后缀表达式的转换
在ACM中,栈也有许多应用,有一类题叫做单调栈,之前也做过几道。
/*
用数组实现一个栈
*/
#include<stdio.h>
#include<stdlib.h>
#define EmptyTOS (-1)
#define MinStackSize (5)
//定义一个栈结构
struct StackRecord;
typedef struct StackRecord *Stack;
typedef int ElementType;
struct StackRecord {
int Capacity;
int TopOfStack;
ElementType *Array;
};
int IsEmpty(Stack S);//判断一个栈是否为空
int IsFull(Stack S); //判断一个栈是否已满
Stack CreateStack(int MaxElements);//初始化一个栈
void DisposeStack(Stack S);//释放一个栈
void MakeEmpty(Stack S);//创建一个空栈
void Push(ElementType X,Stack S); //向栈里添加一个元素
ElementType Top(Stack S);//取栈顶元素
void Pop(Stack S);//删除栈顶元素
ElementType TopAndPop(Stack S);//取出栈顶元素并同时弹出
//初始化一个栈
Stack CreateStack(int MaxElements) {
Stack S;
if (MaxElements < MinStackSize) {
printf("Stack Size is too small\n");
}
S = (Stack)malloc(sizeof(struct StackRecord));
if (S == NULL) {
printf("Out of Space!\n");
}
S->Array = (ElementType*)malloc(sizeof(ElementType)*MaxElements);
S->Capacity = MaxElements;
MakeEmpty(S);
return S;
}
//释放一个栈,要先释放数组,在释放结构体
void DisposeStack(Stack S) {
if (S != NULL) {
free(S->Array);
free(S);
}
}
int IsEmpty(Stack S) {
return S->TopOfStack == EmptyTOS;
}
int IsFull(Stack S) {
return S->Capacity == S->TopOfStack + 1;
}
void MakeEmpty(Stack S) {
S->TopOfStack = EmptyTOS;
}
//栈的重要操作之一:元素进栈,一定要先判断栈是否已经满
void Push(ElementType X, Stack S) {
if (IsFull(S)) {
printf("Full Stack!\n");
}
S->Array[++S->TopOfStack] = X;
}
//取栈顶元素操作,也要判断是否为空
ElementType Top(Stack S) {
if (!IsEmpty(S)) {
return S->Array[S->TopOfStack];
}
printf("Empty Stack!\n");
return 0;
}
//栈的另一种重要操作:元素出栈,一定要先判断是否为空栈
void Pop(Stack S) {
if (IsEmpty(S)) {
printf("Empty Stack!\n");
}
else {
S->TopOfStack--;
}
}
//有时会把元素出栈和取栈顶元素两个函数合二为一
ElementType TopAndPop(Stack S) {
if (!IsEmpty(S)) {
return S->Array[S->TopOfStack--];
}
printf("Empty Stack!\n");
return 0;
}
int main(void) {
Stack S;
S = CreateStack(5);
if (IsEmpty(S)) {
printf("这是一个空栈\n");
}
for (int i = 1; i <= 5; i++) {
Push(i, S);
}
if (IsFull(S)) {
printf("这是一个满的栈\n");
}
printf("%d\n", S->TopOfStack);
printf("%d ", TopAndPop(S));
printf("%d\n", S->TopOfStack);
for (int i = 1; i <= 4; i++) {
printf("%d ", Top(S));
Pop(S);
printf("%d\n", S->TopOfStack);
}
DisposeStack(S);
getchar();
getchar();
return 0;
}
测试代码