队列——火车重排问题

自己做数据结构实验的栈和队列部分时,耗了大量时间做这题,本来想直接抄书上的算法,结果试了好久也没试出来,(((φ(◎ロ◎;)φ))),以为算法错了,自己把书扔到一边再自己写了一个,最后和书上的一对比,结果就一点地方不一样。≧ ﹏ ≦。
现有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个,因为入轨需要和一个缓冲轨合并使用。

  1. 如果所有元素已出轨,输出结果,否则执行2
  2. 对比入轨队列头部和应出轨元素是否相同,如果相同,该元素出入轨队列进入出轨队列,应出轨元素调整,不执行3。否则2执行后执行3
  3. 循环检查非空缓冲队列,如果存在缓冲轨队首与应出轨元素相等,该元素出该缓冲轨队列进入出轨队列,应出轨元素调整.
  4. 如果入轨队列非空
    1. 循环检查非空缓冲队列,如果入轨元素大于缓冲队列队尾元素,元素入该缓冲轨,不执行3.2,否则执行3.2
    2. 如果缓冲轨有剩余,将元素压入最近空队列,否则火车无法重排,结束程序。
  5. 执行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;
}

程序结果为
在这里插入图片描述

发布了3 篇原创文章 · 获赞 1 · 访问量 62

猜你喜欢

转载自blog.csdn.net/weixin_43323747/article/details/103303257
今日推荐