/*
*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中,即可。