码迷,mamicode.com
首页 > 其他好文 > 详细

火车车厢重排问题--队列模拟

时间:2014-05-31 12:53:55      阅读:935      评论:0      收藏:0      [点我收藏+]

标签:c   style   class   blog   code   a   

①问题描述

一列货运列车共有n节车厢,每节车厢将停放在不同的车站。假定n个车站的编号分别为1n,即货运列车按照第n站至第1站的次序经过这些车站。为了便于从列车上卸掉相应的车厢,车厢的编号应与车站的编号相同,这样,在每个车站只要卸掉最后一节车厢。所以,给定任意次序的车厢,必须重新排列它们。

车厢的重排工作可以通过转轨站完成。在转轨站中有一个入轨、一个出轨和k个缓冲轨,缓冲轨位于入轨和出轨之间。假定缓冲轨按先进先出的方式运作,设计算法解决火车车厢重排问题。

②基本要求

  • 设计存储结构表示n个车厢、k个缓冲轨以及入轨和出轨;

  • 设计并实现车厢重排算法;

  • 分析算法的时间性能。

③设计思想

假设有3个缓冲轨,入轨中有9节车厢,次序为5,8,1,7,4,2,9,6,3,重排后,9节车厢出轨次序为9,8,7,6,5,4,3,2,1。重排过程如下:

3号车厢不能直接移至出轨(因为1号车厢和2号车厢必须排在3号车厢之前),因此,把3号车厢移至H16号车厢可放在H13号车厢之后(因为6号车厢将在3号车厢之后出轨)。9号车厢可以继续放在H16号车厢之后,而接下来的2号车厢不能放在9号车厢之后(因为2号车厢必须在9号车厢之前出轨)。因此,应把2号车厢移至H24号车厢可以放在H22号车厢之后,7号车厢可以继续放在4号车厢之后,如图4所示。至此,1号车厢可通过H3直接移至出轨,如图5所示。由于5号车厢此时仍在入轨中,所以把8号车厢移动至H2,这样就可以把5号车厢直接从入轨移至出轨,如图6所示。此后,可依次从缓冲轨中移出6号、7号、8号和9号车厢,如图7所示。

 

4 369247依次入缓冲轨

 

5 1移至出轨,234移至出轨

 

6 8入缓冲轨,5移至出轨

 

7 6789移至出轨

由上述重排过程可知:在把车厢c移至缓冲轨时,车厢c应移动到这样的缓冲轨中:该缓冲轨中队尾车厢的编号小于c;如果有多个缓冲轨满足这一条件,则选择队尾车厢编号最大的缓冲轨;否则选择一个空的缓冲轨。

⑤思考

  • 如果缓冲轨按后进先出的方式工作,即用栈表示缓冲轨,应如何解决火车车厢重排问题?

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#include<iostream>
using namespace std;
class Queue
{
public:
    struct Node
    {
        int data;
        Node * next;
        Node():next(NULL) {}
        Node(int a):data(a),next(NULL) {}
    };
    Node * Front;
    Node * rear;
    int length;
    Queue()
    {
        Node * p = new Node();
        Front = p;
        rear = p;
        length = 0;
    }
    int inQueue(int a)
    {
        Node * p = new Node(a);
        rear -> next = p;
        rear = rear -> next;
        length ++;
    }
    int showrear()
    {
        return rear->data;
    }
    int showfront()
    {
        return Front->next->data;
    }
    void outQueue()
    {
 
        Node * p = Front -> next;
        Front -> next = p -> next;
        delete p;
        length--;
    }
    void printf()
    {
        Node * p = Front -> next;
        for(int i = 0 ; i < length ; i++)
        {
            cout<<p->data<<" ";
            p = p -> next;
        }
    }
    bool isEmpty()
    {
        return length == 0;
    }
 
};
int main()
{
    int n , k ;//n代表车厢数,k代表轨道
    int nowOut = 1;//要输出的车厢编号
    cout<<"input n:"<<endl;
    cout<<"input k:"<<endl;
    cout<<"input train"<<endl;
    cin>>n>>k;
    Queue dusk[k+2];//0到k-1代表缓冲轨道,k代表入轨,k+1代表出轨
    for(int i = 0 ; i < n ; i++)//输入入队车厢号
    {
        int a ;
        cin>>a;
        dusk[k].inQueue(a);
    }
    while(!dusk[k].isEmpty())//出轨不为空的时候循环
    {
        int flag = 0;//判断进入新的缓冲轨还是进入非空缓冲轨道。
        //0进入新的缓冲轨道,非0进入非空缓冲轨道
        int z = 0;//判断是否能直接出轨。0为不能直接出轨,非0为可出轨。
        int flag_end = 0;//退出循环判定
        if(dusk[k].showfront()==nowOut)//如果出轨队头车厢号等于现在要出轨的车厢号
        {
            for(int i = 0 ; i < k ; i++)//遍历所有循环轨,找出一个空的
            {
                if(dusk[i].isEmpty())//找到空的循环轨,输出
                {
 
                    cout<<dusk[k].showfront()<<" train by trace "<<i+1<<" out."<<endl;
                    dusk[k+1].inQueue(dusk[k].showfront());
                    nowOut++;
                    dusk[k].outQueue();
                    z++;
                    flag++;
                    break;
                }
            }
        }
        if(z==0)//如果不能直接出轨,找到比当前要出轨的车厢小的非空轨道,并入轨
        {
            for(int i = 0 ; i < k ; i++)
            {
                if(!dusk[i].isEmpty()&&(dusk[i].showrear()<dusk[k].showfront()))
                {
                    cout<<dusk[k].showfront()<<" train in "<<i+1<<" trace."<<endl;
                    dusk[i].inQueue(dusk[k].showfront());
                    dusk[k].outQueue();
                    flag ++;
                    break;
                }
            }
        }
        //如果找不到比当前要出轨的车厢小的非空轨道,就找空的缓冲轨,并入轨
        if(flag == 0)
        {
            for(int i = 0 ; i < k ; i++)
            {
                if(dusk[i].isEmpty())
                {
                    cout<<dusk[k].showfront()<<" train in "<<i+1<<" trace."<<endl;
                    dusk[i].inQueue(dusk[k].showfront());
                    dusk[k].outQueue();
                    break;
                }
                if(i==k-1)//如果找不到新的缓冲轨,那么输出ERROR,结束循环
                {
                    cout<<"ERROR!"<<endl;
                    flag_end = 1;//结束循环的标志
                    break;
                }
            }
        }
        if(flag_end == 1)//退出while循环
        {
            break;
        }
        //遍历所有非空轨道队头车厢号,如果等于要出队的车厢号,就出轨并且重新循环
        for(int i = 0 ; i < k ; i++)
        {
            if(!dusk[i].isEmpty()&&dusk[i].showfront()==nowOut)
            {
                cout<<dusk[i].showfront()<<" train by trace "<<i+1<<" out."<<endl;
                dusk[k+1].inQueue(dusk[i].showfront());
                dusk[i].outQueue();
                nowOut++;
                i = -1;
            }
        }
    }
 
    dusk[k+1].printf();//打印出轨车厢顺序
}

 

  

 

火车车厢重排问题--队列模拟,布布扣,bubuko.com

火车车厢重排问题--队列模拟

标签:c   style   class   blog   code   a   

原文地址:http://www.cnblogs.com/Duskcl/p/3761133.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!