首页 > 代码库 > 堆栈应用(三):火车车厢重排

堆栈应用(三):火车车厢重排

1、问题描述

  一列货运列车共有 n节车厢,每节车厢将停放在不同的车站。假定 n个车站的编号分别为1 ~n,货运列车按照第 n站至第 1 站的次序经过这些车站。车厢的编号与它们的目的地相同。为了便于从列车上卸掉相应的车厢,必须重新排列车厢,使各车厢从前至后按编号 1 到n的次序排列。当所有的车厢都按照这种次序排列时,在每个车站只需卸掉最后一节车厢即可。
  技术分享

为了重排车厢,需从前至后依次检查入轨上的所有车厢。如果正在检查的车厢就是下一个满足排列要求的车厢,可以直接把它放到出轨上去。如果不是,则把它移动到缓冲铁轨上,直到按输出次序要求轮到它时才将它放到出轨上。缓冲铁轨是按照 L I F O的方式使用的,因为车厢的进和出都是在缓冲铁轨的顶部进行的。在重排车厢过程中,仅允许以下移动:
• 车厢可以从入轨的前部(即右端)移动到一个缓冲铁轨的顶部或出轨的左端。
• 车厢可以从一个缓冲铁轨的顶部移动到出轨的左端。
很容易知道当缓冲铁轨上的车厢编号不是按照从顶到底的递增次序排列时,重排任务将无法完成。
因此新的车厢 u应送入这样的缓冲铁轨:其顶部的车厢编号v 满足v > u,且v 是所有满足这种条件的缓冲铁轨顶部车厢编号中最小的一个编号(若有空的缓冲轨则直接移入空缓冲轨)。只有这样才能使后续的车厢重排所受到的限制最小。

2、代码实现

重排实现:

 1 #include "RailRoad.h" 2 using std::cout; 3 using std::cin; 4  5 bool RailRoad(int r[], int n, int k) 6 { 7     LinkedStack<int> *H; 8     H = new LinkedStack<int>[k + 1]; 9     int NowOut = 1;//可以直接移入出轨的车厢号10     int MinH = n+2;//缓冲轨顶部最小的车厢号11     int MinS;//最小车厢号的缓冲轨号12     for (int i = 0; i < n;++i)13     {14         if (r[i]==NowOut)15         {16             cout << "将车厢" << NowOut << "从入轨直接移动到出轨" << std::endl;17             ++NowOut;18             while (MinH == NowOut)//检查缓冲轨最小车厢号,相等则输出19             {20                 output(MinH, MinS, H, k, n);21                 ++NowOut;22             }23         }24         else25         {26             if(!movetocache(MinH, MinS, H, k, n, r[i]))27             {28                 return false;29             }30         }            31     }32 33     return true;34 }35 
//复杂度O(k)36 void output(int& MinH, int& MinS, LinkedStack<int> *H, int k, int n)37 {38 cout << "将车厢" << MinH << "从缓冲轨" << MinS << "移动到出轨上" << std::endl;39 H[MinS].Delete(MinH);40 MinH = n + 2;41 for (int i = 1; i < k + 1;++i)42 {43 if (!H[i].IsEmpty() && H[i].Top()<MinH)44 {45 MinH = H[i].Top();46 MinS = i;47 }48 }49 }50
//复杂度O(k)51 bool movetocache(int &MinH, int &MinS, LinkedStack<int>* H, int k, int n, int num)52 {53 54 55 int besttrack = 0;56 int BestTop = n + 1;57 int x;58 for (int i = 1; i < k + 1;++i)59 {60 if (H[i].IsEmpty())61 {62 H[i].Add(num);63 cout << "将车厢" << num << "移动到缓冲轨" << i << std::endl;64 if (num < MinH)65 {66 MinH = num;67 MinS = i;68 }69 return true;70 }71 72 x = H[i].Top();73 if (num<x&&x<BestTop)74 {75 BestTop = x;76 besttrack = i;77 }78 }79 80 if (!besttrack)81 {82 return false;83 }84 85 H[besttrack].Add(num);86 cout << "将车厢" << num << "移动到缓冲轨" << besttrack << std::endl;87 if (num < MinH)88 {89 MinH = num;90 MinS = besttrack;91 }92 93 return true;94 }

测试:
 1 #include "RailRoad.h" 2 #include <iostream> 3  4 int main() 5 { 6     int n=0, k=0; 7      8     while (n<1||k<1) 9     {10         std::cout << "车厢节数(>0): ";11         std::cin >> n;12         std::cout << "缓冲轨条数(>0):";13         std::cin >> k;14     }15     16 17     int *p = new int[n];18     std::cout << "输入" << n << "节车厢次序:" << std::endl;19     int i = 0;20     while (i<n)21     {22         std::cin >> p[i++];23     }24 25     if (!RailRoad(p,n,k))26     {27         std::cout << "排序失败" << std::endl;28     }29 30     system("pause");31     return 0;32 }

 

 

输出:

技术分享

堆栈应用(三):火车车厢重排