栈和递归---车辆问题

栈的定义方法
class Stack():
    def __init__(self):
        self._elems = []

    def is_empty(self):
        return self._elems == []

    def top(self):
        if self._elems == []:
            return []
        return self._elems[-1]

    def push(self,elem):
        self._elems.append(elem)

    def pop(self):
        if self._elems == []:
            return []
        return self._elems.pop()
题目

根据要求完成车辆重排的程序代码

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

我们在一个转轨站里完成车厢的重排工作,在转轨站中有一个入轨、一个出轨和k个缓冲铁轨(位于入轨和出轨之间)。图(a)给出一个转轨站,其中有k个(k=3)缓冲铁轨H1,H2 和H3。开始时,n节车厢的货车从入轨处进入转轨站,转轨结束时各车厢从右到左按照编号1至n的次序离开转轨站(通过出轨处)。在图(a)中,n=9,车厢从后至前的初始次序为5,8,1,7,4,2,9,6,3。图(b)给出了按所要求的次序重新排列后的结果。

图1

(1)问题分析

现在分析图 1,为了重排车厢,需从前至后依次检查入轨上的所有车厢:

如果正在检查的车厢就是下一个满足排列要求的车厢,可以直接把它放到出轨上去;
如果不是,则把它移动到缓冲铁轨上,直到按输出次序要求轮到它时才将它放到出轨上;
缓冲铁轨上车厢的进和出只能在缓冲铁轨的尾部进行。
在重排车厢过程中,仅允许以下移动:

1、车厢可以从入轨移动到一个缓冲铁轨的尾部或进入出轨接在重排的列车后。

2、车厢可以从一个缓冲铁轨的尾部移动到出轨接在重排的列车后。

考察图1 (a), 3 号车厢在入轨的前部,但由于它必须位于 1 号和 2 号车厢的后面,因此不能立即输出 3 号车厢,可把 3 号车厢送入缓冲铁轨 H1。

下一节车厢是 6 号车厢,也必须送入缓冲铁轨。如果把 6 号车厢送入 H1,那么重排过程将无法完成,因为 3 号车厢位于 6 号车厢的后面,而按照重排的要求,3 号车厢必须在 6 号车厢之前输出。因此可把 6 号车厢送入 H2。

下一节车厢是 9 号车厢,被送入 H3,因为如果把它送入 H1 或 H2,重排过程也将无法完成。

至此,缓冲铁轨的当前状态如图 2 (a) 所示。

avator

接下来处理 2 号车厢,它可以被送入任一一个缓冲铁轨,因为它能满足缓冲铁轨上车厢编号必须递增排列的要求,不过,应优先把 2 号车厢送入 H1,因为如果把它送入 H3 ,将没有空间来移动 7 号车厢和 8 号车厢。如果把 2号车厢送入 H2,那么接下来的 4 号车厢必须被送入 H3,这样将无法移动后面的 5 号、7 号和 8 号车厢。

新的车厢 u 应送入这样的缓冲铁轨:

其底部的车厢编号 v 满足 v>u,且 v 是所有满足这种条件的缓冲轨顶部车厢编号中最小的一个编号。只有这样才能使后续的车厢重排所受到的限制最小。

接下来处理 4 号车厢时,三个缓冲铁轨顶部的车厢分别为 2 号、6 号、9 号车厢。根据分配规则,4 号车厢应送入H2。

这之后,7 号车厢被送入 H3。图2 (b) 给出了当前的状态。

接下来,1 号车厢被送至出轨,这时,可以把 H1 中的 2 号车厢送至出轨。

之后,从 H1 输出 3 号车厢,H2 输出 4 号车厢。

至此,没有可以立即输出的车厢了。

接下来的 8 号车厢被送入 H1,然后 5 号车厢从入轨处直接输出到出轨处。这之后,从 H2 输出 6 号车厢,从 H3输出 7 号车厢,从 H1 输出 8 号车厢,最后从 H3 输出 9 号车厢。到此为止,“出轨”完毕!

让我们整理一下算法思路:

  • 第一步:若需出轨的编号恰是入轨编号,则直接出轨;
  • 第二步:若需出轨的编号恰是缓冲轨的最小编号,则直接出轨;
  • 第三步:将入轨编号放入缓冲轨。(规则:放到满足小于缓冲轨栈顶元素编号且栈项元素最小的上面。)
def train_sort(trains):
    s_in = Stack()
    s_out = Stack()
    s_H1 = Stack()
    s_H2 = Stack()
    s_H3 = Stack()
    for i in trains:
        s_in.push(i)
    n = 1
    while s_in != []:   #边循环边找合适的值放入出轨栈
        tmp = s_in.pop()
        if tmp == []:
            break
        if tmp == n:
            print("%s号车厢出轨!"%n)
            n+=1
            s_out.push(tmp)
            while (s_out.top()+1) == n:
                if s_H1.top() == n:
                    print("%s号车厢出轨!"%n)
                    n+=1
                    s_out.push(s_H1.top())
                    s_H1.pop()
                elif s_H2.top() == n:
                    print("%s号车厢出轨!"%n)
                    n+=1
                    s_out.push(s_H2.top())
                    s_H2.pop()                   
                elif s_H3.top() == n:
                    print("%s号车厢出轨!"%n)
                    n+=1
                    s_out.push(s_H3.top())
                    s_H3.pop()
                else:
                    break
        else:
            if s_H1.top() == []:
                s_H1.push(tmp)
            elif s_H1.top() < tmp and s_H2.top() == []:
                s_H2.push(tmp)
            elif s_H2.top() < tmp and s_H3.top() == []:
                s_H3.push(tmp)
            else:  #此处需要优化处理下
                if s_H1.top() == min(s_H1.top(),s_H2.top(),s_H3.top()) and s_H1.top() > tmp:
                    s_H1.push(tmp)
                elif s_H2.top() == min(s_H1.top(),s_H2.top(),s_H3.top()) and s_H1.top() > tmp:
                    s_H2.push(tmp)
                elif s_H3.top() == min(s_H1.top(),s_H2.top(),s_H3.top()) and s_H1.top() > tmp:
                    s_H3.push(tmp)
                elif tmp > s_H1.top() and s_H2.top() == min(s_H2.top(),s_H3.top()) and s_H2.top() > tmp:
                    s_H2.push(tmp)
                elif tmp > s_H1.top() and s_H3.top() == min(s_H2.top(),s_H3.top()) and s_H2.top() > tmp:
                    s_H3.push(tmp)
                elif tmp > s_H2.top() and s_H3.top() > tmp:
                    s_H3.push(tmp)
                    
    while (s_out.top()+1) == n:
        if s_H1.top() == n:
            print("*%s号车厢出轨!"%n)
            n+=1
            s_out.push(s_H1.top())
            s_H1.pop()
        elif s_H2.top() == n:
            print("**%s号车厢出轨!"%n)
            n+=1
            s_out.push(s_H2.top())
            s_H2.pop()                   
        elif s_H3.top() == n:
            print("***%s号车厢出轨!"%n)
            n+=1
            s_out.push(s_H3.top())
            s_H3.pop()
        else:
            n+=1                    
        
trains = [5,8,1,7,4,2,9,6,3]
train_sort(trains)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值