版权声明:Andy https://blog.csdn.net/Alibaba_lhl/article/details/82857359
顺序栈
顺序栈是指利用顺序存储结构实现的栈,即利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素。
代码实现如下:
#include <iostream>
#include <stdio.h>
#include <malloc.h>
using namespace std;
typedef int SElemType;
typedef int Status;
#define INIT_SIZE 100
#define STACKINCREMENT 10
#define Ok 1
#define Error 0
#define True 1
#define False 0
typedef struct
{
SElemType *base;///栈底指针
SElemType *top;///栈顶指针
int stacksize;///栈可用的最大容量
}SqStack;
Status InitStack(SqStack *s)///初始化栈
{
s->base = (SElemType *)malloc(INIT_SIZE * sizeof(SElemType));///将顺序栈动态分配一个最大容量为INIT_SIZE的数组空间
if(!s->base)///存储分配失败
{
puts("存储空间分配失败!");
return Error;
}
s->top = s->base;///top初始为base,空栈
s->stacksize = INIT_SIZE;///stacksize置为栈的最大容量为INIT_SIZE
return Ok;
}
///if(base==NULL) 栈结构不存在
///栈非空时,top指向栈顶元素的上一位置
Status Push(SqStack *s, SElemType e)///压栈(插入元素e为新的栈顶元素)
{
if(s->top - s->base >= s->stacksize)///栈满
{
s->base = (SElemType *)realloc(s->base, (s->stacksize + STACKINCREMENT) * sizeof(SElemType));///改变栈的内存大小
if(!s->base)
{
puts("存储空间分配失败!");
return Error;
}
s->top = s->base + s->stacksize;///修改栈顶位置
s->stacksize += STACKINCREMENT;///修改栈长度
}
*s->top++ = e;
return Ok;
}
Status Pop(SqStack *s, SElemType *e)///弹栈
{///删除栈顶元素,用e返回其值
if(s->top == s->base) return Error;///栈空时,无法进行操作
--s->top;///栈顶指针减1
*e = *(s->top);///将栈顶元素赋给e
return Ok;
}
Status GetTop(SqStack *s, SElemType &e)///获得栈顶元素
{
if(s->top == s->base) return Error;///栈底指针和栈顶指针相同时,栈为空
e = *(s->top - 1);///栈非空时,top始终指向栈顶元素的上一个位置
return Ok;
}
Status visit(SElemType c)
{
printf("%d ",c);
return Ok;
}
Status StackTraverse(SqStack *s,Status(*visit)(SElemType))///遍历栈
{
SElemType *b = s->base;///此处不能直接用base或top移动,即不能改变原栈的结构
SElemType *t = s->top;
while(t > b)
{
visit(*b++);
}
printf("\n");
return Ok;
}
Status ClearStack(SqStack *s)///清空栈
{
s->top = s->base;
return Ok;
}
Status StackEmpty(SqStack *s)///栈是否为空
{
if(s->top == s->base) return True;///栈底指针和栈顶指针相同时,栈为空
else return False;
}
Status Destroy(SqStack *s)///销毁栈
{
free(s->base);
s->base = NULL;
s->top = NULL;
s->stacksize = 0;
return Ok;
}
int main()
{
cout<< "1. 进栈" << endl;
cout<< "2. 出栈" << endl;
cout<< "3. 取栈顶元素" << endl;
cout<< "4. 遍历栈" << endl;
cout<< "0. 退出" << endl << endl;
SqStack a;///定义一个栈,命名为a
SqStack *s = &a;///s为栈的指针
SElemType e;
InitStack(s);
int n;
puts("请输入要进栈的个数:");
scanf("%d", &n);
while(n--)
{
int m;
scanf("%d", &m);
Push(s, m);
}
int choose = -1;
while(choose != 0)
{
cout<< "请选择:";
cin>> choose;
switch(choose)
{
case 1:
{
cin>> e;
Push(s,e);
}
break;
case 2:
{
if(StackEmpty(s))
{
printf("该栈以空,无法进行该操作\n");
return 0;
}
Pop(s, &e);
printf("出栈的元素是:%d\n", e);
printf("元素出栈后事实上并没有清除,依然存在于内存空间,所谓的出栈只是指针移动,出栈的元素是%d\n\n", *s->top);
//判断出栈后元素是否还存在于内存中
}
break;
case 3:
{
if(StackEmpty(s))
{
printf("该栈以空,无法进行该操作\n");
return 0;
}
GetTop(s, e);
printf("栈顶元素为:%d\n\n",e);
}
break;
case 4:
{
StackTraverse(s, visit);///遍历该栈
puts("");
}
break;
}
}
Destroy(s);
return 0;
}
程序运行:
链栈
链栈是指采用链式存储结构实现的栈,通常用单链表来表示。
代码实现如下:
#include <bits/stdc++.h>
using namespace std;
#define OK 1
#define ERROR 0
typedef long long ll;
typedef unsigned long long ull;
typedef int SElemType;
typedef int Status;
typedef struct StackNode///链栈的存储结构
{
SElemType data;
struct StackNode *next;
}StackNode, *LinkStack;
Status InitStack(LinkStack &S)///链栈的初始化
{///构建一个空栈S,栈顶指针置空
S = NULL;///链栈的初始化操作就是构造一个空栈,因为没必要设头结点,所以直接将栈顶指针置空。
return OK;
}
Status Push(LinkStack &S, SElemType e)
{///在栈顶插入元素(将元素插入到首元结点)
LinkStack p;
p = new StackNode; ///生成新结点
p->data = e; ///将新结点指针插入栈顶
p->next = S; ///将新结点数据域插入栈顶
S = p; ///修改栈顶指针为p
return OK;
}
Status Pop(LinkStack &S, SElemType &e)
{///删除栈顶元素,用e返回其值
LinkStack p;
if(S==NULL) return ERROR;///栈空
e = S->data; ///将栈顶元素赋给e
p = S; ///用p临时保存栈顶元素空间
S = S->next; ///修改栈顶指针
delete p; ///释放原栈顶元素的空间
return OK;
}
Status GetTop(LinkStack S, SElemType &e)///取栈顶元素
{
if(S==NULL) return ERROR;///栈空
e = S->data;
return OK;
}
Status StackTraverse(LinkStack S)
{
LinkStack p;
if(S==NULL) return ERROR;
p = S;
while(p)
{
cout<< p->data << " ";
p = p->next;
}
cout<< endl;
return OK;
}
int main()
{
cout<< "1. 进栈" << endl;
cout<< "2. 出栈" << endl;
cout<< "3. 取栈顶元素" << endl;
cout<< "4. 遍历栈" << endl;
cout<< "0. 退出" << endl << endl;
LinkStack S;///定义一个栈,命名为a
SElemType e;
InitStack(S);
int n, m;
puts("请输入要进栈的个数:");
scanf("%d", &n);
while(n--)
{
int m;
scanf("%d", &m);
Push(S, m);
}
int choose = -1;
while(choose != 0)
{
cout<< "请选择:";
cin>> choose;
switch(choose)
{
case 1:
{
cin>> e;
Push(S,e);
}
break;
case 2:
{
if(S==NULL)
{
printf("该栈以空,无法进行该操作\n");
return 0;
}
Pop(S,e);
printf("出栈的元素是:%d\n", e);
printf("元素出栈后已经释放空间,出栈的元素是%d\n\n", e);
}
break;
case 3:
{
if(S==NULL)
{
printf("该栈以空,无法进行该操作\n");
return 0;
}
GetTop(S, e);
printf("栈顶元素为:%d\n\n",e);
}
break;
case 4:
{
StackTraverse(S);///遍历该栈
puts("");
}
break;
}
}
return 0;
}