栈的动态分配相关功能的实现

栈的动态分配

静态和动态具有很高的相似性,所有的逻辑是一致的这里就不在叙述

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);//输出栈数据
}

猜你喜欢

转载自blog.csdn.net/qq_46861651/article/details/113038425