火车车厢重排实验报告

  • 格式:doc
  • 大小:156.50 KB
  • 文档页数:12

下载文档原格式

  / 12
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

东华理工大学长江学院数据结构课程设计报告

学号: ********

姓名:***

指导老师:***

2011年1月3日

队列的应用举例——火车车厢重排一、实验分析

一列货运列车共有n节车厢,每节车厢将停放在不同的车站。假定n个车站的编号分别为1 ~ n,即货运列车按照第n站至第1站的次序经过这些车站。为了便于从列车上卸掉相应的车厢,车厢的编号应与车站(目的地)的编号相同,使各车厢从前至后按编号1到n的次序排列,这样,在每个车站只需卸掉最后一节车厢即可。所以,给定任意次序的车厢,必须重新排列他们。可以通过转轨站完成车厢的重排工作,在转轨站中有一个入轨、一个出轨和k个缓冲轨,缓冲轨位于入轨和出轨之间。开始时,n节车厢从入轨进入转轨站,转轨结束时各车厢按照编号1至n的次序离开转轨站进入出轨。假定缓冲轨按先进先出的方式运作,因此可将它们视为队列,并且禁止将车厢从缓冲轨移至入轨,也禁止从出轨移至缓冲轨。图中给出了一个转轨站,其中有3个缓冲轨H1,H2和H3。

为了重排车厢,若有k个缓冲轨,缓冲轨H k为可直接将车厢从入轨移动到出轨的通道,则可用来暂存车厢的缓冲轨的数目为k-1。假定重排9节车厢,其初始次序为5, 8, 1, 7, 4, 2, 9, 6, 3,同时令k=3,如图3-23所示。3号车厢不能直接移动到出轨,因为1号车厢和2号车厢必须排在3号车厢之前,因此,把3号车厢移动至H1。6号车厢可放在H1中3号车厢之后,因为6号车厢将在3号车厢之后输出。9号车厢可以继续放在H1中6号车厢之后,而接下来的2号车厢不能放在9号车厢之后,因为2号车厢必须在9号车厢之前输出。因此,应把2号车厢放在H2的队头。4号车厢可以放在H2中2号车厢之后,7号车厢可以继续放在4号车厢之后。如图3-24(a)所示。至此,1号车厢可通过H3直接移至出轨,然后从H2移动2号车厢至出轨,从H1移动3号车厢至出轨,从H2移动4号车厢至出轨,如图3-24(b)所示。由于5号车厢此时仍在入轨中,所以把8号车厢移动至H2,这样就可以把5号车厢直接从入轨移至出轨。如图3-24(c)所示。此后,可依次从缓冲轨中移出6号、7号、8号和9号车厢。如图所示。

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

假定重排n个车厢,可使用k个缓冲轨,将每个缓冲轨看成是一个队列,用nowOut表示下一个输出至出轨的车厢编号。火车车厢重排的算法用伪代码描述如下:

1. 分别对k个队列初始化;

2. 初始化下一个有爱输出的车厢编号nowOut=1;

3. 依次取入轨中的每一个车厢编号;

3.1如果入轨中的车厢编号等于nowOut,则

3.1.1输出该车厢;

3.1.2nowOut++;

3.2否则,考虑每一个缓冲轨队列

for(j=1;j<=k;j++)

3.2.1取队列j的对头元素c;

3.2.2如果c=nowOut,则

3.2.2.1将队列j的对头元素出队并输出;

3.2.2.2nowOut++;

3.3如果入轨和缓冲轨的对头元素没有编号为nowOut的车厢,则

3.3.1求小雨入轨中第一个车厢编号的最大队尾元素所在队列编号j;

3.3.2如果j存在,则把入轨中的第一个车厢移至缓冲轨j;

3.3.2 如果j不存在,但有多余一个空缓冲轨,则把入轨第一个车厢移至一

个空缓冲轨;否则车厢无法重排,算法结束;

二、程序分析

1. 存储结构

本程序采用单链表结构,具体为链队列结构,使用队列结构的先进先出原则可以较好地处理车厢重排问题。链队列结构示意图如下:

……..

front

a1

a2

.

.

.

a n

rear

2. 关键算法分析

一、本程序的关键算法主要为处理车厢重排问题的函数TrainPermute(),其伪代码如下:

void TrainPermute():

1. 初始化条件:计数器i=0,与非门aa=1

2. 判断是否能入轨while(用i

2.1将aa置空;

2.2用for循环,依次取入入轨中的每一个车厢的编号进入合适的缓冲轨;

2.2.1如果缓冲轨中尾指针比进入缓冲轨元素小,则

进入该缓冲轨;

计数器i+1;

有合适缓冲轨,将aa变为真;

跳出for循环并进入while循环;

2.2.2如果缓冲轨中第一个元素为空,则

进入缓冲轨成为第一个元素;

计数器i+1;

有合适缓冲轨,将aa变为真;

跳出for循环并进入while循环;

2.3 用aa判断是否有进入合适的缓冲轨

①aa=0即没有合适的缓冲轨,则

输出无法排列;

②aa=1即有合适的缓冲轨,则

遍历缓冲轨,

输出每个缓冲轨按顺序存储的车厢;

按从小到大的顺序出轨

for(引入输出轨计数器newOut=1;newOut

newOut与每个队列的头元素比较若相等,则

元素出队;

输出显示;

具体代码如下:

void TrainPermute(int arr[],LinkQueue a[],int n,int k)

{

int i=0;

bool aa=1;

while((i

{

aa=0; //亮点:与非门思想!

for(int m=0;m

{

if(a[m].GetRear()

{

a[m].EnQueue(arr[i]);

i++;

aa=1;

break;

}

if(a[m].front->next==NULL)

{

a[m].EnQueue(arr[i]);

aa=1;

i++;

break;

}

}

}

if(aa==0) //当无法将入轨中队头车厢移至合适缓冲轨中时,程序结束 {

cout<<"车厢无法重排,算法结束"<

}

else //当入轨中已经没有车厢时

{

for(int m=0;m

{

cout<<"第"<<(m+1)<<"个缓冲轨的列车编号";