栈的作用:
有的同学可能会觉得,用数组或链表直接实现功能不就行了吗?干嘛要引入栈这样的数据结构呢?这个问题问的好。其实这和我们明明有两只脚可以走路,干嘛还要乘汽车、火车、飞机一样。理论上,陆地上的任何地方,你都可以靠双脚走到的,可那需要多少时间和精力呢?
我们更关注的是到达而不是如何去的过程。
栈的引入简化了程序设计的问题,划分了不同关注层次,使得思考范围缩小,更加聚焦于我们要解决的问题核心。反之,像数组等,因为要分散精力去考虑数组的下标
增减等细节问题,反而掩盖了问题的本质。
所以现在的许多高级语言,比如java、c#等都有对栈结构的封装,你可以不用关注它的实现细节,就可以直接使用Stack的push和pop方法,非常方便。
/********************* 栈(stack) 的结构类似与手枪的弹夹,后进先出; 浏览器的“后退”键就是通过栈的结构来实现的 栈(stack)是限定仅在表尾进行插入和删除的线性表。 理解栈的定义需要注意: 首先它是一个线性表,也就是说,栈元素具有线性关系,即前驱后继关系。只不过它是一种特殊的线性表而已。 定义中说是在线性表的表尾进行插入和删除操作,这里表尾是指栈顶,而不是栈底。 ********************/ /* ADT 栈(stack) Data 同线性表。元素具有相同的类型,相邻元素具有前驱和后继的关系。 Operation InitStack(*S): 初始化操作,建立一个空栈S。 DestroyStack(*S): 若栈存在,则销毁它。 ClearStack(*S): 将栈清空。 StackEmpty(S): 若栈为空,返回true,否则返回false。 GetTop(S, *e): 若栈存在且非空,用e返回S的栈顶元素。 Push(*S, e): 若栈S存在,插入新元素e到栈S中并成为栈顶元素。 Pop(*S, *e): 删除栈S中栈顶元素,并用e返回其值。 StackLength(S): 返回栈S的元素个数。 endADT */ #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 typedef int Status; //Status是函数的返回类型,其值是函数结果状态代码,如OK等 #define MAXSIZE 20 /*存储空间初始化分配量*/ typedef int ElemType; /*ElemType 类型根据实际情况而定,这里假设为int */ /* 栈的结构定义 SElemType 类型根据实际情况而定,这里假设为int */ typedef int SElemType; typedef struct { SElemType data[MAXSIZE]; //用于栈顶指针 int top; }SqStack; /* 进栈操作push 插入元素e为新的栈顶元素 */ Status Push(SqStack *S, SElemType e) { /*栈满*/ if(S->top == MAXSIZE - 1) { return ERROR; } /*栈顶指针增加一*/ S->top++; /*将新插入元素赋值给栈顶空间*/ S->data[S->top] = e; return OK; } /*出栈pop*/ Status Pop(SqStack *S, SElemType *e) { if(S->top == -1) return ERROR; /*将要删除的栈顶元素赋值给e*/ *e = S->data[S->top]; /*栈顶指针减一*/ S->top--; return OK; }
两栈共享空间
//4.5 两栈共享空间 typedef struct { SElemType data[MAXSIZE]; int top1; /*栈1栈顶指针*/ int top2; /*栈2栈顶指针*/ } SqDoubleStack; /*插入元素e为新的栈顶元素*/ Status Push(SqDoubleStack *S, SElemType e, int stackNumber) { /*栈已满,不能再push新元素了*/ if (S->top1+1 == S->top2) return ERROR; /*栈1有元素进栈*/ if (stackNumber == 1) S->data[++S->top1] = e; /*栈2有元素进栈*/ else if(stackNumber == 2) /*若栈2则先top2-1后给数组元素赋值*/ S->data[--S->top2] = e; return OK; } Status Pop(SqDoubleStack *S, SElemType *e, int stackNumber) { if (stackNumber == 1) { /*说明栈1已经是空栈,溢出*/ if (S->top1 == -1) return ERROR; /*将栈1的栈顶元素出栈*/ *e = S->data[S->top1--]; } else if (stackNumber == 2) { /*说明栈2已经是空栈,溢出*/ if (S->top2 == MAXSIZE) return ERROR; /*将栈2的栈顶元素出栈,溢出*/ *e = S->data[S->top2++]; } return OK; }