系列文章传送门:
数据结构与算法之树和二叉树(一):二叉树基本操作的实现及应用
数据结构与算法之线性表(二):链式表的实现和应用
数据结构与算法之线性表(三):顺序栈的实现和应用
数据结构与算法之线性表(四):链式栈的实现和应用
数据结构与算法之线性表(五):链式队列的实现和应用
数据结构与算法之线性表(六):顺序队列及循环队列的实现和应用
一.链式栈基本操作实现(所有代码均在Embarcadero DevC++6.0和VSCode 2021上编译运行通过)
#include<stdio.h>
#include<stdlib.h>
#define SElemType int
#define Status int
#define OVERFLOW -1
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
//链式栈类型
typedef struct SNode
{
SElemType data;//数据域
struct SNode *next;//指针域
}SNode, *LinkStack;
Status StackEmpty(LinkStack S)
{
if(S->next==NULL) //因链栈中没有头结点,故至少有一个结点
return OK;
else
return FALSE;
}
Status DestroyStack(LinkStack &S) //摧毁:最后什么都不剩
{
LinkStack p = (LinkStack)malloc(sizeof(SNode));
while (S)
{
p = S;
S = S->next;
free(p);
}
free(S); //最后剩下个S空指针,顺带回收
return OK;
}
Status ClearStack(LinkStack &S)
{
LinkStack p = (LinkStack)malloc(sizeof(SNode));
while (S)
{
p = S;
S = S->next; //清空:最后只剩下S一个空指针
free(p);
}
return OK;
}
Status GetTop(LinkStack S,SElemType &e)
{
e = S->data; //申请号的栈不可能为空,故栈顶一定存在
return OK;
}
int StackLength(LinkStack &S)
{
LinkStack p = (LinkStack)malloc(sizeof(SNode));
p = S->next;
int count = 1;
while (p)
{
count++;
p = p->next;
}
return count;
}
Status InitStack(LinkStack &S)
{
S = (LinkStack)malloc(sizeof(SNode));
S = NULL;
return OK;
}
Status Push(LinkStack &S, SElemType e)
{
LinkStack p = (LinkStack)malloc(sizeof(SNode)); //即用即申
if(!p)
exit(OVERFLOW);
p->next = S;
p->data = e;
S = p;
return OK;
}
Status Pop(LinkStack &S, SElemType &e)
{
if(!S)//若栈空
return ERROR;
LinkStack p = (LinkStack)malloc(sizeof(SNode)); //即用即申
if(!p)
exit(OVERFLOW);
p = S;
S = S->next;
e = p->data;
free(p);
return OK;
}
Status StackTraverse(LinkStack S, Status (*visit)(SElemType)) //函数指针:指向返回值为Status类型的函数
{
LinkStack p = (LinkStack)malloc(sizeof(SNode));
p = S;
while (p)
{
if(!visit(p->data))
return FALSE;
p = p->next;
}
return OK;
}
Status print(SElemType e)
{
printf("%d->",e);
return OK;
}
int main(int argc, char const *argv[])
{
SElemType e;
LinkStack S;
InitStack(S);
for (int i = 0; i < 10; i++)
{
Push(S,i);
}
Pop(S,e);
StackTraverse(S,print); //将函数地址作为参数
return 0;
}