一、什么是栈(Stack)
首先来说,栈是一种线性表的表现形式,其定义是只允许在栈顶进行插入或者删除的线性表,所以栈就有线性表的表现形式,链式栈和顺序栈。
栈顶(Top):允许进行数据的插入和删除的一端。
栈底(Bottom):不允许进行数据的插入和删除的一端。
空栈:不含任何元素的栈。
由图我们可以看出栈在插入数据时,比如说插入的是a1,a2,a3,a4,a5,a6,那么出栈的顺序就依次为a6,a5,a4,a3,a2,a1,所以总结一个规律就是栈的元素是后进先出。
二、栈的基本操作
InitStack(&S):初始化一个空栈。
StackEmpty(S):判断一个栈是否为空,为空返回true,不为空返回false。
Push(&S,x):进栈,如过栈未满,讲x加入为新的栈顶元素。
Pop(&S,&x):出栈,弹出栈顶元素,用x返回其值。
GetTop(S,&x):读取栈顶元素,用x返回其值。
DestroyStack(&S):销毁栈,并释放S栈占用的空间。
三、顺序栈的实现
顺序栈的存储结构:
#define MaxSize 100 typedef struct { ElemType data[MaxSize]; //存放栈中的元素 int top; //指向栈顶元素的位置 }SeqStack;
我们在初始化栈的时候栈顶的top初始为-1,在进行入栈操作时候先由top加1在进行元素的添加,在进行出栈操作时先取栈顶元素在使top减1。当S.top==-1时栈为空,S.top == MaxSize-1时栈满。
顺序栈栈的基本操作:
seqStack.h
#include#define MaxSize 100 #define True 1 #define False 0 typedef int ElemType; typedef int Status; typedef int Boolean; typedef struct { ElemType data[MaxSize]; //存放栈中的元素 int top; //指向栈顶元素的位置 }SeqStack; void InitSeqStack(SeqStack *S);//初始化栈。 Boolean SeqStackEmpty(SeqStack S);//判断一个栈是否为空,为空返回true,不为空返回false。 Status PushSeqStack(SeqStack *S, ElemType x);//进栈,如过栈未满,讲x加入为新的栈顶元素。 Status PopSeqStack(SeqStack *S, ElemType *x);//出栈,弹出栈顶元素,用x返回其值。 Status GetTopSeqStack(SeqStack S, ElemType *x);//读取栈顶元素,用x返回其值。 Status DestroySeqStack(SeqStack *S);//毁栈,并释放S栈占用的空间。
seqStack.c
#include#include"sqeStack.h" void InitSeqStack(SeqStack *S) { //初始化栈。 S->top = -1; //初始化栈顶 } Status PushSeqStack(SeqStack *S, ElemType x) { //进栈,如过栈未满,将x加入为新的栈顶元素。 if (S->top == MaxSize - 1) //元素超出报错 return False; else { S->top ++; S->data[S->top] = x; return True; } } Status PopSeqStack(SeqStack *S, ElemType *x) { //出栈,弹出栈顶元素,用x返回其值。 if (S->top == -1) return False; else { *x = S->data[S->top]; S->top--; return True; } } Boolean SeqStackEmpty(SeqStack S) { //判断一个栈是否为空,为空返回true,不为空返回false。 if (S.top == -1) return True; else return False; } Status GetTopSeqStack(SeqStack S, ElemType *x) { //读取栈顶元素,用x返回其值。 if (S.top == -1) return False; else { *x = S.data[S.top]; } } Status DestroySeqStack(SeqStack *S) { //毁栈,并释放S栈占用的空间。 S->top = -1; }
链栈的存储结构:
typedef struct LinkNode { ElemType data; struct LinkNode *next; }LinkNode,*LinkStack;
链栈的Push和Pop操作:
代码实现:
LinkStack.h
#include#define True 1 #define False 0 typedef int ElemType; typedef int Status; typedef int Boolean; typedef struct LinkNode { ElemType data; struct LinkNode *next; }LinkNode,*LinkStack; void InitLinkStack(LinkStack S);//初始化栈。 Boolean LinkStackEmpty(LinkStack S);//判断一个栈是否为空,为空返回true,不为空返回false。 Boolean PushLinkStack(LinkStack S, ElemType x);//进栈,将x加入为新的栈顶元素。 Boolean PopLinkStack(LinkStack S, ElemType *x);//出栈,弹出栈顶元素,用x返回其值。 Boolean GetTopLinkStack(LinkStack S, ElemType *x);//读取栈顶元素,用x返回其值。 Boolean DestroyLinkStack(LinkStack S);//毁栈,并释放S栈占用的空间。
LinkStack.c
#include"LinkStack.h" void InitLinkStack(LinkStack S) { //初始化栈。 S = (LinkNode*)malloc(sizeof(LinkNode)); S->next = NULL; } Boolean PushLinkStack(LinkStack S, ElemType x) { //进栈,将x加入为新的栈顶元素。 LinkNode *newSpace = (LinkNode*)malloc(sizeof(LinkNode)); newSpace->data = x; newSpace->next = S->next; S->next = newSpace; return True; } Boolean PopLinkStack(LinkStack S, ElemType *x) { //出栈,弹出栈顶元素,用x返回其值。 if (S->next == NULL) return False; else { LinkNode *p = S->next; *x = p->data; S->next = p->next; free(p); return True; } } Boolean LinkStackEmpty(LinkStack S) { //判断一个栈是否为空,为空返回true,不为空返回false。 if (S->next == NULL) return True; else return False; } Boolean GetTopLinkStack(LinkStack S, ElemType *x) { //读取栈顶元素,用x返回其值。 if (S->next == NULL) return False; else { *x = S->next->data; return True; } } Boolean DestroyLinkStack(LinkStack S) { //毁栈,并释放S栈占用的空间。 S->next = NULL; free(S); return True; }