教你快速搞懂C++栈

栈的介绍

栈是什么:

栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。

栈的特点
其特殊之处在于栈底和栈顶,我们将新元素添加到栈中时,叫做压栈,也就是将新元素放在栈顶,当我们项删除元素时,也只能从栈顶开始删除,这个叫做出栈。也就是说我们添加删除元素时都只能从栈顶开始,这个就有些限制我们了。当我们想要用新元素替代栈顶元素时,栈这种东西时先出后入的。
在这里插入图片描述
栈相关算法:

1.进栈(PUSH)算法
①若TOP≥n时,则给出溢出信息,作出错处理(进栈前首先检查栈是否已满,满则溢出;不满则作②);
②置TOP=TOP+1(栈指针加1,指向进栈地址);
③S(TOP)=X,结束(X为新进栈的元素);
2.退栈(POP)算法
①若TOP≤0,则给出下溢信息,作出错处理(退栈前先检查是否已为空栈, 空则下溢;不空则作②);
②X=S(TOP),(退栈后的元素赋给X):
③TOP=TOP-1,结束(栈指针减1,指向栈顶)。

栈的相关实现:
我们在平时用栈时,有的人可能会直接用STL库里面的,用一个#include 头文件就可以了,那里面有相关实现函数。但是有的人为了节省运行时间,就会自己直接写一个栈类,然后自己直接用就行了。以下是我自己写的一个栈模板类,我们在里面想存什么数据都可以,但是如果说要存一个类的话,我们的输入输出赋值啥操作就需要我们去运用运算符重载了。

template <typename T>
class MyStack
{
	public: 
	    MyStack(int psize)            //构造函数 
		{
			size=psize;
			myBuffer=new T[size];
			top=0;
		}
		~MyStack()                   //析构函数 
		{
			delete []myBuffer;
		}
		bool Empty()                 //判断是否为空 
		{
			if(top==0)
			{
				return true;
			}
			else return false;
		}
		bool stackFull()            //判断是否溢出 
		{
			if(top==size)
			{
				return true;
			}
			else
			{
				return false;
			}
		}
		void clear()        //清空栈 
		{
			top=0;
		}
		int stackLength()
		{
			return top;
		}
		void push(T elem)        //入栈 
		{
			if(!stackFull())
			{
				myBuffer[top]=elem;
				top++;
			}
		}
		void pop()             //出栈 
		{
			if(!Empty())
			{
				top--;
			}
		}
		void stackTraverse(int n)           //遍历输出两种方式 
		{
			if(n==1){ 
			for(int i=0;i<top;i++)
			{
			    cout<<myBuffer[i]<<" ";
			}
			cout<<endl;
			}
			if(n==2)
			{
				for(int i=top-1;i>=0;i--)
			{
			    cout<<myBuffer[i]<<" ";
			}
			    cout<<endl;
			} 
		}
			T ptop()                 //访问栈顶元素· 
		{
			return myBuffer[top-1];
		}
	private:
		T *myBuffer;     //栈空间指针 
		int size;          //栈容量 
		int top;           //栈元素个数 
};

以上是一个比较完整的栈模板类,做题时可以利用里面的相关函数,不需要用到的自己也可以不用写了。

经典例子

进制转换:
进制转换这种算法相信大家都已经很清楚了,就是我们以前高中学过的除k取余法,然而呢,我们现在可以用栈来实现它,把每一个余数压入栈中,然后输出就可以了。
以下是核心代码:

        char num[]="0123456789ABCDEF";          //考虑到十六进制转换时大于等于10的数需要分别用ABCDEF表示 
		MyStack<int> *stack = new MyStack<int>(30);
		int N=1348;
		cout<<"请输入数字:"<<endl;
		cin>>N;
		int mod=0;
		int n;
		cout<<"请输入你想要转换的进制数:"<<endl;
		cin>>n;
		while(N!=0)
		{
			mod=N%n;
			stack->push(mod);
			N=N/n;
		}
        while(!stack->Empty())
		{
        	cout<<num[stack->ptop()];
        	stack->pop();
		}

括号符匹配:
遍历字符串,遇到左括号就压入栈中,遇到右括号,就看栈顶是否有与之匹配的左括号,如果有,就让栈顶元素出栈,反之则不。这也慢慢执行下去,到最后再判断栈是否为空,若为空,则字符串合法,反之则不合法。如果说想要更加清楚的话,大家可以在纸上手动演示该过程,相信你这样可以更加理解栈。以下是核心代码:

    MyStack<char> *stack = new MyStack<char>(30);
	string str;
	cin>>str;
	for(int i=0;i<str.length();i++)
	{
		if(str[i]=='('||str[i]=='['||str[i]=='{')
		{
			stack->push(str[i]);
		}
		if(str[i]==')')
		{
			if(stack->ptop()=='(')
			{
				stack->pop();
			}
		}
		if(str[i]==']')
		{
			if(stack->ptop()=='[')
			{
				stack->pop();
			}
		}
		if(str[i]=='}')
		{
			if(stack->ptop()=='{')
			{
				stack->pop();
			}
		}
	}
	if(stack->Empty()) cout<<"YES"<<endl;
	else cout<<"NO"<<endl;

这是本人对栈的理解,希望能够对大家有所帮助。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值