上文提到过栈以及栈的基本操作。上文中是基于链表做的实现。但是这种方法会出现大量的malloc()和free()操作,这种开销是非常昂贵的。
另外一种实现方式是基于数组的实现。这种实现方式需要预先制定一个栈的大小,此外还需要一个Top来记录栈顶元素下一个位置的数组索引值。如下图所示:
有的教材将Top指向栈顶元素,也就是上图中X所在的数组单元。我们这里不这么认为。
这种情况下栈的数据结构定义如下:
typedef struct StackRecord *Stack; struct StackRecord { int Capacity; int Top; int *Array; };
主要操作如下:
//判断栈是否为空 int IsEmpty(Stack S); //判断栈是否已满 int IsFull(Stack S); //创建栈 Stack CreateStack(int MaxElements); //回收栈 void DisposeStack(Stack S); //清空栈 void MakeEmpty(Stack S); //进栈操作 void Push(int X, Stack S); //返回栈顶元素 int Top(Stack S); //出栈操作 void Pop(Stack S); //出栈并且返回栈定元素 int PopAndTop(Stack S);
一个完整的例子代码如下:
#include <stdio.h> #include <stdlib.h> #define MIN_STACK_SIZE 5 typedef struct StackRecord *Stack; struct StackRecord { int Capacity; int Top; int *Array; }; //判断栈是否为空 int IsEmpty(Stack S); //判断栈是否已满 int IsFull(Stack S); //创建栈 Stack CreateStack(int MaxElements); //回收栈 void DisposeStack(Stack S); //清空栈 void MakeEmpty(Stack S); //进栈操作 void Push(int X, Stack S); //返回栈顶元素 int Top(Stack S); //出栈操作 void Pop(Stack S); //出栈并且返回栈定元素 int PopAndTop(Stack S); int IsEmpty(Stack S) { return S->Top == 0; } int IsFull(Stack S) { return S->Top == S->Capacity; } void MakeEmpty(Stack S) { S->Top = 0; } Stack CreateStack(int MaxElements) { if(MaxElements < MIN_STACK_SIZE) { fprintf(stderr, "Can't create a Stack less than %d elements\n",MIN_STACK_SIZE); exit(1); } else { Stack S = malloc(sizeof(struct StackRecord)); if(S == NULL) { fprintf(stderr, "Out of space!"); exit(1); } S->Array = malloc(sizeof(int)*MaxElements); S->Capacity = MaxElements; MakeEmpty(S); return S; } } void DisposeStack(Stack S) { if(S != NULL) { free(S->Array); free(S); } } void Push(int X, Stack S) { if(IsFull(S)) { fprintf(stderr,"The Stack Is Full"); } else { //元素先入栈 S->Array[S->Top++] = X; } } int Top(Stack S) { if(!IsEmpty(S)) { int tmp = S->Top - 1; return S->Array[tmp]; } else { fprintf(stderr,"The Stack Is Full"); exit(1); } } void Pop(Stack S) { if(!IsEmpty(S)) { --(S->Top); } else { fprintf(stderr,"The Stack Is Full"); exit(1); } } int PopAndTop(Stack S) { if(!IsEmpty(S)) { return S->Array[--S->Top]; } else { fprintf(stderr,"The Stack Is Full"); exit(1); } } int main(void) { Stack S = CreateStack(10); int i; for(i = 0; i < 10; i++) { Push(i,S); } while(!IsEmpty(S)) { printf("%d ",PopAndTop(S)); } printf("\n"); return 0; }