上周学习的数据结构中关于栈,有下面几点,我感觉引起我的重视。
- 栈的基本操作中,基本上都是在栈顶进行的。比如在栈顶的插入,删除,栈的初始化,栈的判空(S.base == S.top),取栈顶元素等等。所以关于top指针要引起足够的重视和理解。
- 理解栈和基本线性表的之间的关系。首先,栈就是线性表,栈是一种操作受限的线性表。可以想想就是带着镣铐跳舞的感觉,所以实现的时候必须严格按照栈的定义来执行栈的操作。
- 栈不存在的条件:base = null;
- 栈为空的条件:base = top;
- 栈满的条件:top – base = stacksize;
下面是我上周做得实验中的关于顺序栈的部分算法的实现。链式栈的实现,在后续中还会贴出来。一个小实验贴出来,分享一下,共同进步。
实验环境:dev-c++5
定义的头文件SqStack.h。主要完成一些
宏命令的定义, 自定义类型的定义 和 函数的声明
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define STACK_INIT_SIZE 100 //存储空间初始分配量
#define STACKINCREMENT 10 //存储空间增量
typedef int Status;
typedef int SElemType;
typedef struct
{
SElemType *base;//栈底指针
SElemType *top; //栈顶指针
int stacksize; //当前已经分配的空间,以元素为单位
}SqStack;
Status InitStack(SqStack *S); //构造一个空栈
Status Push(SqStack *s,SElemType e); //压栈操作
Status Pop (SqStack *s,SElemType *e); //出栈操作
文件SqStack.c 完成顺序表中的部分基本操作函数的定义。
#include "SqStack.h"
#include
#include
Status InitStack(SqStack *S)
{
S->base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(!S->base) exit(OVERFLOW);
S->top = S->base;
S->stacksize = STACK_INIT_SIZE;
return OK;
}//InitStack
Status Push(SqStack *S,SElemType e)
{
if(S->top - S->base>=S->stacksize)
{
S->base = (SElemType*)realloc(S->base,(S->stacksize+STACKINCREMENT)*
sizeof(SElemType));
if(!S->base) exit(OVERFLOW);
S->top = S->base + S->stacksize;
S->stacksize += STACKINCREMENT;
}
*(S->top++) = e; //加一句老师讲的入栈口诀:“先压后加”,
//可以看到元素先压入栈中,然后栈顶指针指向栈顶元素的下一个位置
return OK;
}//Push
Status Pop(SqStack *S,SElemType *e)
{
if(S->top == S->base) return ERROR;
*e = *(--S->top); //出栈口诀:“先减后弹”
//可以看到栈顶指针先执行--操作,保证栈顶指针指向栈顶元素,然后弹出栈
return OK;
}//Pop
main.c文件,测试用的主函数,这个文件借鉴了上课是老师讲的利用函数返回的状态参量来作为循环终止的判断条件。
include
#include
#include "SqStack.h"
int main(int argc, char *argv[])
{
int i ;
SqStack S ;
InitStack(&S);//构造一个空栈
for(i=0;i<10; i++)
Push(&S,i);//压栈操作,压入10个元素 0,1,2,3.....9;
while(1)
{
SElemType e;
if( Pop(&S,&e)==ERROR)//出栈操作,10个元素全部出栈,
break; //可以看到通过判断Pop返回值的状态,来终止循环的执行
printf("%d\n",e);
}
system("PAUSE");
return 0;
}