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

时间:2019-04-16 10:35:17

标签: tree ocaml binary-tree binary-search-tree breadth-first-search

我想使用队列在OCaml中的二叉树上进行广度优先搜索,但是我无法使其正常工作。

当节点没有任何“邻居”时,该函数似乎卡住了。

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 []

这是我要测试的树。

[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))))]

使用我的代码:[“ E”; “ B”; “一种”; “一种”; “ A”]

预期结果:[“ E”; “ B”; “F”; “一种”; “ D”; “G”; “C”; “ O”]

1 个答案:

答案 0 :(得分:1)

您的代码中存在三个问题:

首先,您的qhd函数与dequeenque函数不兼容。实际上,对于非空队列q和值any,人们希望在队列末尾添加元素不会更改顶部的元素:

 qhd q = qhd (enque any q)

对于队列q的实现使得deque q不为空,而您拥有

 qhd q = qhd (deque q)

第二,在您的broadthFirstHelp函数中,即使[]中有未决的子树,空情况也总是返回l

修复这两个问题应该会给您正确的结果,但是最后一个性能问题是:enque函数的扩展性很强,因为它需要遍历整个队列。

一个简单的解决方案是将列表一分为二

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

当底部列表按相反顺序排列时。因此,附加到队列就是附加在底部列表顶部的问题。弹出队列仅需要获取top列表中的第一个元素(如果不为空),否则只需从底部列表中重新填充。