简体   繁体   English

使用队列在OCaml中对二叉树进行广度优先搜索

[英]Breadth first search on binary trees in OCaml using queues

I want to create a breadth-first search on binary trees in OCaml using queues, but I can't get it to work. 我想使用队列在OCaml中的二叉树上进行广度优先搜索,但是我无法使其正常工作。

it seems like the function gets stuck when a node doesn't have any "neighbours". 当节点没有任何“邻居”时,该函数似乎卡住了。

let rec enque v l = 
    match l with
        [] -> [v]
    |   h::t -> h::(enque v t)



let rec qhd l =
    match l with
        h::[] -> h
    |   h::t -> qhd t



let deque l =
    match l with
        [] -> []
    |   h::t -> t



let notempty l = (l != [])


let rec breadthFirstHelp l =
    if notempty l
    then
        let cur = qhd l in
            match cur with
                Empty -> []
           |   (Node(Empty, node, Empty)) -> node::(breadthFirstHelp (deque l))
           |   (Node(left, node, right)) ->
               let l = enque right l in
               let l = enque left l in 
                   node::(breadthFirstHelp (deque l))
    else []

Here is a tree that I'm testing on. 这是我正在测试的树。

[tree =
  Node
   (Node
     (Node (Empty, "A", Empty), "B",
      Node (Node (Empty, "C", Empty), "D", Empty)),
    "E", Node (Empty, "F", Node (Empty, "G", Node (Empty, "O", Empty))))]

With my code: ["E"; 用我的代码:[“ E”; "B"; “B”; "A"; “一种”; "A"; “一种”; "A"] “一种”]

Expected result: ["E"; 预期结果:[“ E”; "B"; “B”; "F"; “F”; "A"; “一种”; "D"; “d”; "G"; “G”; "C"; “C”; "O"] “O”]

There are three problems in your code: 您的代码中存在三个问题:

First, your qhd function is not compatible with your deque and enque function. 首先,您的qhd函数与dequeenque函数不兼容。 Indeed, for a not empty queue q and a value any , one would expect that adding elements at the end of the queue does not change the element at the top: 确实,对于一个不为空的队列q和一个值any ,人们希望在队列末尾添加元素不会更改顶部的元素:

 qhd q = qhd (enque any q)

whereas with your implementation for a queue q such that deque q is not empty, you have 而对于队列q实现,使得deque q不为空,则

 qhd q = qhd (deque q)

Second, in your breadthFirstHelp function, the empty case always returns [] even if there are pending subtrees in l . 第二,在breadthFirstHelp函数中,即使l存在未决子树,空情况也始终返回[]

Fixing those two issues should give you the right result, there is however a last performance issue: the enque function is very expansive because it needs to traverse the whole queue. 解决这两个问题应该可以为您带来正确的结果,但是最后一个性能问题是: enque函数的扩展性很强,因为它需要遍历整个队列。

A simple solution is to split the list in two 一个简单的解决方案是将列表分为两部分

  type 'a queue = { top: 'a list; bottom: 'a list }

when the bottom list is kept in reverse order. 当底部列表按相反顺序排列时。 Thus appending to the queue is a matter of appending at the top of the bottom list. 因此,附加到队列就是附加在底部列表顶部的问题。 Whereas poping the queue requires only to take the first element of the top list if it is not empty, or to refill it from the bottom list otherwise. 弹出队列只需要取top列表中的第一个元素(如果不为空),否则从底列表中重新填充它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM