学习笔记:栈的使用

首先,栈是什么?不就是削减了功能的容器,相比vector,栈只能对栈顶元素增删查,那么不就是一个弱化版的vector吗,很多原有的功能都不能用了,我刚开始就觉得,还不如直接用vector或list呢!
但,功能的简化反而使我们的思考聚焦于要解决问题的核心,听起来没什么道理,不是功能多才利于解决问题吗?功能多让我在解决问题时有更大的操作空间,相反不久自缚手脚了吗?
注意上面这句话重点在聚焦于解决问题的核心,还是于vector比较,如果频繁地插入和删除数据,这就让分散我们的精力去思考元素的位置或下标,更多时候是让麻烦加大到无法解决。

总结一下,stack抛弃了繁乱的功能,让我们不必操心定位元素的下标。下面,我们具体来看栈解决问题的算法,同时我也会不断地积累,学习这些精妙算法的闪光点。

一、四则运算

例如:3+2*(6-4)+8/2+2
首先将它转换成后缀表达式:3 2 6 4 - * +8 2 / + 2 +,然后计算得13
1.假设已经转换了,我们来看后缀表达式是怎么计算得到13的
将后缀表达式中的元素依此入栈,如果是数字就入栈,如果是符号就将栈顶的两个元素出栈,然后根据相应符号计算,将得到的结果入栈,不断进行,直到遍历完后缀表达式,最后栈顶元素就是计算结果。
如果,我们将stack换成vector,那么我们的精力会分散到定位元素位置。
inline void PopNumbers(stack &s, int &number1, int &number2)
{
number1 = s.top();
s.pop();
number2 = s.top();
s.pop();
}

void Calulation(queue &q)
{
stack s;
int number1 = 0;
int number2 = 0;

	while(!q.empty())
	{
		if(q.front()>='0' && q.front()<='9')
		{
			s.push(int(q.front()-'0'));
		}
		else if(q.front()=='+')		
		{
			PopNumbers(s, number1, number2);
			s.push(number2+number1);
		}
		else if(q.front()=='-')
		{
			PopNumbers(s, number1, number2);
			s.push(number2-number1);
		}else if(q.front()=='*')
		{
			PopNumbers(s, number1, number2);
			s.push(number2*number1);
		}else
		{
			PopNumbers(s, number1, number2);
			s.push(number2/number1);
		}	
		q.pop();
	}	
	cout<<s.top()<<endl;

}

2.中缀转后缀
将中缀的元素依此入栈,遇见数字就放到输出,即成为后缀的一部分,遇到符号,如果它的优先级大于栈顶的符号就直径入栈,反之先将栈顶的出栈,然后它再入栈。
如果,这个换成vector,就无法解决,因为我们无法定位到栈元素位置。
void InTransPost(char *p)
{
stack s;
queue q;

	while(*p != '\0')
	{
		if(isdigit(*p))
		{
			q.push(*p);
		}
		else if(*p == '(')
		{
			s.push(*p);
		}
		else if(*p == ')')
		{
			while(s.top()!='(')
			{
				q.push(s.top());
				s.pop();
			}
			s.pop();
		}
		else if(*p == '+' || *p == '-')
		{
			while((!s.empty()) && s.top()!='(')
			{
				q.push(s.top());
				s.pop();
			}
			s.push(*p);
		}
		else
		{
			if(s.top()=='*' || s.top()=='/')
			{
				q.push(s.top());
				s.pop();
			}
			s.push(*p);
		}
		p++;
	}

	while(!s.empty())
	{
		q.push(s.top());
		s.pop();
	}

}

二、二叉树前中后遍历的非递归实现

三、两个栈实现队列,两个队列实现栈

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值