我们知道,堆栈在数据结构中扮演着重要的角色,而在理解堆栈先进后出的特性时,有一个经典的问题就是T型轨道的列车排列问题。
1.问题模型
2.基本思路
分析可知,这道题的考察点就是堆栈的先进后出特性的应用。火车列车之所以会有不同的排列方式,就是因为不同列车进入与离开轨道垂直段的时间不同,有的列车先进先出,有的先进后出,有的后进先出,有的后进后出。把握好这一点,我们就来考察每一种情况的代码逻辑。将车厢一节节的分析来看,每一节车厢在进入轨道垂直段时,都会面临着相同的选择:直接进还是等待下一个列车一起进;同理,其在离开时,也会有着如此抉择:现在离开,还是和下一个一起离开。
现在这样分析过后,结果已经很明了了,我们需要用到堆栈与递归,因为高度的重复性的情况下使用递归就可使代码变得非常容易。当然,另一个困难点是我们要把握好情况的判断条件与临界点
3.代码实现
最后,就是代码实现,因为用了递归,代码变得相对简洁。
代码注释应该已经相对明晰了,当然也欢迎大家与博主一起讨论。
//火车车厢的排列顺序问题
#include<iostream>
#include<vector>
#include<stack>
using namespace std;//a为数据初始存放数组,b为模拟铁轨的堆栈类型,c数组储存重新排列后的车厢顺序
//sizec表示C数组中元素个数,starta用来记录a中下一个要处理数字
void compute(vector<int>& a, stack<int>& b, vector<int>& c, int sizec, int starta, int& n)
{
if (sizec == a.size()) //判断C数组中储存的数字是否已达到上限,满足则输出
{
for (int i = 0; i < a.size(); i++)
{
cout << c[i] << " ";
}
cout << endl;
n++; //统计共有多少种组合情况
cout << "Situation Number : " << n << endl; //将每种组合编号输出
return; //开始返回
}
if (!b.empty()) //表示栈B有车厢需要处理
{
c[sizec] = b.top(); //将该车存入C中
b.pop();
compute (a, b, c, sizec + 1, starta, n);
b.push(c[sizec]); //表示另一种选择,此列车将与接下来的新列车组合
}
if (starta < a.size()) //表示还A中有待处理车厢未被分配
{
b.push(a[starta]); //将该车厢压入B栈中
compute(a, b, c, sizec, starta + 1, n); //下一次运算
b.pop(); //将B栈中的该节车厢取出
}
}
int main()
{
int number;
cout << "Please enter the number of train you want : " << endl;
cin >> number;
int n = 0;
vector<int>a(number);
for (int i = 0; i < number; i++) //对列车进行初始化
a[i] = i + 1;
stack<int>b;
vector<int>c(number, 0);
compute(a, b, c, 0, 0, n);
}
4.结果演示
结果为n=4时的情况