以下是如何在不假设任何有关树的布局的情况下实施第 1 步的方法。为简单起见,我将选择最小化的节点,而不是最小化某些功能的节点,但是修改这个想法并不难。由于某种原因,rosezipper
它没有提供获取拉链所有子项的操作,因此我们必须首先实现它。一旦我们这样做了,这个想法就很简单了:递归孩子,然后选择当前位置或递归结果的最小值。
import Data.List
import Data.Ord
import Data.Tree
import Data.Tree.Zipper
childrenAsList :: TreePos Full a -> [TreePos Full a]
childrenAsList = go . children where
go z = case nextTree z of
Nothing -> []
Just z -> z : go (nextSpace z)
minZipper :: Ord a => Tree a -> TreePos Full a
minZipper = go . fromTree where
go z = minimumBy (comparing (rootLabel . tree))
(z:map go (childrenAsList z))
您当然不需要使用拉链来做一些有效的事情,但这无疑是解决问题的一种合理且好的方法。与两次遍历方法相比,这种方法的一个优点是它应该具有最大的共享。