数据结构——堆栈

概念

为什么使用堆栈?

用计算机进行表达式的求值时。

我们知道,算术表达式由两类对象构成:运算数和运算符号,但不同运算符的优先级不同。

对计算机来说,我们引入后缀表达式,比如abc*+de/-,我们平常所用的是中缀表示式,就是a+b*c-d/e,和前面的式子是一个意思。注意后缀的符号运算是从右向左的。

因此可以联想到“栈”,先放进去的数据,后拿出来。用一个表达式来理解:6 2 / 3 - 4 2 * + = ?首先在栈中依次放入6,2,遇到运算符“/”,出栈,依次拿出来2,6,进行运算得到结果3,放进栈中,再放入下一个数据3,遇到运算符“-”,再出栈,重复类似这样的过程。

复杂度是线性的,T(n)=O(n)。

堆栈的抽象数据类型描述:

是具有一定操作约束的线性表,只在一端(栈顶(Top)做插入(入栈push)、删除(出栈pop)

堆栈:Stack

操作集:长度为MaxSize的堆栈S,堆栈元素item属于ElementType

主要函数:

Stack CreateStack(int MaxSize);//生成空的堆栈,它的最大长度为Maxsize 
int IsFull(Stack S,int MaxSize);//判断堆栈S是否已满 
void Push(Stack S,ElementType item);//将元素item压入堆栈 
int IsEmpty(Stack S);//判断堆栈S是否为空 
ElementType Pop(Stack S);//删除并返回栈顶元素 

栈的顺序存储实现

通常由一个一维数组(存储栈的元素)和一个记录栈顶元素(栈顶指针) 位置的变量组成。

#define MaxSize//储存数据元素的最大个数
typedef struct SNode *Stack;
struct SNode
{
	ElementType Data[MaxSize];
	int Top;
};

入栈和出栈的模板如下: 

//入栈
void Push(Stack PtrS,ElementType item)
{
	if(PtrS->Top==Maxsize-1)
	{
		cout<<"堆栈满";
		return; 
	}else 
	{
		PtrS->Data[++(PtrS->Top)]=item;
		return;
	}
} 

//出栈
ElemenType Pop(Stack PtrS)
{
	if(PtrS->Top==-1)
	{
		cout<<"堆栈空";
		return ERROR; 
	}else 
	{
		return (PtrS->Data[(PtrS->top)--]);
	}
	
} 

我们用一个例题理解一下吧^_^

例题】用一个数组实现两个堆栈,最大利用数组空间,使数组只要有空间入栈就可以成功

思路:从栈的两头分别从中间生长,当两个栈的栈顶指针相遇,表示两个栈都满了。指针top1代表栈1的空间,而top2代表堆栈减去栈2剩下的空间,所以不可以用相加表示栈空间。

#define MaxSize<储存数据元素的最大个数>
struct DStack
{
	ElementType Data[MaxSize];
	int Top1;
	int Top2;
}S;
S.Top1=-1;
S.Top2=Maxsize;
void Push(struct DStack *PtrS,ElementType item,int Tag)//Tag是区分两个堆栈的标志 
{
	if(PtrS->Top2-PtrS->Top1==1)
	{
		cout<<"堆栈满";
		return;
	}
	if(Tag==1)
	{
		if(PtrS->Top1==-1)
		{cout<<"堆栈1空";
		return NULL;}else return PtrS->Data[(PtrS->Top1)--];
	}else 
	{
		if(PtrS->Top2==MaxSize)
		{
			cout<<"堆栈2空";
			return NULL;
		}else return PtrS->Data[(PtrS->Top2)++];
	}
}

堆栈的链式存储实现

实际上就是一个单链表,叫做链栈。插入和删除操作只能在链栈的栈顶进行。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值