数据结构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】-----------------------------------------------------------------

posted @ 2021-11-23 13:52  TDTX  阅读(141)  评论(0编辑  收藏  举报