栈的动态分配
静态和动态具有很高的相似性,所有的逻辑是一致的这里就不在叙述
1>定义结构体和声明栈
为栈分配空间时不在使用计算机内部默认连续的地址空间,使用malloc函数开辟地址内存空间,和静态分配地址空间的基本操作是相同的。在结构体中定义的变量不同,在动态分配中只定义了栈顶和栈底指针
#include<stdio.h>
#include<stdlib.h>
#define MaxSize 5
typedef struct SqStack
{
int *top;//栈顶指针
int *base;//栈底指针
}SqStack;//typedef重命名为SqStack
void main()
{
SqStack S;//声明一个栈
}
2>初始化栈
使用malloc函数分配内存空间,将基地址指向空间的首地址。初始化后栈顶和栈底是一致的,所以将栈顶初始化为栈底
void InitStack(SqStack &S)
{
S.base = (int*)malloc(sizeof(int)*MaxSize);//为栈分配内存空间,不是连续的地址空间
if (!S.base)//为空输出提示
printf("抱歉内存分配失败!");
else
printf("内存分配完成,初始化成功!\n");
S.top = S.base;//初始栈栈顶等价于栈底,讲栈顶初始化为栈底
}
这样栈初始化完成,同时基地址也指向了开辟空间的首地址(也就是栈底)
3>添加数据
输入数据如果输入数据数量n:
n>maxsize 则输入是不能完成全部是输入
n<maxsize 可以完成所有输入
这里使用两种输入是可以更好理解栈输入过程中内存空间的可用度:
更好的简洁的方式可以(s.top-s.base==maxsize)判断空间是否满 *(s.top)++=e;先将数据压入栈然后指针移动位置,这样可以节省很多代码。上述方法便于理解
void CreatStack(SqStack &S,int n)
{
int data;//保存数据
printf("向栈中添加%d个数据:\n", n);
if (n <= MaxSize)
{
for (int i = 0; i < n ; i++)
{
printf("data[%d]=", i);
scanf("%d", &data);
*S.top++ = data;//先赋值后移动位置
}
}
else
{
for (int i = 0; i < MaxSize ; i++)
{
printf("data[%d]=", i);
scanf("%d", &data);
*S.top++= data;//先赋值后自增位置
}
printf("剩余%d元素无法入栈!\n",n-MaxSize);
}
}
输入数据数量小于开辟的内存空间
输入数据数量大于开辟的内存空间
4>输出数据
在输入中在完成最后一个数据是输入过程中,是先赋值给地址空间然后指针后移动。所以在输入数据结束后,指针其实在栈顶的上方(在输入数据是可以修改到栈顶这里就没有修改),在输出是数据前进行指针前移
void ShowStack(SqStack S)//打印
{
printf("打印栈数据:\n");
int i = 0;
while (S.top != S.base)
{
S.top--;//从栈顶向下移动
printf("data[%d]=%d\n", i, *S.top);
i++;
}
}
输入数据空间小于开辟空间:
输入数据空间大于开辟空间
5>插入数据到栈顶
插入数据到栈顶需要判断栈的空间是否充足,只有具备剩余空间条件下才可以插入。由于在输入数据中末数据输入后指针以及在节点的上方,所以插入栈顶时先赋值后移动指针
void PushStack(SqStack &S, int e)//将元素入栈
{
if (S.top - S.base ==MaxSize)
printf("当前栈已满!\n");
*S.top++ = e;//赋值后移动节点到下一处
}
向栈顶插入数据
6>删除栈顶元素
同理由于在输入数据中末数据输入后指针以及在节点的上方,所以删除栈顶时先移动指针后赋值
void PopStack(SqStack &S)//元素出栈
{
int e=*(S.top--);//保存栈顶数据
printf("删除栈顶元素%d\n",e);
}
先插入然后立即删除
常规输入删除栈顶元素
7>获取栈顶元素
由于在输入数据时末数据指针的位置,所以和删除栈顶一样先移动指针后获取数据。
void GetElemStack(SqStack S)//得到栈顶元素
{
S.top--;
int e = *S.top;
printf("栈顶元素为%d\n", e);
}
8>整体代码
#include<stdio.h>
#include<stdlib.h>
#define MaxSize 5
typedef struct SqStack
{
int *top;//栈顶指针
int *base;//栈底指针
}SqStack;//typedef重命名为SqStack
void InitStack(SqStack &S)
{
S.base = (int*)malloc(sizeof(int)*MaxSize);//为栈分配内存空间,不是连续的地址空间
if (!S.base)//为空输出提示
printf("抱歉内存分配失败!");
else
printf("内存分配完成,初始化成功!\n");
S.top = S.base;//初始栈栈顶等价于栈底,讲栈顶初始化为栈底
}
void EmptyStack(SqStack S)
{
if (S.top==S.base)
printf("当前为空栈!\n");
else
printf("当前栈不为空栈!\n");
}
void CreatStack(SqStack &S,int n)
{
int data;//保存数据
printf("向栈中添加%d个数据:\n", n);
if (n <= MaxSize)
{
for (int i = 0; i < n ; i++)
{
printf("data[%d]=", i);
scanf("%d", &data);
*S.top++ = data;//先赋值后移动位置
}
}
else
{
for (int i = 0; i < MaxSize ; i++)
{
printf("data[%d]=", i);
scanf("%d", &data);
*S.top++= data;//先赋值后自增位置
}
printf("剩余%d元素无法入栈!\n",n-MaxSize);
}
}
void PushStack(SqStack &S, int e)//将元素入栈
{
if (S.top - S.base ==MaxSize)
printf("当前栈已满!\n");
*S.top++ = e;//赋值后移动节点到下一处
}
void PopStack(SqStack &S)//元素出栈
{
int e=*(S.top--);//保存栈顶数据
printf("删除栈顶元素%d\n",e);
}
void GetElemStack(SqStack S)//得到栈顶元素
{
S.top--;
int e = *S.top;
printf("栈顶元素为%d\n", e);
}
void ShowStack(SqStack S)//打印
{
printf("打印栈数据:\n");
int i = 0;
while (S.top != S.base)
{
S.top--;//从栈顶向下移动
printf("data[%d]=%d\n", i, *S.top);
i++;
}
}
void main()
{
SqStack S;//声明一个栈
InitStack(S);//初始化
EmptyStack(S);//判断是否空栈
CreatStack(S,4);//添加数据
PushStack(S,99);//将元素插入到栈顶
PopStack(S);//将栈顶数据删除
GetElemStack(S);//得到栈顶元素
ShowStack(S);//输出栈数据
}