堆栈的操作其实还好,比较简单,但是吧,一些算法涉及非递归算法,就需要它;当然,计算一串数学表达式的值,或者字符回文判断,都是会用到的,下面介绍一下用比较简单的链栈实现的堆栈基本操作吧!
一、首先定义堆栈的存储结构及基本操作原型(头文件)
不多说,直接上代码,代码风格如果不好,希望多指点!毕竟新手哈!
#ifndef usr_stack.h
#define usr_stack.h
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
//堆栈的链栈表示--栈结点
typedef struct SNode
{
char ch; //堆栈结点保存的数据
struct Node *next; //指向下一个链栈结点的指针
}SNode;
//堆栈的链栈表示--栈元素
typedef struct
{
SNode *top; //栈顶指针
SNode *base; //栈底指针
int stacksize; //栈当前大小
}SqStack;
//-------基本操作函数原型说明
int InitStack(SqStack **S);
//构造一个空栈
int DestroyStack(SqStack *S);
//销毁栈,栈S不在存在
int ClearStack(SqStack *S);
//将栈置空
int StackEmpty(SqStack *S);
//是空栈则返回1,否则为0
int StackLength(SqStack *S);
//返回栈的长度
int GetTop(SqStack *S, SNode *e);
//用e返回堆栈的顶指针
int Push(SqStack *S, char c);
//插入元素e为新的栈顶元素
int Pop(SqStack *S, SNode *e);
//若栈不空,则删除栈顶元素,用e返回其值,并返回OK,否则返回ERROR
int StackTraverse(SqStack *S, void (* visitSNode)(SNode *));
//从栈底到栈顶依次调用visit函数,一旦visit失败,则操作失败
void visitSNode(SNode *e);
//打印栈结点数据
#endif //usr_stack.h
二、函数实现
1、第一步当然是初始化我们的链栈,我们应该使用双重指针,更方便一点,具体道理,再往后有时间会再发博文的!
/*
**函数功能:初始化栈
*/
int InitStack(SqStack **S)
{
//构造一个空的堆栈
SNode *pnode;
if( (*S = (SqStack *)malloc(sizeof(SqStack))) == NULL)
exit(-1);
if( (pnode = (SNode *)malloc(sizeof(SNode))) == NULL)
exit(-1);
pnode->next = NULL;
(*S)->top = pnode;
(*S)->base = pnode;
(*S)->stacksize = 0;
return OK;
}//InitStack
2、压栈操作
/*
**函数功能:插入元素e为新的栈顶
*/
int Push(SqStack *S, char c)
{
SNode *pnode;
if((pnode = (SNode *)malloc(sizeof(SNode)))== NULL)
exit(-1);
pnode->ch = c;//e->ch;
pnode->next = S->top;
S->top = pnode;
++(S->stacksize);
return OK;
}//Push
/*
**函数功能:若栈非空,则退栈,用e返回其值,并返回1;否则返回0
*/
int Pop(SqStack *S, SNode *e)
{
if(S->base == S->top) return FALSE; //栈空
SNode *pnode;
pnode = S->top; //临时存放栈顶
e->ch = pnode->ch; //返回栈顶
e->next = pnode->next;
S->top = pnode->next;
free(pnode);
--(S->stacksize);
return OK;
}//Pop
以上就是基于链栈的堆栈的介绍,代码实现比较简单,如果是顺序存储结构就会比较麻烦,后面再说吧,不过用的顺手,就保持简单吧!