栈其实抽象的来说就是往瓶子里面放糖的一个过程,先放进去的糖要最后才能吃。
![]()
栈的定义
栈(stack)是限定仅在表尾进行插入或者删除的线性表。对于栈来说,表尾端称为栈顶(top),表头端称为栈低(bottom)。不含元素的空表称为空栈。因为栈限定在表尾进行插入或者删除,所以栈又被称为后进先出的线性表(简称LIFO:Last in, First out.结构)。
栈的逻辑定义、特点及运算:
栈是限定在表的一端进行插入和删除的运算的线性表,通常将插入、删除的一端称为栈顶,另一端称为栈底。不含元素的空表称为空栈。栈的操作具有先进后出或后进先出的特点。栈的运算主要有置空栈、判栈空、判栈满、进栈、退栈、和取栈顶元素6种。
基本概念
栈作为一种数据结构,是一种只能在一端进行插入和删除操作的特殊线性表。它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。栈具有记忆作用,对栈的插入与删除操作中,不需要改变栈底指针。
栈是允许在同一端进行插入和删除操作的特殊线性表。允许进行插入和删除操作的一端称为栈顶(top),另一端为栈底(bottom);栈底固定,而栈顶浮动;栈中元素个数为零时称为空栈。插入一般称为进栈(PUSH),删除则称为退栈(POP)。栈也称为先进后出表。
栈可以用来在函数调用的时候存储断点,做递归时要用到栈!
例题:
这里有 n 列火车将要进站再出站,但是,每列火车只有 1 节,那就是车头。
这 n 列火车按 1 到 n 的顺序从东方左转进站,这个车站是南北方向的,它虽然无限长,只可惜是一个死胡同,而且站台只有一条股道,火车只能倒着从西方出去,而且每列火车必须进站,先进后出。
也就是说这个火车站其实就相当于一个栈,每次可以让右侧头火车进栈,或者让栈顶火车出站。
车站示意如图:
出站<—— <——进站
|车|
|站|
|__|
现在请你按《字典序》输出前 20 种可能的出栈方案。
输入格式
输入一个整数 n,代表火车数量。
输出格式
按照《字典序》输出前 20 种答案,每行一种,不要空格。
数据范围
1≤n≤20
输入样例:
3
输出样例:
123
132
213
231
321
难度:简单 |
时/空限制:1s / 64MB |
总通过数:2854 |
总尝试数:5033 |
来源:《算法竞赛进阶指南》 |
算法标签 |
解题思路 :
由题目可以知道,火车栈存在两种情况,要么出栈,要么进栈。
于是我们模拟一下样例:
n = 3
第一种情况:
1. 1 进栈
2. 1 出栈
3. 2 进栈
4. 2 出栈
5. 3 进栈
6. 3 出栈
输出顺序:1 2 3
第二种情况:
1. 1 进栈
2. 1 出栈
3. 2 进栈
4. 3 进栈
5. 3 出栈
6. 2 出栈
输出顺序:1 3 2
······
ac代码
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 30 ;
int cnt=20 , t1 , t2 ;
int n , s3 = 1;
int s1[MAXN],s2[MAXN];
void dfs()
{
if( !cnt )
return ;
if( t1 == n )
{
for( int i = 1 ; i < t1 ;i ++ )
{
cout << s1[i] ;
}
cout << s1[ t1 ] << endl ;
cnt --;
return ;
}
if( t2 > 0 )
{
s1 [ ++ t1 ] = s2 [ t2 -- ] ;
dfs();
s2 [ ++ t2 ] = s1 [ t1 -- ];
}
if( s3 <= n)
{
s2[ ++t2 ] = s3 ++ ;
dfs();
s3 -- ;
t2 -- ;
}
}
int main()
{
cin>>n;
dfs();
return 0;
}