《数据结构、算法与应用 —— C++语言描述》学习笔记 — 队列 —— 应用(一)
一、列车车厢重排
在学习栈时,我们考察过这个问题。这次,我们稍微修改下我们的需求。所有的缓冲轨道不再是后进先出,而是先进先出:
1、求解策略
首先我们需要重新明确题目要求和有解条件。仿照我们前面的表述:
在重排车厢的过程中,仅允许以下移动:
(1)车厢可以从入轨道的前端移动到一个缓冲轨道的顶部或出轨道的后端。
(2)车厢可以从一个缓冲轨道的尾部移动到出轨道的后端。
该问题有解的两个条件:
(1)在整个过程中,任何一条缓冲轨道上的车厢都需要保证从顶到底是递减的。
(2)从入轨道中移动车厢到缓冲轨道时,如果有多个满足条件的缓冲轨道时,优先选择顶部车厢编号最大的缓冲轨道,空轨道的优先级最低。
同样,这个条件是为了保证所有的缓冲轨道都能被充分利用。但是其容量的计算方式与栈不同。我们可以认为每条轨道的剩余容量为 m a x N u m − 队 列 首 元 素 maxNum - 队列首元素 maxNum−队列首元素 。那么向某满足条件的缓冲轨道中添加新的车厢后,其容量减少为 车 厢 号 − 队 列 首 元 素 车厢号 - 队列首元素 车厢号−队列首元素 。因此队首元素越大,添加新车厢后缓冲队列总容量越大。
2、实现
这里我把与流程或修改无关的代码去掉了,详情可以参考栈的应用中的算法描述和实现。
#pragma once
#include "arrayQueue.h" // change
...
tuple<bool, string> railroad(int inputOrder[], int numOfCars, int numOfTracks)
{
...
for (int i = 1; i < numOfCars + 1; i++)
{
if (inputOrder[i] == needCar)
{
...
while (smallestCar == needCar)
{
...
for (int i = 0; i < numOfTracks; ++i)
{
if (!tracks[i].empty() && tracks[i].front() < smallestCar) // change
{
smallestCar = tracks[i].front(); // change
smallestTrack = i;
}
}
...
}
}
else
{
int bestTop = 0; // change
...
for (int j = 0; j < numOfTracks; ++j)
{
if (!tracks[j].empty())
{
if (tracks[j].back() < inputOrder[i] && tracks[j].back() > bestTop) // change
{
bestTop = tracks[j].back(); // change
bestTrack = j;
}
}
...