So for an side exercise on exercism I implemented a BinarySearchTree. I was confident in implementing the creation of the binary tree. But I'm very unsure about the traversal of the tree. So I came up with two implementations of the traversal algorithm - which one is the "better" solution?
I'm learning about F# because I want to learn Functional Programming. This is code review - so any criticism is welcome!
module BinarySearchTree
type Node<'a> =
{ Left: Node<'a> option
Right: Node<'a> option
Data: 'a }
let left (node: Node<'a>) = node.Left
let right (node: Node<'a>) = node.Right
let data (node: Node<'a>) : 'a = node.Data
let rec insertNode (root: Node<'a> option) (nextValue: 'a) : Node<'a> =
match root with
| Some root -> if nextValue <= root.Data then { root with Left = Some(insertNode root.Left nextValue) }
elif nextValue > root.Data then { root with Right = Some(insertNode root.Right nextValue) }
else root
| None -> { Left=None; Right=None; Data=nextValue }
let create (items: 'a list) : Node<'a> =
items
|> List.fold (fun (acc: Option<Node<'a>>) (item: 'a) -> Some(insertNode acc item)) None
|> function
| None -> failwith "Failed to construct binary tree. You must pass a valid item list."
| Some root -> root
let sortedData (node: Node<'a>) : ('a list) =
let rec traverse (acc: 'a list) (node: Node<'a>) =
match (node.Left, node.Right) with
| Some left, Some right -> seq {
yield! node.Data::acc
yield! (traverse [] left)
yield! (traverse [] right)}
|> Seq.toList
| Some left, None -> traverse (node.Data::acc) left
| None, Some right -> traverse (node.Data::acc) right
| None, None -> node.Data::acc
List.sort (traverse [] node)
And the alternative implementation of sortedData
:
let sortedData (node: Node) : (int list) =
let rec traverse (acc: int list) (node: Node) =
match (node.Left, node.Right) with
| Some left, Some right -> (node.Data::acc)@(traverse [] left)@(traverse [] right)
| Some left, None -> traverse (node.Data::acc) left
| None, Some right -> traverse (node.Data::acc) right
| None, None -> node.Data::acc
List.sort (traverse [] node)