【数据结构(三)】栈(下)链式存储结构&栈的应用

栈的链式存储结构

  • 简称为链栈

  • 链栈的栈顶放在单链表的头部,顶替头结点。

  • 链栈不存在栈满。

  • 链栈为空是top=NULL。

  • 链栈的存储结构:

typedef struct StackNode
{
	sElemType data;
	struct StackNode *next;
}StackNode,*LinkStackPtr;

typedef strucf LinkStack
{
	LinkStackPtr top;
	int count;
}LinkStack;
链栈的进栈
int Push(LinkStack *S, SElemType e)
{
	LinkStackPtr s = (LinkStackPtr)malloc(sizeof(StackNode));		//新结点
	s->data = e;
	s->next = S->top;		//把当前的栈顶元素赋值给新结点的直接后继。
	S->top = s;		//将新结点赋值给栈顶指针
	S->count++;		//栈顶元素移位
	return 1;
}
  • 时间复杂度为O(1)。
链栈的出栈
int Pop (LinkStack *S, SElemType *e)
{
	LinkStackPtr p;
	if (StackEmpty(*S))		//栈空
		return 0;
	*e = S->top->data;
	p = S->top;		//将栈顶结点赋值给p
	S->top = S->top->next;		//栈顶元素移位
	free(p);		//释放p
	s->count--;
	return 1;
}
  • 时间复杂度为O(1)。

栈的应用

递归
  • 定义:一个直接调用自己或者通过一系列调用语句间接的调用自己的函数,叫做递归函数。

  • 必须至少有一个条件,使得满足条件后不再调用自身。

  • 斐波那契数列:

//打印出前50位斐波那契数列
int Fbi(int i)
{
	if( i < 2 )
		return i == 0 ? 0 : 1;		//若i==0,返回0。若i!=0,则返回1。
	return Fbi(i - 1)+Fbi(i - 2);		//调用自己
}
int main ()
{
	int i;
	for (int i = 0; i < 50; i++)		//循环打印
		printf("%d", Fbi(i));
	return 0;
}
  • 递归缺点:大量使用会建立函数的副本,消耗大量的时间和内存。
四则运算
  • 后缀表达式:将算式通过后缀表达法转换表示后的表达式。(如:3+1/2=312/+)

  • 通过栈将表达式转化为后缀表达式
    ①遇到数字输出
    ②遇到第一个符号进栈
    ③遇到符号后若是左括号则进栈等待右括号进栈后,依次将括号内进栈的符号出栈输出(不输出左右括号)
    ④遇到非括号的符号与栈顶元素比较算数优先级,若高于栈顶元素则进栈,否则将栈顶元素出栈完毕后再进栈
    ⑤输出最后一个数字后,将栈内的符号依次出栈,结束。

  • 后缀表达式的计算
    ①遇到数字进栈
    ②遇到符号将栈顶元素依次出栈两个进行计算
    ③将计算结果再次入栈
    ④直到表达式完全计算完毕,结束。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值