【发布时间】:2020-04-15 15:44:12
【问题描述】:
Purely Functional Data Structure 中的练习 2.2 表明原始 member 函数在最坏的情况下执行大约 2d 比较,其中 d 是树的深度。根据this paper,作者建议重写member 函数,通过跟踪可能等于查询元素的候选元素(例如,
以下是代码:
data Tree a = Leaf
| Fork (Tree a) a (Tree a)
deriving (Show, Eq)
-- The original member function.
member :: Ord a => a -> Tree a -> Tree a
member _ Leaf = False
member x (Fork l y r)
| x < y = member x l
| x > y = member x r
| otherwise = True
-- The improved member function that I write.
member' :: Ord a => a -> Tree a -> Tree a
member' v t = loop Nothing v t
where
loop candidate _ Leaf = Just x == candidate
loop candidate x (Fork l y r)
| x < y = loop candidate x l
| otherwise = loop (Just y) x r
现在我的问题是:
根据the paper,我改进的
member功能对吗?在最坏的情况下,改进的
member比原来的更有效,因为它的比较不超过d + 1次。但根据算法,改进后的member将对每个查询进行d + 1比较。对于原始的member,如果查询值等于根值,则只比较两次,而改进后的member似乎仍然需要d + 1比较。因此,在最好的情况下,改进后的算法似乎不如原来的算法有效。我在这里有什么误解吗?其实the paper关于算法的内容如下:
到达搜索节点时,算法不会终止 但在右子树中继续。由于该子树中的所有元素 大于搜索的,算法将不再 通过该节点后右转。因此,如果元素搜索 是在树中找到它必须在最后一个节点中 右转,就是candidate所指的节点。
看来这就是我对算法的理解。
- 如果第 2 点为真,那么除了使用 Haskell 中的三路比较功能
compare之外,如何改进算法以使其在最佳情况下不需要比较d + 1次?
感谢您提供任何信息!
【问题讨论】:
标签: algorithm haskell binary-search-tree