Types 从F中的二进制搜索树中删除元素#
我正在尝试编写一个从BST中删除元素的方法。到目前为止,这就是我所拥有的。我不确定我是否走上了正确的道路,或者是否有更好的方法通过使用模式匹配来匹配不同的删除情况,即:无子项、1子项、2子项Types 从F中的二进制搜索树中删除元素#,types,f#,binary-search-tree,Types,F#,Binary Search Tree,我正在尝试编写一个从BST中删除元素的方法。到目前为止,这就是我所拥有的。我不确定我是否走上了正确的道路,或者是否有更好的方法通过使用模式匹配来匹配不同的删除情况,即:无子项、1子项、2子项 type 'a bst = NL | BinTree of 'a * 'a bst * 'a bst;; let rec smallest = function | NL -> failwith "tree is empty" | BinTree(m, lst, rst) ->
type 'a bst = NL | BinTree of 'a * 'a bst * 'a bst;;
let rec smallest = function
| NL -> failwith "tree is empty"
| BinTree(m, lst, rst) -> if lst = NL then BinTree(m, lst, rst)
else smallest lst;;
let rec smallest2 = function
| NL -> failwith "tree is empty"
| BinTree(m, lst, rst) -> if lst = NL then m
else smallest2 lst;;
let rec rem2 = function
| NL -> NL
| BinTree(m, NL, NL) -> NL
| BinTree(m, NL, rst) -> rst
| BinTree(m, lst, NL) -> lst
| BinTree(m, lst, rst) -> BinTree(smallest2 rst, lst, rst);;
let rec rem x = function
|NL -> failwith "Node doesn't exit"
|BinTree(m, lst, rst) -> if m = x then rem2 (BinTree(m, lst, rst))
elif m < x then BinTree(m, lst, rem x rst)
else BinTree(m, rem x lst, rst);;
键入'a bst=NL |'a*'a bst*'a bst;的BinTree;;
设rec最小=函数
|NL->failwith“树为空”
|二叉树(m,lst,rst)->如果lst=NL,则二叉树(m,lst,rst)
其他最小的lst;;
设rec smallest2=函数
|NL->failwith“树为空”
|二叉树(m,lst,rst)->如果lst=NL,那么m
否则最小2 lst;;
设rec rem2=函数
|NL->NL
|二叉树(m,NL,NL)->NL
|二叉树(m,NL,rst)->rst
|二叉树(m,lst,NL)->lst
|二叉树(m,lst,rst)->二叉树(smallest2rst,lst,rst);;
设rec rem x=函数
|NL->failwith“节点未退出”
|二叉树(m,lst,rst)->如果m=x,则rem2(二叉树(m,lst,rst))
elif m
没有子节点和只有一个子节点的情况非常好,但是当要删除的节点有两个子节点时,我无法理解如何实现这种情况。我想用其右子树上的最小项替换该节点的值,然后删除其右子树上的最小项。我不太确定我是否理解
remove
函数试图实现的逻辑。通常的方法是编写一个递归函数:
- 如果
小于当前值,则从左子树递归删除x
x
- 如果
大于当前值,则从右子树递归删除x
x
- 如果
等于当前节点,则删除当前节点并合并两棵树x
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)
我遵循了Tomas在其帖子中描述的步骤,并提出了以下解决方案:
// BST - binary search tree
type BST<'a when 'a: comparison> = | Leaf
| Node of BST<'a> * 'a * BST<'a>
let rec rmMaxBST = function
| Leaf -> failwith "Tree was empty"
| Node(tL, x, Leaf) -> x, tL
| Node(tL, x, tR ) -> let m, newTR = rmMaxBST tR
m, Node(tL, x, newTR)
let rec rmMinBST = function
| Leaf -> failwith "Tree was empty"
| Node(Leaf, x, tR) -> x, tR
| Node(tL, x, tR) -> let m, newTL = rmMinBST tL
m, Node(newTL, x, tR)
let mergeBST t1 t2 =
match t1, t2 with
| (Leaf, Leaf) -> Leaf
| (t1, Leaf) -> let x, t = rmMaxBST t1
Node(t, x, Leaf)
| (t1, t2 ) -> let x, t = rmMinBST t2
Node(t1, x, t)
let rec delBST x = function
| Leaf -> Leaf
| Node(tL, a, tR) when x < a -> Node(delBST x tL, a, tR)
| Node(tL, a, tR) when a < x -> Node( tL, a, delBST x tR)
| Node(tL, _, tR) -> mergeBST tL tR
//BST-二进制搜索树
类型BST=|叶
|你的问题是什么?非常感谢,这对我帮助很大!但是,合并未按预期工作,即:当要删除的节点有2个子节点时,它将被删除,但树不保持其BST顺序。我尝试了另一种方法,将要删除的节点传递给rem2函数,然后处理个别情况,即:1个孩子,2个孩子,没有孩子。请看我的编辑
// BST - binary search tree
type BST<'a when 'a: comparison> = | Leaf
| Node of BST<'a> * 'a * BST<'a>
let rec rmMaxBST = function
| Leaf -> failwith "Tree was empty"
| Node(tL, x, Leaf) -> x, tL
| Node(tL, x, tR ) -> let m, newTR = rmMaxBST tR
m, Node(tL, x, newTR)
let rec rmMinBST = function
| Leaf -> failwith "Tree was empty"
| Node(Leaf, x, tR) -> x, tR
| Node(tL, x, tR) -> let m, newTL = rmMinBST tL
m, Node(newTL, x, tR)
let mergeBST t1 t2 =
match t1, t2 with
| (Leaf, Leaf) -> Leaf
| (t1, Leaf) -> let x, t = rmMaxBST t1
Node(t, x, Leaf)
| (t1, t2 ) -> let x, t = rmMinBST t2
Node(t1, x, t)
let rec delBST x = function
| Leaf -> Leaf
| Node(tL, a, tR) when x < a -> Node(delBST x tL, a, tR)
| Node(tL, a, tR) when a < x -> Node( tL, a, delBST x tR)
| Node(tL, _, tR) -> mergeBST tL tR
> delBST 3 Leaf;;
val it : BST<int> = Leaf
> delBST 3 (Node(Leaf, 4, Leaf));;
val it : BST<int> = Node (Leaf,4,Leaf)
> delBST 3 (Node(Leaf, 3, Leaf));;
val it : BST<int> = Leaf
> delBST 3 (Node(Node(Leaf, 1, Leaf), 3, Node(Leaf, 5,Leaf)));;
val it : BST<int> = Node (Node (Leaf,1,Leaf),5,Leaf)
> delBST 1 (Node(Node(Leaf, 1, Leaf), 3, Node(Leaf, 5,Leaf)));;
val it : BST<int> = Node (Leaf,3,Node (Leaf,5,Leaf))
> delBST 5 (Node(Node(Leaf, 1, Leaf), 3, Node(Leaf, 5,Leaf)));;
val it : BST<int> = Node (Node (Leaf,1,Leaf),3,Leaf)