自己做数据结构实验的栈和队列部分时,耗了大量时间做这题,本来想直接抄书上的算法,结果试了好久也没试出来,(((φ(◎ロ◎;)φ))),以为算法错了,自己把书扔到一边再自己写了一个,最后和书上的一对比,结果就一点地方不一样。≧ ﹏ ≦。
现有n节车厢,给定k节缓冲轨,且位于出轨和入轨之间。车厢的顺序已被打乱,要求n节车厢从入轨进入缓冲轨,至出轨时顺序为1~n。
例:车厢9节,缓冲轨 3
入轨顺序为 3 6 9 2 4 7 1 8 5
出轨顺序为 1 2 3 4 5 6 7 8 9
队列解决算法
我给的解决算法如下。详细信息对比main.cpp,有个小处理就是实际上能用到的缓冲轨应该是k-1个,因为入轨需要和一个缓冲轨合并使用。
- 如果所有元素已出轨,输出结果,否则执行2
- 对比入轨队列头部和应出轨元素是否相同,如果相同,该元素出入轨队列进入出轨队列,应出轨元素调整,不执行3。否则2执行后执行3
- 循环检查非空缓冲队列,如果存在缓冲轨队首与应出轨元素相等,该元素出该缓冲轨队列进入出轨队列,应出轨元素调整.
- 如果入轨队列非空
- 循环检查非空缓冲队列,如果入轨元素大于缓冲队列队尾元素,元素入该缓冲轨,不执行3.2,否则执行3.2
- 如果缓冲轨有剩余,将元素压入最近空队列,否则火车无法重排,结束程序。
- 执行1
程序样例
/*Queue.h*/
#include<iostream>
using namespace std;
template <class T>
class Queue
{
public:
template <class S>
class Node //火车车厢节点
{
public:
S data;
Node<S>* next;
Node<S>():next(nullptr) {}
Node<S>(T i):data(i),next(nullptr) {}
};
Node<T> * front;
Node<T> * rear;//队头队尾
Queue(){
Node<T> *p=new Node<T>;
p->next=nullptr;
front=rear=p;
}
~Queue(){
Node<T> *p=nullptr;
while(front!=nullptr){
p=front->next;
delete front;
front=p;
}
}
void inQueue(T i){
Node<T> *p=new Node<T>;
p->data=i;
p->next=nullptr;
rear->next=p;
rear=p;
}
T getfront(){
Node<T> *p=front->next;
if(p==nullptr)throw "null";
return p->data;
}
T getrear(){
Node<T> *p=rear;
if(p==nullptr)throw "null";
return p->data;
}
T outQueue(){
Node<T> *p=nullptr;
T i;
if(rear==front) throw "null,can't out";
p=front->next;
front->next=p->next;
i=p->data;
if(p->next==nullptr)rear=front;
delete p;
return i;
}
void printQueue()
{
for(Node<T> *p=front->next; p!=nullptr; p=p->next)
{
cout<<p->data<<" " ;
}
cout<<endl;
}
bool isEmpty()
{
return front==rear;
}
};
/* main.cpp */
#include <iostream>
#include "Queue.h"
using namespace std;
int main()
{
//输入车厢和火车轨数
int n,k;
cin>>n>>k;
//初始化入轨,出轨,k节缓冲轨
Queue<int> *dusk=new Queue<int>[k+1];//0,k入轨,出轨,1~k-1缓冲轨
for(int i=0;i<n;i++){
int a;
cin>>a;
dusk[0].inQueue(a);
}
while(nowcount<=n){
//检查入轨是否满足
flag=0;
if(!dusk[0].isEmpty()&&nowcount==dusk[0].getfront()){
dusk[k].inQueue(dusk[0].outQueue());
cout<<nowcount<<"从0轨出轨"<<endl;
nowcount++;
flag=1;
}
//检查其余缓冲轨是否满足
for(int i=1;i<k;i++){
if(!dusk[i].isEmpty()){
if(dusk[i].getfront()==nowcount){
dusk[k].inQueue(dusk[i].outQueue());
cout<<nowcount<<"从"<<i<<"轨出轨"<<endl;
nowcount++;
}
}
}
//添加至其余缓冲轨,前提入轨非空且入轨未直接出轨
if(!dusk[0].isEmpty()&&!flag){
flag=0;
//优先添加至非空队列
for(int i=1;i<k;i++){
if(!dusk[i].isEmpty()){
//如果队尾小于入轨,入队
if(dusk[i].getrear()<dusk[0].getfront()){
dusk[i].inQueue(dusk[0].outQueue());
cout<<dusk[i].getrear()<<" 入"<<i<<"轨"<<endl;
flag=1;
break;
}
}
}
//如果添加至非空队列失败,添置新缓冲轨
if(!flag){
if(num<k-1)//如果缓冲轨有空余
for(int i=1;i<k;i++){
if(dusk[i].isEmpty()){
dusk[i].inQueue(dusk[0].outQueue());
cout<<dusk[i].getrear()<<" 入"<<i<<"轨"<<endl;
num++;
break;
}
}
else{
cout<<"重排失败,缓冲轨已用完"<<endl;
}
}
}
}
/**************************************/
cout<<"重排结束,排序结果为"<<endl;
dusk[k].printQueue();
return 0;
}
程序结果为