#include<iostream>
using namespace std;
#include<stdlib.h>
#define OK 1
#define ERROR 0
#define STACK_INIT_SIZE 100 //设置一个变量,到时候创建栈的时候,直接把栈的容量定义为这个大小。
#define STACKINCREMENT 10 //栈的增量(万一栈的长度不够,增加的长度)
typedef int status;
typedef int SElemType;
typedef struct //用struct定义栈类型,其实就三个东西,一个栈顶指针,一个栈尾指针,还有一个栈的容量
{
SElemType *base; //栈底指针
SElemType *top; //栈顶指针
SElemType stacksize; //栈的容量
}SqStack; //栈类型定义完毕,别名为SqStack
//初始化栈
status InitStack(SqStack &S)
{
S.base = (SElemType *)malloc(sizeof(SElemType)*STACK_INIT_SIZE); //malloc函数分配存储空间,你栈中准备存放什么数据就用什么类型的指针指向这片存储空间,并把栈尾指针也指向这片空间。
if(!S.base) //判断是否分配成功
{
return ERROR;
}
S.top = S.base; //将栈顶指针与栈底指针指向同一位置 - > 在栈中没有放入元素的时候,我们将栈尾指针与栈顶指针指向同一位置代表此时栈为空
S.stacksize = STACK_INIT_SIZE; //把栈的容量设置为我们提前定义好的变量。
return OK;
}
//栈的销毁
status DestroyStack(SqStack &S) //free函数直接释放,把长度变为0,值得注意的是,我们释放完成后,要把base指针与top指针都赋值为NULL,
{ //因为空间被释放,如果不释放原来的指针,那么可能会成为野指针。
free(S.base); //释放空间,让空间回归内存
S.stacksize = 0; //把长度设置为0
S.base = NULL; //之前分配的空间已经不存在,要把之前的指针赋值为NULL
S.top = NULL;
cout <<"栈已经销毁。"<<endl;
return OK;
}
//入栈操作
status Push(SqStack &S,SElemType e) //在往栈里放入元素之前,我们应该考虑一件事情,就是现在栈里面还有没有位置来接收新的元素,
//即我们要判断,栈顶指针与栈尾指针之间元素的数量是不是已经超过了我们预先设置的最大容量。
{
if(S.top - S.base >= S.stacksize) //达到这个条件,栈已经满了
{
S.base = (SElemType *)realloc(S.base,(S.stacksize + STACKINCREMENT)*sizeof(SElemType));
if(!S.base) //同样进行判断是否成功分配
{
return ERROR;
}
S.top = S.base + S.stacksize; //这里是分配成功进行的操作,栈顶指针指向新的位置,栈的容量也发生变化
S.stacksize += STACKINCREMENT; //因为分配了更多的空间,栈的长度相应的也会增加。
}
//如果栈的长度够用的话,那么我直接把要入栈的元素放在栈顶指针的地方,同时栈顶指针上移
*S.top = e;
S.top++;
return OK;
}
//元素出栈
status Pop(SqStack &S,SElemType &e) //出栈的时候,我们要考虑一种情况---假溢出--即栈中没有元素,这个时候就不能出栈。
{
if(S.top == S.base) //这个时候,栈里面没有元素,不能进行元素出栈的操作
{
return ERROR;
}
--S.top; //如果栈中有元素,那么我们直接让栈顶指针下移,然后用变量e带出栈顶元素。其实这个时候,我们那个栈顶元素还在原来那个地方,
e = *S.top; //但是我们默认,这个元素已经出栈了,因为我的栈顶指针已经下移了。这个在后面清空栈道理一样,我只需要把栈顶指针与栈尾指针指向同一个地方,即使你之前的元素还在原位置
return OK; //但是我默认,我的栈已经清空了
}
//栈的输入
status CinSack(SqStack &S,int n) //往栈S里面输入n个元素
{
cout<<"请输入栈的元素:"<<endl;
int e;
for(int i = 0; i < n;i++)
{
cin>>e; //每输入一个元素,调用一下入栈操作。
Push(S,e);
}
return OK;
}
//栈的元素获取
status GetElem(SqStack S,SElemType &e)
{
if(S.base = S.top) //栈此时为空,无法获取元素
{
return ERROR;
}
e = *(S.top - 1); //我们的栈顶指针的位置是在栈顶元素的上一个位置(为了便于操作)
return OK; //所以我们获取栈顶元素的时候,先让栈顶指针下移,再对栈顶指针解引用得到栈顶元素。
}
//栈的清空
status ClearStack(SqStack &S)
{
S.top = S.base; //栈的清空操作,只需要把栈顶指针指向栈底指针的位置,长度清零就行。不必考虑之前存放的数据问题,下一次输入新的数据时会覆盖掉。
S.stacksize = 0;
cout<<"栈已经清空:"<<endl;
return OK;
}
int main()
{
SqStack S;int n;SElemType e;
InitStack(S);
cout<<"请输入栈的长度:"<<endl;
cin>>n;
CinSack(S,n);
cout<<"请输入要插入的数:"<<endl;
cin>>e;
Push(S,e);
GetElem(S,e);
cout<<"此时栈顶元素为:"<<e<<endl;
for(int i=0;i<2;i++)
{
Pop(S,e);
cout<<"删除的元素为:"<<e<<endl;
}
ClearStack(S);
DestroyStack(S);
return OK;
}
栈的基本操作
最新推荐文章于 2024-07-12 18:56:03 发布