数据结构与算法-栈和队列(2)栈的链式存储结构和逆波兰计算器例题

(本文为根据b站小甲鱼的数据结构与算法视频所做笔记,供加强记忆和复习使用。)
栈的链式存储结构

简称栈链,栈因为只是栈顶来做插入和删除操作,所以较好的方法就是将栈顶放在单链表的头部,栈顶指针和单链表的头指针合体。
在这里插入图片描述
结构代码:

typedef struct StackNode
{
	ElemType data;	
	struct StackNode *next;
} StackNode, *LinkStackPtr;
typedef struct LinkStack
{
	LinkStackPtr top;
	int count
}

进栈操作:

对于栈链的Push操作,假设元素值为e的新节点是s,top为栈顶指针

Status Push(LinkStack *s, ElemType e)
{
	LinkStackPtr p = (LinkStackPtr) malloc(sizeof(StackNode));
	 p->data = e;
	 p->next = s->top;
	 s->top = p;
	 s->count++;
	 return OK;
}

出栈操作:

对于栈链的出栈Pop操作,假设变量p用来存储要删除的栈顶结点,将栈顶指针下移一位,最后释放p即可。

 Status Pop(LinkStack *s, ElemType *e)
 {
 	LinkStackPtr p;
 	if( StackEmpty(*s))
 	{
 		return ERROR;
 	}
 	*e = s->top->data;
 	p = s->top;
 	s->top = s->top->next;
 	free(p);
 	s->count-- ;
 	return OK;
 }

逆波兰表达式(RPN):

不需要括号的后缀表达式。

对于(1-2)*(4+5),用RPN表示法应该是这样:
1 2 - 4 5 + *
在这里插入图片描述
数字1和2近栈,遇到减号操作符则弹出两个元素进行运算并把结果入栈;
4和5入栈,遇到加号操作就弹栈,相加后将结果入栈;
然后遇到乘法运算符,将9和-1弹出栈进行乘法运算,此时栈空并无数据压栈,-9为最终运算结果。

假设所需头文件都引入了,初始化栈sqStack,Push,Pop,Len函数都已经写好(详情见之前的文章应该有写过或者去b站小甲鱼数据结构预算法视频系列p27)

int main
{
	sqStack s;
	char c;
	double d,e;
	char str[MAXBUFFER];
	int i = 0;
	
	InitStack(&s);
	
	printf("请按逆波兰表达式输入待计算数据,数据与运算符之间用空格隔开,以#作为结束标志:")scanf("%c", &c);
	
	while(c != '#'{
		while(isdigit(c) || c=='.')
		{
			str[i++] = c;
			str[i] = '\0';
			if(i >= 10)
			{
				printf("出错,输入的单个数据过大! \n");
				return -1;
			}
			scanf("%c", &c);
			if(c == ' ')
			{
				d = atof(str);
				Push(&s, d);
				i = 0;
				break
			}
		}
		switch(c)
		{
			case '+':
				Pop(&s, &e);
				Pop(&s, &d);
				Push(&s,  d+e);
				break;
			case '-':
				Pop(&s, &e);
				Pop(&s, &d);
				Push(&s, d-e);	
				break;
			case '*':
				Pop(&s, &e);
				Pop(&s, &d);
				Push(&s, d*e);	
				break;
			case '/':
				Pop(&s, &e);
				Pop(&s, &d);
				if(e != 0)
				{
					Push(&s, d/e);
				}
				else
				{
					printf("\n出错:除数为0!\n");
					return -1;
				}
				break;
		}
		scanf("%c",&c);
	}
	
	Pop(&s, &d);
	printf("\n最终的计算结果为: %f\n", d);
	
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值