数据结构C语言—线性表【栈】动态顺序栈(malloc动态分配实现)
SqStackMalloc.h
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
#define NOEXIST -1
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE 1
#define OVERFLOW 1
typedef int Status;
typedef int DataType;
typedef int *Pt;
typedef struct SqStack
{
Pt base;//指向栈底的指针
Pt top;//指向栈顶元素的下一个顺序位置
DataType sqstacksize;//栈已经分配得到空间的个数,可以存放一个元素的是一个空间
}SqStack,*SqStackElem;
Status InitStack(SqStackElem S);//初始化一个空动态顺序栈S,成功返回OK,否则返回ERROR
Status ClearStack(SqStackElem S);//清空一个动态顺序栈S,成功返回OK,否则返回ERROR,栈不存在(NOEXIST) ;栈顶指针等于栈底指针——空状态标志
Status DestoryStack(SqStackElem S);//销毁一个动态顺序栈S,将动态分配的数组释放掉,成功返回OK,否则返回ERROR;栈不存在(NOEXIST)
Status IsEmptyStack(SqStackElem S);//判断一个栈是否为空,是空(TRUE),不是空(FALSE),栈不存在(NOEXIST)
DataType StackLength(SqStackElem S);//返回栈S的元素个数,即栈长度,栈不存在(NOEXIST);不同于sqstacksize数目
Status GetTop_Stack(SqStackElem S,Pt e);//若栈不空,用*e返回栈S顶的元素,返回OK;若栈空(ERROR);栈不存在(NOEXIST)
Status Push_Stack(SqStackElem S,DataType e);//若栈存在,将e入栈,返回OK;栈不存在(NOEXIST)
Status Pop_Stack(SqStackElem S,Pt e);//若栈不空,将栈顶元素出栈,即删除栈顶元素,用*e返回其值,返回OK;若栈空(ERROR);栈不存在(NOEXIST)
Status StackTraverse(SqStackElem S,Status (*Visit)(SqStackElem S,DataType p));//栈不空,对每个元素调用Visist(),返回OK;若栈空(ERROR);栈不存在(NOEXIST)
Status Visit(SqStackElem S,DataType p);//遍历调用函数
SqStackMalloc.c
#include <stdio.h>
#include <stdlib.h>
#include "SqStackMalloc.h"
Status Visit(SqStackElem S,DataType p)
{
if(p==0)
{
printf("栈底指针----->%d:%d\n",p,(S->base)[p]);
}
else
{
printf(" %d:%d\n",p,(S->base)[p]);
}
return OK;
}
Status InitStack(SqStackElem S)//初始化一个空动态顺序栈S,成功返回OK,否则返回ERROR
{
S->base=(Pt)malloc(STACK_INIT_SIZE*sizeof(DataType));
if(S->base!=NULL)
{
puts("==========开始【初始化栈】操作!==========");
S->top=S->base;
S->sqstacksize=STACK_INIT_SIZE;//记录下已经获得数组元素的个数
puts("==========完成【初始化栈】操作!==========");
return OK;
}
puts("==========开始【初始化栈】操作!==========");
S->base=NULL;//若分配不成功,则让栈底指向NULL,作为栈不存在标志!
puts("==========失败【初始化栈】操作!==========");
return ERROR;
}
Status ClearStack(SqStackElem S)//清空一个动态顺序栈S,成功返回OK,否则返回ERROR,栈不存在(NOEXIST) ;栈顶指针等于栈底指针——空状态标志
{
if(S->base==NULL)//栈不存在标志
{
puts("\n==========栈不存在!不能执行【清空】操作!==========");
return NOEXIST;
}
puts("\n==========开始【清空】动态顺序栈S!==========");
S->top=S->base; //空栈标志
puts("\n==========【清空】动态顺序栈S完成!==========");
return OK;
}
Status DestoryStack(SqStackElem S)//销毁一个动态顺序栈S,将动态分配的数组释放掉,成功返回OK,否则返回ERROR;栈不存在(NOEXIST)
{
if(S->base==NULL)//栈不存在标志
{
puts("\n==========栈不存在!不能执行【销毁】操作!==========");
return NOEXIST;
}
puts("\n==========开始【销毁】动态顺序栈S!==========");
free(S->base);
S->base=NULL;
puts("\n==========【销毁】动态顺序栈S完成!==========");
return OK;
}
Status IsEmptyStack(SqStackElem S)//判断一个栈是否为空,是空(TRUE),不是空(FALSE),栈不存在(NOEXIST)
{
if(S->base==NULL)//栈不存在标志
{
puts("==========栈不存在!不能执行【判空】操作!==========");
return NOEXIST;
}
if(S->base==S->top)
{
return TRUE;
}
else
{
return FALSE;
}
}
DataType StackLength(SqStackElem S)//返回栈S的元素个数,即栈长度,栈不存在(NOEXIST)
{
if(S->base==NULL)//栈不存在标志
{
puts("==========栈不存在!不能执行【返回当前栈中存放元素个数】操作!==========");
return NOEXIST;
}
return S->top-S->base;
}
Status GetTop_Stack(SqStackElem S,Pt e)//若栈不空,用*e返回栈S顶的元素,返回OK;若栈空(ERROR);栈不存在(NOEXIST)
{
if(S->base==NULL)//栈不存在标志
{
*e=-6699;
puts("==========栈不存在!不能执行【返回栈顶元素】操作!==========");
return NOEXIST;
}
if(S->base==S->top)
{
*e=-6699;
puts("==========栈S为空!不能执行【返回栈顶元素】操作!==========");
return ERROR;
}
else
{
*e=(S->base)[StackLength(S)-1]; //或*e=*(S->top-1);
printf("当前动态顺序栈S中,栈顶元素是:%d\n",*e);
return OK;
}
}
Status Push_Stack(SqStackElem S,DataType e)//若栈存在,将e入栈,返回OK;若栈满,则增加空间后入栈,返回OK,分配失败返回ERROR;栈不存在(NOEXIST)
{
if(S->base==NULL)//栈不存在标志
{
puts("==========栈不存在!不能执行【入栈】操作!==========");
return NOEXIST;
}
if(StackLength(S)>=S->sqstacksize)//栈若满,则增加空间
{
S->base=(Pt)realloc(S->base,(S->sqstacksize+STACKINCREMENT)*sizeof(DataType));
if(S->base!=NULL)
{
S->top=S->base+S->sqstacksize;//更新栈顶指针位置
S->sqstacksize=S->sqstacksize+STACKINCREMENT;//更新当前已获得数组空间个数
(S->base)[StackLength(S)]=e;//入栈操作,或*S->top++=e;
S->top++; //top指针指向当前栈顶元素的下一个顺序位置
return OK;
}
else
{
return ERROR;
}
}
else
{
(S->base)[StackLength(S)]=e;//入栈操作,或*S->top++=e;
S->top++;//top指向栈顶元素的下一个顺序位置
return OK;
}
}
Status Pop_Stack(SqStackElem S,Pt e)//若栈不空,将栈顶元素出栈,即删除栈顶元素,用*e返回其值,返回OK;若栈空(ERROR);栈不存在(NOEXIST)
{
if(S->base==NULL)//栈不存在标志
{
*e=-6699;
puts("==========栈不存在!不能执行【出栈】操作!==========");
return NOEXIST;
}
if(S->base==S->top)
{
*e=-6699;
puts("==========栈空!不能执行【出栈】操作!==========");
return ERROR;
}
else
{
*e=(S->base)[StackLength(S)-1]; //或*e=*S->top--;
S->top--;
return OK;
}
}
Status StackTraverse(SqStackElem S,Status (*Visit)(SqStackElem,DataType))//栈不空,对每个元素调用Visit(),返回OK;若栈空(ERROR);栈不存在(NOEXIST)
{
if(S->base==NULL)//栈不存在标志
{
puts("\n==========栈不存在!不能执行【遍历】操作!==========");
return NOEXIST;
}
if(S->base==S->top)
{
puts("\n==========开始遍历检查动态顺序栈S==========");
printf("栈顶指针----->0:空<-----栈底指针");
puts("\n==========遍历检查动态顺序栈S完成==========");
return ERROR;
}
else
{
puts("==========开始遍历检查动态顺序栈S==========");
Pt p;
printf("栈顶指针----->%d\n",StackLength(S));
for(p=S->top;p-S->base-1!=-1;p--)
{
// printf("p-S->base-1=%d\n",p-S->base-1);
Visit(S,p-S->base-1);
}
puts("==========遍历检查动态顺序栈S完成==========");
return OK;
}
}
main.c
#include <stdio.h>
#include <stdlib.h>
#include "SqStackMalloc.h"
/* 线性表——顺序栈(动态分配)【自编代码】 */
int main()
{
SqStack S;
DataType e;
InitStack(&S);
puts("请按先后顺序,输入要入栈的元素(空格分隔,f结束):");
while(1)
{
int n,k;
k=scanf("%d",&n);
if(k==0)
{
break;
}
Push_Stack(&S,n);
}
StackTraverse(&S,Visit);
if(IsEmptyStack(&S))
{
puts("\n==========动态顺序栈S【是空栈】==========");
}
else
{
puts("\n==========动态顺序栈S【不是空栈】==========");
}
if(StackLength(&S)!=NOEXIST)
{
printf("当前动态顺序栈S中已存在元素个数是:%d!\n",StackLength(&S));
}
GetTop_Stack(&S,&e);
Pop_Stack(&S,&e);
if(e!=-6699)
{
printf("已经弹出栈顶元素:%d!\n",e);
}
StackTraverse(&S,Visit);
ClearStack(&S);
StackTraverse(&S,Visit);
if(IsEmptyStack(&S))
{
puts("\n==========动态顺序栈S【是空栈】==========");
}
else
{
puts("\n==========动态顺序栈S【不是空栈】==========");
}
fflush(stdin);
puts("请按先后顺序,输入要入栈的元素(空格分隔,f结束):");
while(1)
{
int n,k;
k=scanf("%d",&n);
if(k==0)
{
break;
}
Push_Stack(&S,n);
}
StackTraverse(&S,Visit);
DestoryStack(&S);
StackTraverse(&S,Visit);
IsEmptyStack(&S);
return 0;
}
运行结果示例
------------------------------------------------------第五次发文章有点激动啊!-----------------------------------------------------
-----------------------------------------------------【数据结构代码自编练习】------------------------------------------------------
----------------------------------------------------------------【TDTX】-----------------------------------------------------------------