在F#中实现一个队列类型

11

我正在尝试在F#中实现一个队列,目前这是我的代码,但我认为它的行为更像一个堆栈:

type 'a queue = NL| Que of 'a * 'a queue;;

let enque m = function
    |NL -> Que(m, NL)
    |Que(x, xs) -> Que(m, Que(x, xs));;

let rec peek  = function
    |NL -> failwith "queue is empty"
    |Que(x, xs) -> x;;

let rec deque  = function
    |NL -> failwith "queue is empty"
    |Que(x, xs) -> xs;;

let rec build = function
    | [] -> NL
    | x::xs -> enque x (build xs);;

除了enque操作之外,其他操作都正常运行。我想让它将新元素添加到队列后面而不是前面。

2个回答

25

函数式队列的标准方法是使用两个列表,这样可以实现摊销的 O(1) 访问:

type queue<'a> =
    | Queue of 'a list * 'a list

let empty = Queue([], [])

let enqueue q e = 
    match q with
    | Queue(fs, bs) -> Queue(e :: fs, bs)

let dequeue q = 
    match q with
    | Queue([], []) -> failwith "Empty queue!"
    | Queue(fs, b :: bs) -> b, Queue(fs, bs)
    | Queue(fs, []) -> 
        let bs = List.rev fs
        bs.Head, Queue([], bs.Tail)

4

目前您将它放在队列的最前面;如果您想将其排队到队列末尾,您需要一直前进到末尾,然后再放置您的值:

let rec enque m = function
  NL          -> Que (m, NL)
| Que (x, xs) -> Que (x, enque m xs) // Note : not tail-rec

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接