数据结构基础——栈

什么是栈

关于栈,在 如何使用两个栈实现一个队列 中粗略介绍过,下面将详细接受栈以及栈代码的实现。

符合 先进后出,后进先出!——函数调用堆栈,类似于弹匣的结构。

栈底: 栈的存储空间的最底下的位置。一般是一块空间的首地址。

栈顶: 动态变化的位置,会随着入栈和出栈操作在申请的空间上左右滑动。

栈大小: 记录总共能够存储的数据元素的个数。
在这里插入图片描述

栈的代码实现

顺序栈的结构

typedef  int  ElemType;

typedef  struct Stack
{
    ElemType    *stack_low;  //  栈底指针,存储空间的首地址
    int           top;       //   栈顶(使用下标来表示), 元素的个数
    int           size;      //  栈空间的大小
}Stack;

顺序栈的操作方法

void   InitStack(Stack *st,  int init_size);  //  初始化

bool   Push(Stack  *st,  ElemType  data);   //  入栈

bool    Top(Stack  *st,  ElemType  *reval);  //  仅仅获取栈顶的数据

bool    Pop(Stack  *st);   //  出栈,  仅仅弹出栈顶的数据

bool    Empty(Stack  *st);  //  判空

void    DestroyStack(Stack *st);  //  销毁

方法的实现

InitStack__栈的初始化

void InitStack(Stack *st, int init_size)
{
	if(st == NULL)  exit(0);

	init_size = init_size > 0 ? init_size : 10;

	st->stack_low =  (ElemType*)malloc(sizeof(ElemType) * init_size);
	//分配空间给栈使用
	if(st->stack_low == NULL)  exit(0);

	st->top = 0;//栈顶为0,此时栈为空
	st->size = init_size;
}

在这里插入图片描述

Push__入栈

其中调用了:判满函数,以及给栈增加空间函数

bool  Push(Stack *st, ElemType value)
{
	if(st == NULL) exit(0);

	if(Full(st))
	{
		if(!AppendSpace(st))
		{
			return false;
		}
	}

	st->stack_low[st->top++] = value;
	//例如下图,向空栈中入栈a,则st->stack_low[0] = value
	//而 st->top 正好为需要放入空间的下标 同时令top++ 就实现入栈
	//则st->stack_low[0]中存放了a,而 tou == 1.
	return true;
}

在这里插入图片描述

Full__判满

static bool Full(Stack *st)
{
	return st->top == st->size;
	//当top的下标等于size时 栈满
}

当栈满,top指向的下标大小 正好为 size 的大小
在这里插入图片描述

AppendSpace__增加空间

static bool AppendSpace(Stack *st)
{
	ElemType *new_space = (ElemType*)malloc(sizeof(ElemType) * st->size * 2);
	//申请双倍空间的 new_space
	if(new_space == NULL) return false;

	for(int i = 0; i < st->size; ++i)
	{
		new_space[i] = st->stack_low[i];
	}//将原本的入栈数据放入new_space
	
	free(st->stack_low);//释放原本的栈
	st->stack_low = new_space;//指针指向新栈的地址
	st->size *= 2;//size * 2 

	return true;
}

Top__获取栈顶数据

这里调用了:判空函数

bool Top(Stack *st, ElemType *reval)
{
	if(st == NULL) exit(0);

	if(Empty(st)) return false;
	
	*reval = st->stack_low[st->top - 1];//给 *reval 赋值栈顶元素
	return true;
}

Pop__弹出栈顶数据

bool  Pop(Stack *st)
{
	if(st == NULL)  exit(0);

	if(Empty(st)) return false;

	st->top--;//判空后之间令top--,即使得原本栈最后一个数据变为栈顶(top)
	return true;
}

这个时候栈内只有 a,b,c,d 四个数据,尽管stack_low[4]存放着d,但是不将它视为栈内数据。
在这里插入图片描述

Empty__判空

bool  Empty(Stack *st)
{
	if(st == NULL) exit(0);

	return st->top == 0;//查看top是否为0即可
}

DestryStack__销毁栈

void DestroyStack(Stack *st)
{
	if(st == NULL) exit(0);

	free(st->stack_low);//直接释放顺序表空间
	st->stack_low = NULL;
	st->top = st->size  = 0;
	//清空数据即可
}

链式栈的实现

和链表的操作完全一样,除了初始化,销毁,判空, 头插(Push),头删(Pop)等方法。

栈的应用

中缀转后缀

中缀转后缀

两个栈实现一个队列

如何用两个栈实现一个队列

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值