我想使用队列在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”]
答案 0 :(得分:1)
您的代码中存在三个问题:
首先,您的qhd
函数与deque
和enque
函数不兼容。实际上,对于非空队列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
列表中的第一个元素(如果不为空),否则只需从底部列表中重新填充。