栈的顺序储存结构实战讲解

    首先我们来学习栈的定义是什么:栈(stack)是限定仅在表尾进行插入和删除操作的线性表。 

    我们把允许插入和删除的一端称为栈顶(top),另一端称为栈低(bottom),不含任何数据元素的栈称为空栈。栈又称为后进先出(Last In First Out)的线性表,简称LIFO结构。

    学习栈要注意的一点是,这个叫做栈的线性表的表尾是指栈顶,而不是栈底。

    栈的插入操作叫作进栈、压栈或者入栈。

    栈的删除操作叫作出栈或者弹栈。

    栈的应用很广泛,比如说实现递归操作,进行四则表达式求值等等。

                                                 


    关于栈的结构定义和各种操作函数,我写了相关代码并用注释的方式进行了详细的讲解,具体请看以下代码:

#include <stdio.h>//我们要实现一个线性结构的栈,只需要引入stdio.h头文件用于打印显示验证就好了 

//下面是一堆我不说你也看得懂的宏定义 
#define OK 1
#define ERROR 0

#define MAXSIZE 5//为了方便,我定义这个栈的最大容量为5 

#define BOOL int
#define TRUE 1
#define FALSE 0

typedef int SElemType;// SElemType类型根据实际情况而定,这里我们假设其为int 
typedef int Status;//用作返回函数的执行状态,成功返回OK(1),失败返回(0) 

typedef struct//这是栈的结构定义,包含两个成员,一是用了储存栈的数组,二是代表栈顶指针的top 
{
	SElemType data[MAXSIZE];
	int top;
}SqStack;

//一堆函数声明,具体意义和实现方法我会在下面讲 
Status Push(SqStack *S,SElemType e);
Status Pop(SqStack *S, SElemType *e);
void InitStack(SqStack *S);
void PrintStack(SqStack *S);
void ClearStack(SqStack *S);
BOOL StackEmpty(SqStack *S);
Status GetTop(SqStack *S,SElemType *e);
int StackLength(SqStack *S);

int main(int argc, char *argv[]) {
	SElemType temp;//定义一个临时变量,用于返回元素值 
	SqStack S1;//声明一个栈S1 
	SqStack *s1=&S1;//为了方便,我们定义一个指向栈的指针s1 
	
	InitStack(s1);//现在我们初始化这个栈 
	PrintStack(s1);//由于此时栈为空,因此会打印出来一个NULL
	
	//现在我们来进行压栈操作,因为栈的最大容量为5,因此在第六次操作时会返回一个ERROR,同时压栈失败 
	if(Push(s1,1)==ERROR) printf("ERROR\n");
	if(Push(s1,2)==ERROR) printf("ERROR\n");
	if(Push(s1,3)==ERROR) printf("ERROR\n");
	if(Push(s1,4)==ERROR) printf("ERROR\n");
	if(Push(s1,5)==ERROR) printf("ERROR\n");
	if(Push(s1,6)==ERROR) printf("ERROR\n");
	
	//打印一下看看,是不是上面所压栈的数字1~5 
	PrintStack(s1);
	
	//我们现在再来试一下弹栈操作,同时打印出弹出的元素,如果栈为空,那么会弹栈失败并打印出一个ERROR 
	if(Pop(s1, &temp)) printf("%d\n",temp);
	else printf("ERROR\n");
	if(Pop(s1, &temp)) printf("%d\n",temp);
	else printf("ERROR\n");
	if(Pop(s1, &temp)) printf("%d\n",temp);
	else printf("ERROR\n");
	if(Pop(s1, &temp)) printf("%d\n",temp);
	else printf("ERROR\n");
	if(Pop(s1, &temp)) printf("%d\n",temp);
	else printf("ERROR\n");
	if(Pop(s1, &temp)) printf("%d\n",temp);//果然第六次弹栈不会成功的 
	else printf("ERROR\n");
	
	//我们再来重新压进三个元素,用于验证其它操作 
	if(Push(s1,10)==ERROR) printf("ERROR\n");
	if(Push(s1,11)==ERROR) printf("ERROR\n");
	if(Push(s1,12)==ERROR) printf("ERROR\n");
	
	printf("StackLength:%d\n",StackLength(s1));//打印一下栈的长度,没错果然是3 
	
	if(GetTop(s1, &temp)) printf("%d\n",temp);//我们来返回一下栈顶元素并打印,与弹栈不同的是不会将栈顶元素弹出 
	else printf("ERROR\n");
	
	if(StackEmpty(s1)) printf("Empty\n");//测试栈是否为空,因为栈中还有三个元素,此处打印出了Not Empty 
	else printf("Not Empty\n");
	
	ClearStack(s1);//现在我们清空这个栈 
	
	if(StackEmpty(s1)) printf("Empty\n");//果然清空后这个栈又重新变成了空的 
	else printf("Not Empty\n");
	
	return 0;
}

//若栈S存在,插入新元素e到栈S中并成为栈顶元素 
Status Push(SqStack *S, SElemType e)
{
	if(S->top == MAXSIZE-1)//如果栈满了,返回ERROR 
	{
		return ERROR;
	}
	
	S->top++;//栈顶指针增加一 
	
	S->data[S->top]=e;//将新插入元素赋值给栈顶空间 
	
	return OK;
}

//弹出栈S中的栈顶元素,并用e返回其值 
Status Pop(SqStack *S, SElemType *e)
{
	if(S->top == -1)//如果栈为空,则返回ERROR 
	{
		return  ERROR;
	}
	
	*e=S->data[S->top];//将弹出的栈顶元素赋值给e 
	
	S->top--;//栈顶指针减一 
	
	return OK;
}

//初始化栈S的空间,创建一个空栈 
void InitStack(SqStack *S)
{
	int i;
	
	S->top=-1;//栈顶指针指向-1表示栈为空 
	
	for(i=0;i<MAXSIZE;i++)//将栈中元素用0进行初始化 
	{
		S->data[i]=0;
	}
}

//打印栈S中的所有元素,用于验证各项操作是否成功 
void PrintStack(SqStack *S)
{
	int i;
	
	if(S->top == -1)//如果栈为空,打印NULL并返回 
	{
		printf("NULL\n");
		return;
	}
	
	for(i=0;i<=S->top;i++)//栈不为空则打印所有元素 
	{
		printf("%d ",S->data[i]);
	}
	printf("\n");
}

//将栈S清空 
void ClearStack(SqStack *S)
{
	int i;
	
	S->top=-1;//将栈顶指针指向-1表示栈为空 
	
	for(i=0;i<MAXSIZE;i++)//用0初始化栈空间 
	{
		S->data[i]=0;
	}
}

//测试栈S是否为空 
BOOL StackEmpty(SqStack *S)
{
	if(S->top==-1)//若栈为空,返回TRUE 
	{
		return TRUE;
	}
	
	else//若不为空则返回FALSE 
	{
		return FALSE;
	}
}

//若栈S存在且非空,用e返回S的栈顶元素 
Status GetTop(SqStack *S,SElemType *e)
{
	if(S->top==-1)//若栈为空,返回ERROR 
	{
		return ERROR;
	}
	
	*e=S->data[S->top];//把栈顶元素的值赋值给e 
	
	return OK;
}

//返回栈S的元素个数 
int StackLength(SqStack *S)
{
	return S->top+1;//因为数组的下标是从0开始的,所以要返回栈顶指针的值加一后的结果。	
}
    谢谢阅读,图片来源于网络,侵删
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值