/* *Copyright (c) 2015 , 烟台大学计算机学院 *All right resvered . *文件名称: 建立顺序栈算法库.cpp *作 者: 郑兆涵 *栈和队列(一)——栈 */
问题:
顺序栈算法库采用程序的多文件组织形式,包括两个文件:
①头文件:sqstack.h,包含定义顺序栈数据结构的代码、宏定义、要实现算法的函数的声明
②源文件:sqstack.cpp,包含实现各种算法的函数的定义
编程代码:
//头文件:sqstack.h,包含定义顺序栈数据结构的代码、宏定义、要实现算法的函数的声明 #ifndef SQSTACK_H_INCLUDED #define SQSTACK_H_INCLUDED #define MaxSize 100 typedef char ElemType; typedef struct { ElemType data[MaxSize]; int top; //栈指针 } SqStack; //顺序栈类型定义 void InitStack(SqStack *&s); //初始化栈 void DestroyStack(SqStack *&s); //销毁栈 bool StackEmpty(SqStack *s); //栈是否为空 int StackLength(SqStack *s); //返回栈中元素个数——栈长度 bool Push(SqStack *&s,ElemType e); //入栈 bool Pop(SqStack *&s,ElemType &e); //出栈 bool GetTop(SqStack *s,ElemType &e); //取栈顶数据元素 void DispStack(SqStack *s); //输出栈 #endif // SQSTACK_H_INCLUDED //源文件:sqstack.cpp,包含实现各种算法的函数的定义 #include <stdio.h> #include <malloc.h> #include "sqstack.h" void InitStack(SqStack *&s) { s=(SqStack *)malloc(sizeof(SqStack)); s->top=-1; } void DestroyStack(SqStack *&s) { free(s); } int StackLength(SqStack *s) //返回栈中元素个数——栈长度 { return(s->top+1); } bool StackEmpty(SqStack *s) { return(s->top==-1); } bool Push(SqStack *&s,ElemType e) { if (s->top==MaxSize-1) //栈满的情况,即栈上溢出 return false; s->top++; s->data[s->top]=e; return true; } bool Pop(SqStack *&s,ElemType &e) { if (s->top==-1) //栈为空的情况,即栈下溢出 return false; e=s->data[s->top]; s->top--; return true; } bool GetTop(SqStack *s,ElemType &e) { if (s->top==-1) //栈为空的情况,即栈下溢出 return false; e=s->data[s->top]; return true; } void DispStack(SqStack *s) //输出栈 { int i; for (i=s->top;i>=0;i--) printf("%c ",s->data[i]); printf("\n"); } #include <stdio.h> #include "sqstack.h" int main() { ElemType e; SqStack *s; printf("(1)初始化栈s\n"); InitStack(s); printf("(2)栈为%s\n",(StackEmpty(s)?"空":"非空")); printf("(3)依次进栈元素a,b,c,d,e\n"); Push(s,'a'); Push(s,'b'); Push(s,'c'); Push(s,'d'); Push(s,'e'); printf("(4)栈为%s\n",(StackEmpty(s)?"空":"非空")); printf("(5)栈长度:%d\n",StackLength(s)); printf("(6)从栈顶到栈底元素:");DispStack(s); printf("(7)出栈序列:"); while (!StackEmpty(s)) { Pop(s,e); printf("%c ",e); } printf("\n"); printf("(8)栈为%s\n",(StackEmpty(s)?"空":"非空")); printf("(9)释放栈\n"); DestroyStack(s); return 0; }
学习心得:
一、栈是最常用的和最重要的数据结构之一,用途广泛。在学习了二叉树之后,我发现,还会回来再看看栈的问题,因为将递归算法转换成非递归算法的时候,还需要使用到栈。以下是栈的一些相关概念:
①栈顶:线性表中允许进行插入、删除操作的一端。也就是说初始化栈的时候,就会设立一个指针专门指向栈顶P,而栈在进行插入和删除的时候,栈顶就是进行所谓操作的那个位置。
②栈底:线性表的另一端为栈底。
③空栈:线性表中没有元素的时候,或者说刚刚初始化的一个栈,都是空栈。
④压栈(进栈):插入操作。对当前栈顶位置进行进栈操作。
⑤退栈(出栈):删除操作。也是删除当前栈顶位置元素的操作。
二、栈的顺序存储结构及其基本运算的实现(代码分析)
typedef struct
{
Elemtype data[Maxsize];
int top; //定义一个栈顶指针
}SqStack; //定义一个顺序栈类型
①通过对栈的大小MaxSize进行设置,每个元素都具有同意数据类型即ElemType,其中定义一个top为栈的栈顶指针,最后再定义一个顺序栈类型SqStack。
②再定义一个指针s专门取指向顺序栈,栈空条件为s->top==-1;栈满条件为s->top==MaxSize-1;元素e的进栈操作和出栈操作都是分别对栈顶元素top进行+1和-1的操作。
(1)void InitStack(SqStack *&s); //初始化栈
建立一个新的空栈s,实际上是将栈顶指针指向-1即可:
首先对顺序栈SqStack分配空间malloc(sizeof(SqStack)),再将它的地址赋值给s,即可得到s指向顺序栈,并且top指向-1的位置
(2)void DestroyStack(SqStack *&s); //销毁栈
释放栈s所占用的存储空间:
整个栈的存储,是占用了包含由top=-1这一个空间和其他栈内空间所构成的整段空间,只需要将s指向的这个顺序栈作为一个结构体整体释放即可。
(3)bool StackEmpty(SqStack *s); //栈是否为空
栈s为空的条件是s->top==-1:
只需要定义一个布尔型变量,来判断栈顶元素top是否为-1即可,若top==-1则return(true),也就可以判断出这个栈为空;若top!=-1则return(false),也就可以判断出这个栈不为空。
(4)int StackLength(SqStack *s); //返回栈中元素个数——栈长度
直接进行top+1即可,只需要判断是否满栈就行。
(5)bool Push(SqStack *&s,ElemType e); //入栈
在栈不满的条件下,先将栈顶指针增1,然后由栈顶指针指向位置插入元素e:
在代码中,首先是if语句进行判断是否满栈,若满栈则return(false),则说明在定义的布尔型变量中,进栈操作无法进行,此时为栈上溢出,这是因为顺序栈的空间是有限的。如果栈不为满,则自然会进行下一步,s->top++,并且把当前位置s->top所对应的坐标中的数s->data赋值给e,此时进栈成功。
(6)bool Pop(SqStack *&s,ElemType &e); //出栈
在栈不空的条件下,先将栈顶指针元素赋值给e,然后将栈顶元素指针减1:
在代码中,首先是if语句进行判断是否为空栈,若空栈则return(false),则说明在定义的布尔型变量中,出栈操作无法进行,此时为栈下溢出。如果栈不为空,则自然会进行下一步,并且把e赋值给当前位置s->top所对应的坐标中的数s->data中,s->top--,此时出栈成功。
(7)bool GetTop(SqStack *s,ElemType &e); //取栈顶数据元素
在栈不为空的条件下,将栈顶元素赋值给e。
在代码中,首先是if语句进行判断是否为空栈,若空栈则return(false),则说明在定义的布尔型变量中,出栈操作无法进行,此时为栈下溢出。如果栈不为空,则不是栈下溢出,就直接把e赋值给当前位置s->top所对应的坐标中的数s->data中,即可。