我不太确定我理解你的逻辑remove
函数正在尝试实现。通常的方法是编写一个递归函数:
- if
x
小于当前,删除x
从左子树递归
- if
x
大于当前,删除x
从右子树递归
- if
x
等于当前,删除当前节点并合并两棵树
在 F# 中对此进行编码的方法是使用模式匹配编写递归函数 - 与您编写的函数非常相似:
let rec remove x = function
| NL -> NL
| BinTree(m, lst, rst) when x = m -> merge lst rst
| BinTree(m, lst, rst) when x < m -> BinTree(m, remove x lst, rst)
| BinTree(m, lst, rst) (* x > m *) -> BinTree(m, lst, remove x rst)
[EDIT以下内容实际上不起作用!]这几乎完成了,但是您需要添加merge
功能。 merge函数的逻辑如下:
- 如果两棵树都是空的,则返回空树
- 如果剩下的是
Bin(n, llst, lrst)
右边是rst
然后返回一棵包含n
with llst
在左边并(递归地)合并lrst
and rst
在右边(因为它们中的元素都大于n
).
- 类似地,如果正确的是
Bin
左边是其他东西。
这不会产生balanced二叉树,但它是一个好的开始。
EDIT:我认为也许最简单的选择是编写两个函数 - 一个用于删除树中最大的元素,一个用于删除树中最小的元素(然后在合并时,您可以只调用这两个函数之一)。这可能比编写完全通用的删除函数更容易。
以下代码删除最大元素并将其与新树(没有最大元素)一起返回:
let rec remLargest = function
| NL -> failwith "Tree was empty!"
| BinTree(m, l, NL) -> m, l
| BinTree(m, l, r) ->
let res, newR = remLargest r
res, BinTree(m, l, newR)