mirror of
https://github.com/Smaug123/fsharp-red-black-tree
synced 2025-10-08 01:08:41 +00:00
A better toSeq
This commit is contained in:
@@ -20,8 +20,9 @@ module TestRedBlackTree =
|
||||
let ``Examples found by property-based testing`` (l : int list) =
|
||||
l
|
||||
|> List.fold (fun tree i -> RedBlackTree.add i () tree) RedBlackTree.empty
|
||||
|> RedBlackTree.toList
|
||||
|> RedBlackTree.toListRev
|
||||
|> List.map fst
|
||||
|> List.rev
|
||||
|> shouldEqual (Set.ofList l |> Set.toList)
|
||||
|
||||
[<TestCase 9>]
|
||||
@@ -30,7 +31,7 @@ module TestRedBlackTree =
|
||||
let rbt =
|
||||
perm
|
||||
|> List.fold (fun tree i -> RedBlackTree.add i () tree) RedBlackTree.empty
|
||||
if rbt |> RedBlackTree.toList |> List.map fst <> [1..n] then failwithf "Correctness error: %+A produced %+A" perm rbt
|
||||
if rbt |> RedBlackTree.toListRev |> List.map fst |> List.rev <> [1..n] then failwithf "Correctness error: %+A produced %+A" perm rbt
|
||||
let balance = RedBlackTree.balanceFactor rbt
|
||||
if balance.Longest >= balance.Shortest * 2 then
|
||||
failwithf "Unbalanced! %+A produced %+A (balance: %+A)" perm rbt balance
|
||||
@@ -40,9 +41,24 @@ module TestRedBlackTree =
|
||||
let property (list : int list) =
|
||||
list
|
||||
|> List.fold (fun tree i -> RedBlackTree.add i () tree) RedBlackTree.empty
|
||||
|> RedBlackTree.toList
|
||||
|> RedBlackTree.toListRev
|
||||
|> List.map fst
|
||||
|> List.rev
|
||||
|> shouldEqual (Set.ofList list |> Set.toList)
|
||||
|
||||
let config = { Config.Default with MaxTest = 10000 }
|
||||
Check.One(config, property)
|
||||
Check.One(config, property)
|
||||
|
||||
[<Test>]
|
||||
let ``toSeq vs toList`` () =
|
||||
let property (list : int list) =
|
||||
let rbt =
|
||||
list
|
||||
|> List.fold (fun tree i -> RedBlackTree.add i () tree) RedBlackTree.empty
|
||||
rbt
|
||||
|> RedBlackTree.toSeq
|
||||
|> Seq.toList
|
||||
|> shouldEqual (RedBlackTree.toListRev rbt |> List.rev)
|
||||
|
||||
let config = { Config.Default with MaxTest = 10000 }
|
||||
Check.One(config, property)
|
||||
|
@@ -338,12 +338,46 @@ module RedBlackTree =
|
||||
| RedBlackTree.RedRoot root -> foldRed folder state root
|
||||
| RedBlackTree.BlackRoot root -> foldBlack folder state root
|
||||
|
||||
/// Convert the tree to a list, in sorted order.
|
||||
let toList<'a, 'v when 'a : comparison> (tree : RedBlackTree<'a, 'v>) : ('a * 'v) list =
|
||||
fold (fun ls a -> a :: ls) [] tree |> List.rev
|
||||
/// Convert the tree to a list, in reverse sorted order.
|
||||
let toListRev<'a, 'v when 'a : comparison> (tree : RedBlackTree<'a, 'v>) : ('a * 'v) list =
|
||||
fold (fun ls a -> a :: ls) [] tree
|
||||
|
||||
let rec private toSeqBlack<'a, 'v, 'depth when 'a : comparison> (tree : BlackNode<'a, 'v, 'depth>) : ('a * 'v) seq =
|
||||
seq {
|
||||
match tree with
|
||||
| BlackNode.Leaf ->
|
||||
()
|
||||
| BlackNode.BlackBlackNode (left, right, value) ->
|
||||
yield! toSeqBlack left
|
||||
yield (ValueAtDepth.value value)
|
||||
yield! toSeqBlack right
|
||||
| BlackNode.BlackRedNode (left, right, value) ->
|
||||
yield! toSeqBlack left
|
||||
yield (ValueAtDepth.value value)
|
||||
yield! toSeqRed right
|
||||
| BlackNode.RedBlackNode (left, right, value) ->
|
||||
yield! toSeqRed left
|
||||
yield (ValueAtDepth.value value)
|
||||
yield! toSeqBlack right
|
||||
| BlackNode.RedRedNode (left, right, value) ->
|
||||
yield! toSeqRed left
|
||||
yield (ValueAtDepth.value value)
|
||||
yield! toSeqRed right
|
||||
}
|
||||
|
||||
and private toSeqRed<'a, 'v, 'depth when 'a : comparison> (tree : RedNode<'a, 'v, 'depth>) : ('a * 'v) seq =
|
||||
seq {
|
||||
match tree with
|
||||
| RedNode.RedNode (left, right, value) ->
|
||||
yield! toSeqBlack left
|
||||
yield (ValueAtDepth.value value)
|
||||
yield! toSeqBlack right
|
||||
}
|
||||
|
||||
let toSeq<'a, 'v when 'a : comparison> (tree : RedBlackTree<'a, 'v>) : ('a * 'v) seq =
|
||||
fold (fun ls a -> seq { yield! ls ; yield a }) Seq.empty tree
|
||||
match tree with
|
||||
| RedBlackTree.RedRoot root -> toSeqRed root
|
||||
| RedBlackTree.BlackRoot root -> toSeqBlack root
|
||||
|
||||
let rec private balanceFactorBlack<'a, 'v, 'depth when 'a : comparison> (node : BlackNode<'a, 'v, 'depth>) : int * int =
|
||||
match node with
|
||||
|
@@ -16,8 +16,8 @@ module RSet =
|
||||
| Some _ -> true
|
||||
| None -> false
|
||||
|
||||
let toList<'a when 'a : comparison> (RSet s : RSet<'a>) : 'a list =
|
||||
RedBlackTree.toList s
|
||||
let toListRev<'a when 'a : comparison> (RSet s : RSet<'a>) : 'a list =
|
||||
RedBlackTree.toListRev s
|
||||
|> List.map fst
|
||||
|
||||
let toSeq<'a when 'a : comparison> (RSet s : RSet<'a>) : 'a seq =
|
||||
|
Reference in New Issue
Block a user