【c++】栈教程

今天来讲讲栈


栈是什么?

老样子,先来看一道题:

【栈】栈的基本操作

描述

栈的定义:栈是一种特殊的表这种表只在表头进行插入和删除操作。因此,表头对于栈来说具有特殊的意义,称为栈顶。相应地,表尾称为栈底。不含任何元素的栈称为空栈。

栈的逻辑结构:假设一个栈 SS 中从顶到底的元素为 a_n,a_{n-1},\ldots,a_1an​,an−1​,…,a1​,则称 a_1a1​ 为栈底元素,a_nan​ 为栈顶元 素。栈中的元素按 a_1,a_2,..,a_{n-1},a_na1​,a2​,..,an−1​,an​ 的次序进栈。在任何时候,出栈的元素都是栈顶元素。换句话说,栈的修改是按后进先出的原则进行的。因此,栈又称为后进先出 (Last In First Out) 表,简称为 LIFO 表。所以,只要问题满足 LIFO 原则,就可以使用栈。

举个生活中的例子,比如洗碗,先洗的碗在底层,后面洗的碗会叠在先洗的碗的上面。这样在使用的时候,最后洗的碗就会先拿。

在程序实现上,栈也是用数组来存放的,需要一个数组下标变量来控制数据在数组的存入和读取等操作。

由于 C++ 的 STL 本身提供了栈这种数据结构,你只要学会使用 STL 的栈操作就行了。

后面学的递归(回溯)算法,递归会调用系统栈是来实现(这个是递归内部实现,我们不用去操作),只是理解栈这个结构会帮助我们更好地理解递归这个算法。当然,栈本身在一些题目上也会用到。

首先看一下 C++ 栈的方法的基本用法:

push():向栈内压入一个成员;

pop():从栈顶弹出一个成员;

empty():如果栈为空返回true,否则返回false

top():返回栈顶,但不删除成员;

size():返回栈内元素的大小;

普通栈的操作:

#include<iostream>
#include<stack>  //使用栈需要的头文件 
using namespace std;
int x; 
int main(){
    stack <int>stk; //定义一个整数类型的栈变量 
    //入栈
    for(int i=0;i<50;i++){
        cin>>x;
        stk.push(x);  // 数据入栈 
    }
    cout<<"栈的大小:"<<stk.size()<<endl;
    while(!stk.empty()){
        cout<<stk.top()<<endl;  //取出栈顶数据 
        stk.pop();   //删除栈顶数据,就是出栈 
    }
    cout<<"栈的大小:"<<stk.size()<<endl;
    return 0;
}

结构体栈的使用:

#include<iostream>
#include<stack>  //使用栈需要的头文件 
using namespace std;
struct people{
    int sg,tz;
    char xb;
}; 
people x; 
int n;
int main(){
    stack <people> stk; //定义一个结构体类型的栈变量 
    //入栈
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>x.sg>>x.tz>>x.xb; 
        stk.push(x);  // 结构体数据入栈 
    }
    cout<<"栈的大小:"<<stk.size()<<endl;
    while(!stk.empty()){
        x= stk.top();  //取出栈顶数据
        cout<<x.sg<<"  "<<x.tz<<"  "<<x.xb<<endl;  //取出栈顶数据 
        stk.pop();   //删除栈顶数据,就是出栈 
    }
    cout<<"栈的大小:"<<stk.size()<<endl;
    return 0;
}

现给定一组栈的操作(入栈与出栈),要求按顺序输出出栈的数,和最终留在栈里的数。

输入

一行若干个正整数,以0结尾。

操作有如下几种:

  • 1 x:表示将 x 入栈;
  • 2:表示将栈顶弹出。

输出

第一行按顺序输出出栈的数;无则输出空行;

如果出现栈满并且还有数据进栈则单行输出:the stack is full!

如果出现栈空并且还有数据出栈则单行输出:the stack is empty!

最后一行如果栈里还有数据则输出栈里的数(注意:出现栈满情况时也要输出栈里剩余的数)。

输入样例 1 

1 3 1 2 2 1 1 2 0

输出样例 1

2 1
3

输入样例 2 

1 3 2 2 1 3 1 4 1 5 1 6 0

输出样例 2

3

the stack is empty!

提示

对于 100% 的数据,栈的最大容量为 300,每次需要入栈的正整数小于等于 10^9。

来源

lzy

首先我来讲一下展示怎么样的东西

这里有一个羽毛球筒

|  |
|  |
|  |
|  |

现在我把一号球放进去:

|  |
|  |
|  |
|1|

现在我把二号球放进去:

|  |
|  |
|2|
|1|

现在我们要取出一个球,我们只能先取出2,再取出1(先进入的数字反而最后出来,也就是先进后出)(考试经常考哦)

|  |       ——>2(取出)
|  |
|  |
|1|

|  |       ——>2(取出)
|  |       ——>1(取出)
|  |
|  |

这就是栈,像一个羽毛球筒


栈怎么写?

定义是这样的:

stack<int> q;
//其中,<>里的数据类型代表q的类型
//比如现在q为int型
//如果把int改为longlong,q就是longlong型

其他的操作室这样的:

q.size()//求q的大小(元素个数,比如栈里有1和2,元素个数就是2) 
!q.empty()//判断q是否为空(空就是没有元素)如果空了就返回1(真),否则返回2(假) 
q.top();//获取栈顶的数字,比如刚刚的羽毛球筒,放了1和2,用这个就会返回2 
q.pop();//弹出栈顶(把栈顶删掉),将最后一个放入的2拿出,就可以用这个 
q.push(x);//入栈,也就是把x跟球一样放进栈里
//注意了!不管你怎么用,都要加个括号
//q.size()这种返回数字的东西,是可以当数字来用的
//比如if(q.size()==300) ,就是判断q的元素个数是不是等于300
//a=q.top();就是a=栈顶的那个数字 

所以我们就可以解出最开始的那道题了:
 

#include<bits/stdc++.h>
using namespace std;
int main(){
	stack<int> q;//定义 
	long long a,x;//定义(a读的是前面的1或2) 
	do{
		cin>>a;//读入 
		if(a==1){//a==1说明要入栈 
			if(q.size()==300){//如果说栈已经满了 
				cout<<endl<<"the stack is full!"<<endl;//输出 
				while(!q.empty()){//循环,栈没空就一直循环 
					cout<<q.top()<<" ";//输出栈顶 
					q.pop();//弹出栈顶,为下一次的输出做准备 
				}				
				return 0;
			}//否则就可以正常入栈了 
			cin>>x;//读入 
			q.push(x);//入栈 
		}else if(a==2){//如果要弹出 
			if(q.empty()){//如果栈空了,就弹不了了 
				cout<<endl<<"the stack is empty!";//输出 
				return 0;
			}
			cout<<q.top()<<" ";//否则输出栈顶 
			q.pop();//弹出栈顶 
		}
	}while(a!=0);//a==0就是要停止输入了 
	cout<<endl;
	while(q.size()!=0){//循环,只要栈的元素个数!=0就一直循环 
		cout<<q.top()<<" ";//输出 
		q.pop();//弹出 
	}
	return 0;
}

你知道我写了多久吗?写了20分钟。这还不值得你给我点个赞吗?

  • 23
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值