文章所用的栈stackArray见栈的数组实现。
列车车厢重排问题
一列货运列车有n节车厢,将原来的乱序列车车厢如[581742963]通过输入轨道后,在中转站中经过中转调度,将其有序地驶出输出轨道,如[987654321]。中转站有一个输入轨道,一个输出轨道和k个缓冲轨道。对缓冲轨道的要求为:缓冲轨道上面的车厢序号小于下面的车厢序号,即序号顶部往下为递增的;编号为u的车厢应该进入的缓冲轨道,其顶部车厢编号是大于u的最小者。
代码实现为:
//=========================列车车厢重排=================================
//分析可得 时间复杂度为O(numberOfCarriages*numberOfTracks)
//算法主要步数集中在对numberOfCarriages-1节车厢在while或者else的条件下再次遍历numberOfTracks条轨道
namespace carriageRearrange {
//列车车厢重排需要用到的全局变量
stackArray<int>* tracks; //缓冲轨道数组
int numberOfCarriages; //输入列车序列的车厢数量
int numberOfTracks; //用于缓冲排序的轨道数量
int smallestCarriage; //在缓冲轨道中最小的车厢
int itsTrack; //最小车厢对应的缓冲轨道
void outputFromHoldingTrack();
bool putIntoHoldingTrack(int);
//函数railrod 遍历输入车厢序列,进行排序
bool railroad(int inputOrder[],int _numberOfCarriages,int _numberOfTracks) {
numberOfCarriages = _numberOfCarriages;
numberOfTracks = _numberOfTracks;
tracks = new stackArray<int> [numberOfTracks+1];
int nextCarriageToOutput = 1;//下一出轨道的车厢序号
smallestCarriage = numberOfCarriages + 1;//初始时无车厢在缓冲轨道中
for (int i = 0; i < numberOfCarriages;++i) {
//遍历输入车厢序列
if (inputOrder[i] == nextCarriageToOutput) {
//当前车厢可以移动到出轨道
cout << "Move carriage[" << inputOrder[i] << "] from input track "
<<"to output track" << endl;
++nextCarriageToOutput;
//将缓冲轨道中可以移出的车厢进行移动
while (smallestCarriage==nextCarriageToOutput) {
outputFromHoldingTrack();
++nextCarriageToOutput;
}
}
else {
//当前车厢不能移动到出轨道 将其移动到一个缓冲轨道
if (!putIntoHoldingTrack(inputOrder[i])) {
cout << "Rearranged failed!" << endl;
return false;
}
}
}
delete[] tracks;
return true;
}
void outputFromHoldingTrack() {
try {
tracks[itsTrack].pop();//当前缓冲轨道最小车厢出栈 移出到出轨道
}
catch (const stackEmpty& e)
{
e.output();
}
cout << "Move carriage[" << smallestCarriage << "] from holding track["
<< itsTrack << "] to output track" << endl;
//更新下一个缓冲轨道中编号最小的车厢和它所在的轨道编号
//smallestCarriage = numberOfCarriages + 1;
smallestCarriage = numberOfCarriages + 2;
//Q:为什么+2 A:因为如果+1会在排序完成后与递增的nextCarriageToOutput相等 从而导致对下一个不存在
//的车厢再次进行outputFromHoldingTrack() 从而导致数组越界 对一个空数组进行pop()导致异常
//如果没有对pop()进行try-catch对stackArray中的异常进行处理 那么程序将崩溃
for (int i = 1; i <= numberOfTracks;++i) {
if ((!tracks[i].empty()) && (tracks[i].top()<smallestCarriage)) {
smallestCarriage = tracks[i].top();
itsTrack = i;
}
}
}
bool putIntoHoldingTrack(int carriage) {
int bestTrack = 0;//目前最适合的缓冲轨道
int bestTop = numberOfCarriages + 1;//bestTrack中的顶部车厢
//遍历缓冲轨道 找到最适合的bestTrack
for (int i = 1; i <= numberOfTracks;++i) {
if (!tracks[i].empty()) {
int currentTrackTop = tracks[i].top();
if (carriage < currentTrackTop && currentTrackTop < bestTop) {
bestTop = currentTrackTop;
bestTrack = i;
}
}
else {
if