engineer at NoRedInk
@t_kelly9
module BinaryTree
exposing
( BinaryTree
, new
, empty
, member
, insert
, remove
)
Strategy:
type alias BinaryTree comparable =
Array (Maybe comparable)
leftChild : Int -> Int
leftChild index =
2 * index + 1
rightChild : Int -> Int
rightChild index =
2 * index + 2
empty : BinaryTree comparable
empty =
Array.empty
new : comparable -> BinaryTree comparable
new value =
Array.initialize 1 (\_ -> Just value)
member : comparable -> BinaryTree comparable -> Bool
member =
memberAt 0
memberAt : Int -> comparable -> BinaryTree comparable -> Bool
memberAt index value tree =
case Array.get index tree of
Just (Just nodeValue) ->
if value < nodeValue then
memberAt (leftChild index) value tree
else if value > nodeValue then
memberAt (rightChild index) value tree
else
value == nodeValue
_ ->
False
insert : comparable -> BinaryTree comparable -> BinaryTree comparable
insert =
insertAt 0
insertAt : Int -> comparable -> BinaryTree comparable -> BinaryTree comparable
insertAt index value tree =
case Array.get index tree of
Just (Just nodeValue) ->
if value < nodeValue then
insertAt (leftChild index) value tree
else if value > nodeValue then
insertAt (rightChild index) value tree
else
tree
Just Nothing ->
Array.set index (Just value) tree
Nothing ->
fillWithEmptiesUntil index value tree
fillWithEmptiesUntil : Int -> comparable -> BinaryTree comparable -> BinaryTree comparable
fillWithEmptiesUntil index value tree =
Array.repeat (index - Array.length tree) Nothing
|> Array.push (Just value)
|> Array.append tree
remove : comparable -> BinaryTree comparable -> BinaryTree comparable
remove =
removeAt 0
removeAt : Int -> comparable -> BinaryTree comparable -> BinaryTree comparable
removeAt index value tree =
case Array.get index tree of
Just (Just nodeValue) ->
if value < nodeValue then
removeAt (leftChild index) value tree
else if value > nodeValue then
removeAt (rightChild index) value tree
else
case ( Array.get (leftChild index) tree, Array.get (rightChild index) tree ) of
( Just (Just leftValue), _ ) ->
Array.set index (Just leftValue) (removeAt (leftChild index) leftValue tree)
( _, Just (Just rightValue) ) ->
Array.set index (Just rightValue) (removeAt (rightChild index) rightValue tree)
( _, _ ) ->
Array.set index Nothing tree
_ ->
tree
type alias BinaryTree comparable =
Array (Maybe comparable)
type alias BinaryTree comparable =
Array (Maybe comparable)
empty : BinaryTree comparable
empty =
Array.empty
new : comparable -> BinaryTree comparable
new value =
Array.initialize 1 (\_ -> Just value)
member : comparable -> BinaryTree comparable -> Bool
member =
memberAt 0
memberAt : Int -> comparable -> BinaryTree comparable -> Bool
memberAt index value tree =
case Array.get index tree of
Just (Just nodeValue) ->
if value < nodeValue then
memberAt (leftChild index) value tree
else if value > nodeValue then
memberAt (rightChild index) value tree
else
value == nodeValue
_ ->
False
insert : comparable -> BinaryTree comparable -> BinaryTree comparable
insert =
insertAt 0
insertAt : Int -> comparable -> BinaryTree comparable -> BinaryTree comparable
insertAt index value tree =
case Array.get index tree of
Just (Just nodeValue) ->
if value < nodeValue then
insertAt (leftChild index) value tree
else if value > nodeValue then
insertAt (rightChild index) value tree
else
tree
Just Nothing ->
Array.set index (Just value) tree
Nothing ->
.... uh oh!!!
insert : comparable -> BinaryTree comparable -> BinaryTree comparable
insert =
insertAt 0
insertAt : Int -> comparable -> BinaryTree comparable -> BinaryTree comparable
insertAt index value tree =
case Array.get index tree of
Just (Just nodeValue) ->
if value < nodeValue then
insertAt (leftChild index) value tree
else if value > nodeValue then
insertAt (rightChild index) value tree
else
tree
Just Nothing ->
Array.set index (Just value) tree
Nothing ->
fillWithEmptiesUntil index value tree
fillWithEmptiesUntil : Int -> comparable -> BinaryTree comparable -> BinaryTree comparable
fillWithEmptiesUntil index value tree =
Array.repeat (index - Array.length tree) Nothing
|> Array.push (Just value)
|> Array.append tree
remove : comparable -> BinaryTree comparable -> BinaryTree comparable
remove =
removeAt 0
removeAt : Int -> comparable -> BinaryTree comparable -> BinaryTree comparable
removeAt index value tree =
case Array.get index tree of
Just (Just nodeValue) ->
if value < nodeValue then
removeAt (leftChild index) value tree
else if value > nodeValue then
removeAt (rightChild index) value tree
else
case ( Array.get (leftChild index) tree, Array.get (rightChild index) tree ) of
( Just (Just leftValue), _ ) ->
Array.set index (Just leftValue) (removeAt (leftChild index) leftValue tree)
( _, Just (Just rightValue) ) ->
Array.set index (Just rightValue) (removeAt (rightChild index) rightValue tree)
( _, _ ) ->
Array.set index Nothing tree
_ ->
tree
This helps make our code more readable by cutting out the bananas `Just Nothing` business, but it doesn't solve all of our problems with this implementation.
type alias BinaryTree comparable =
Array (Node comparable)
type Node comparable
= Node comparable
| Empty
insertAt : Int -> comparable -> BinaryTree comparable -> BinaryTree comparable
insertAt index value tree =
case Array.get index tree of
Just (Node nodeValue) ->
if value < nodeValue then
insertAt (leftChild index) value tree
else if value > nodeValue then
insertAt (rightChild index) value tree
else
tree
Just Empty ->
Array.set index (Node value) tree
Nothing ->
fillWithEmptiesUntil index value tree
removeAt : Int -> comparable -> BinaryTree comparable -> BinaryTree comparable
removeAt index value tree =
case Array.get index tree of
Just (Node nodeValue) ->
if value < nodeValue then
removeAt (leftChild index) value tree
else if value > nodeValue then
removeAt (rightChild index) value tree
else
case ( Array.get (leftChild index) tree, Array.get (rightChild index) tree ) of
( Just (Node leftValue), _ ) ->
Array.set index (Node leftValue) (removeAt (leftChild index) leftValue tree)
( _, Just (Node rightValue) ) ->
Array.set index (Node rightValue) (removeAt (rightChild index) rightValue tree)
( _, _ ) ->
Array.set index Empty tree
_ ->
tree
Strategy:
type alias BinaryTree comparable =
Dict Int comparable
empty : BinaryTree comparable
empty =
Dict.empty
member : comparable -> BinaryTree comparable -> Bool
member =
memberAt 0
memberAt : Int -> comparable -> BinaryTree comparable -> Bool
memberAt index value tree =
case Dict.get index tree of
Just nodeValue ->
if value < nodeValue then
memberAt (leftChild index) value tree
else if value > nodeValue then
memberAt (rightChild index) value tree
else
value == nodeValue
_ ->
False
insert : comparable -> BinaryTree comparable -> BinaryTree comparable
insert =
insertAt 0
insertAt : Int -> comparable -> BinaryTree comparable -> BinaryTree comparable
insertAt index value tree =
case Dict.get index tree of
Just nodeValue ->
if value < nodeValue then
insertAt (leftChild index) value tree
else if value > nodeValue then
insertAt (rightChild index) value tree
else
tree
Nothing ->
Dict.insert index value tree
remove : comparable -> BinaryTree comparable -> BinaryTree comparable
remove =
removeAt 0
removeAt : Int -> comparable -> BinaryTree comparable -> BinaryTree comparable
removeAt index value tree =
case Dict.get index tree of
Just nodeValue ->
if value < nodeValue then
removeAt (leftChild index) value tree
else if value > nodeValue then
removeAt (rightChild index) value tree
else
case ( Dict.get (leftChild index) tree, Dict.get (rightChild index) tree ) of
( Just leftValue, _ ) ->
Dict.insert index leftValue (removeAt (leftChild index) leftValue tree)
( _, Just rightValue ) ->
Dict.insert index rightValue (removeAt (rightChild index) rightValue tree)
( Nothing, Nothing ) ->
Dict.remove index tree
_ ->
tree
leftChild : Int -> Int
leftChild index =
2 * index + 1
rightChild : Int -> Int
rightChild index =
2 * index + 2
new : comparable -> BinaryTree comparable
new value =
Dict.singleton 0 value
type alias BinaryTree comparable =
Dict Int comparable
empty : BinaryTree comparable
empty =
Dict.empty
new : comparable -> BinaryTree comparable
new value =
Dict.singleton 0 value
member : comparable -> BinaryTree comparable -> Bool
member =
memberAt 0
member : comparable -> BinaryTree comparable -> Bool
member =
memberAt 0
memberAt : Int -> comparable -> BinaryTree comparable -> Bool
memberAt index value tree =
case Dict.get index tree of
Just nodeValue ->
if value < nodeValue then
memberAt (leftChild index) value tree
else if value > nodeValue then
memberAt (rightChild index) value tree
else
value == nodeValue
_ ->
False
insert : comparable -> BinaryTree comparable -> BinaryTree comparable
insert =
insertAt 0
insertAt : Int -> comparable -> BinaryTree comparable -> BinaryTree comparable
insertAt index value tree =
case Dict.get index tree of
Just nodeValue ->
if value < nodeValue then
insertAt (leftChild index) value tree
else if value > nodeValue then
insertAt (rightChild index) value tree
else
tree
Nothing ->
Dict.insert index value tree
remove : comparable -> BinaryTree comparable -> BinaryTree comparable
remove =
removeAt 0
removeAt : Int -> comparable -> BinaryTree comparable -> BinaryTree comparable
removeAt index value tree =
case Dict.get index tree of
Just nodeValue ->
if value < nodeValue then
removeAt (leftChild index) value tree
else if value > nodeValue then
removeAt (rightChild index) value tree
else
case ( Dict.get (leftChild index) tree, Dict.get (rightChild index) tree ) of
( Just leftValue, _ ) ->
Dict.insert index leftValue (removeAt (leftChild index) leftValue tree)
( _, Just rightValue ) ->
Dict.insert index rightValue (removeAt (rightChild index) rightValue tree)
( Nothing, Nothing ) ->
Dict.remove index tree
_ ->
tree
Strategy:
type BinaryTree comparable
= Node
{ value : comparable
, left : BinaryTree comparable
, right : BinaryTree comparable
}
| Empty
empty : BinaryTree comparable
empty =
Empty
new : comparable -> BinaryTree comparable
new value =
Node
{ value = value
, left = Empty
, right = Empty
}
member : comparable -> BinaryTree comparable -> Bool
member value tree =
case tree of
Node node ->
if value < node.value then
member value node.left
else if value > node.value then
member value node.right
else
value == node.value
Empty ->
False
insert : comparable -> BinaryTree comparable -> BinaryTree comparable
insert value tree =
case tree of
Node node ->
if value < node.value then
Node
{ value = node.value
, left = insert value node.left
, right = node.right
}
else if value > node.value then
Node
{ value = node.value
, left = node.left
, right = insert value node.right
}
else
Node node
Empty ->
new value
remove : comparable -> BinaryTree comparable -> BinaryTree comparable
remove value tree =
case tree of
Node node ->
if value < node.value then
Node
{ value = node.value
, left = remove value node.left
, right = node.right
}
else if value > node.value then
Node
{ value = node.value
, left = node.left
, right = remove value node.right
}
else
case ( node.left, node.right ) of
-- No children to consider
( Empty, Empty ) ->
empty
-- One child, on the right
( Empty, Node rightTree ) ->
Node rightTree
-- One child, on the left
( Node leftTree, Empty ) ->
Node leftTree
-- Two children, right and left
( Node leftTree, Node rightTree ) ->
Node
{ value = rightTree.value
, left = Node leftTree
, right = remove rightTree.value (Node rightTree)
}
Empty ->
Empty
type BinaryTree comparable
= Node
{ value : comparable
, left : BinaryTree comparable
, right : BinaryTree comparable
}
| Empty
type BinaryTree comparable
= Node
{ value : comparable
, left : BinaryTree comparable
, right : BinaryTree comparable
}
| Empty
empty : BinaryTree comparable
empty =
Empty
new : comparable -> BinaryTree comparable
new value =
Node
{ value = value
, left = Empty
, right = Empty
}
insert : comparable -> BinaryTree comparable -> BinaryTree comparable
insert value tree =
case tree of
Node node ->
if value < node.value then
Node
{ value = node.value
, left = insert value node.left
, right = node.right
}
else if value > node.value then
Node
{ value = node.value
, left = node.left
, right = insert value node.right
}
else
Node node
Empty ->
new value
remove : comparable -> BinaryTree comparable -> BinaryTree comparable
remove value tree =
case tree of
Node node ->
if value < node.value then
Node
{ value = node.value
, left = remove value node.left
, right = node.right
}
else if value > node.value then
Node
{ value = node.value
, left = node.left
, right = remove value node.right
}
else
case ( node.left, node.right ) of
( Empty, Empty ) ->
empty
( Empty, Node rightTree ) ->
Node rightTree
( Node leftTree, Empty ) ->
Node leftTree
( Node leftTree, Node rightTree ) ->
Node
{ value = rightTree.value
, left = Node leftTree
, right = remove rightTree.value (Node rightTree)
}
Empty ->
Empty
Strategy:
type BinaryTree comparable
= Node comparable (BinaryTree comparable) (BinaryTree comparable)
| Empty
empty : BinaryTree comparable
empty =
Empty
new : comparable -> BinaryTree comparable
new value =
Node value empty empty
member : comparable -> BinaryTree comparable -> Bool
member value tree =
case tree of
Node nodeValue left right ->
if value < nodeValue then
member value left
else if value > nodeValue then
member value right
else
value == nodeValue
Empty ->
False
insert : comparable -> BinaryTree comparable -> BinaryTree comparable
insert value tree =
case tree of
Node nodeValue left right ->
if value < nodeValue then
Node nodeValue (insert value left) right
else if value > nodeValue then
Node nodeValue left (insert value right)
else
Node nodeValue left right
Empty ->
new value
remove : comparable -> BinaryTree comparable -> BinaryTree comparable
remove value tree =
case tree of
Node nodeValue left right ->
if value < nodeValue then
Node nodeValue (remove value left) right
else if value > nodeValue then
Node nodeValue left (remove value left)
else
case ( left, right ) of
( Empty, Empty ) ->
empty
( Empty, (Node _ _ _) as rightChild ) ->
rightChild
( (Node _ _ _) as leftChild, Empty ) ->
leftChild
( Node _ _ _, (Node rightChildValue _ _) as rightChild ) ->
Node rightChildValue left (remove value rightChild)
Empty ->
Empty
type BinaryTree comparable
= Node comparable (BinaryTree comparable) (BinaryTree comparable)
| Empty
type BinaryTree comparable
= Node comparable (BinaryTree comparable) (BinaryTree comparable)
| Empty
empty : BinaryTree comparable
empty =
Empty
new : comparable -> BinaryTree comparable
new value =
Node value empty empty
insert : comparable -> BinaryTree comparable -> BinaryTree comparable
insert value tree =
case tree of
Node nodeValue left right ->
if value < nodeValue then
Node nodeValue (insert value left) right
else if value > nodeValue then
Node nodeValue left (insert value right)
else
Node nodeValue left right
Empty ->
new value
member : comparable -> BinaryTree comparable -> Bool
member value tree =
case tree of
Node nodeValue left right ->
if value < nodeValue then
member value left
else if value > nodeValue then
member value right
else
value == nodeValue
Empty ->
False
remove : comparable -> BinaryTree comparable -> BinaryTree comparable
remove value tree =
case tree of
Node nodeValue left right ->
if value < nodeValue then
Node nodeValue (remove value left) right
else if value > nodeValue then
Node nodeValue left (remove value left)
else
case ( left, right ) of
( Empty, Empty ) ->
empty
( Empty, (Node _ _ _) as rightChild ) ->
rightChild
( (Node _ _ _) as leftChild, Empty ) ->
leftChild
( Node _ _ _, (Node rightChildValue _ _) as rightChild ) ->
Node rightChildValue left (remove value rightChild)
Empty ->
Empty
@t_kelly9
type alias BinaryTree comparable =
Array (Node comparable)
type Node comparable
= Node comparable
| Empty
empty : BinaryTree comparable
empty =
Array.empty
new : comparable -> BinaryTree comparable
new value =
Array.initialize 1 (\_ -> Node value)
member : comparable -> BinaryTree comparable -> Bool
member =
memberAt 0
memberAt : Int -> comparable -> BinaryTree comparable -> Bool
memberAt index value tree =
case Array.get index tree of
Just (Node nodeValue) ->
if value < nodeValue then
memberAt (leftChild index) value tree
else if value > nodeValue then
memberAt (rightChild index) value tree
else
value == nodeValue
_ ->
False
insert : comparable -> BinaryTree comparable -> BinaryTree comparable
insert =
insertAt 0
insertAt : Int -> comparable -> BinaryTree comparable -> BinaryTree comparable
insertAt index value tree =
case Array.get index tree of
Just (Node nodeValue) ->
if value < nodeValue then
insertAt (leftChild index) value tree
else if value > nodeValue then
insertAt (rightChild index) value tree
else
tree
Just Empty ->
Array.set index (Node value) tree
Nothing ->
fillWithEmptiesUntil index value tree
fillWithEmptiesUntil : Int -> comparable -> BinaryTree comparable -> BinaryTree comparable
fillWithEmptiesUntil index value tree =
Array.repeat (index - Array.length tree) Empty
|> Array.push (Node value)
|> Array.append tree
remove : comparable -> BinaryTree comparable -> BinaryTree comparable
remove =
removeAt 0
removeAt : Int -> comparable -> BinaryTree comparable -> BinaryTree comparable
removeAt index value tree =
case Array.get index tree of
Just (Node nodeValue) ->
if value < nodeValue then
removeAt (leftChild index) value tree
else if value > nodeValue then
removeAt (rightChild index) value tree
else
case ( Array.get (leftChild index) tree, Array.get (rightChild index) tree ) of
( Just (Node leftValue), _ ) ->
Array.set index (Node leftValue) (removeAt (leftChild index) leftValue tree)
( _, Just (Node rightValue) ) ->
Array.set index (Node rightValue) (removeAt (rightChild index) rightValue tree)
( _, _ ) ->
Array.set index Empty tree
_ ->
tree
leftChild : Int -> Int
leftChild index =
2 * index + 1
rightChild : Int -> Int
rightChild index =
2 * index + 2
type alias BinaryTree comparable =
Dict Int comparable
empty : BinaryTree comparable
empty =
Dict.empty
new : comparable -> BinaryTree comparable
new value =
Dict.singleton 0 value
member : comparable -> BinaryTree comparable -> Bool
member =
memberAt 0
memberAt : Int -> comparable -> BinaryTree comparable -> Bool
memberAt index value tree =
case Dict.get index tree of
Just nodeValue ->
if value < nodeValue then
memberAt (leftChild index) value tree
else if value > nodeValue then
memberAt (rightChild index) value tree
else
value == nodeValue
_ ->
False
insert : comparable -> BinaryTree comparable -> BinaryTree comparable
insert =
insertAt 0
insertAt : Int -> comparable -> BinaryTree comparable -> BinaryTree comparable
insertAt index value tree =
case Dict.get index tree of
Just nodeValue ->
if value < nodeValue then
insertAt (leftChild index) value tree
else if value > nodeValue then
insertAt (rightChild index) value tree
else
tree
Nothing ->
Dict.insert index value tree
remove : comparable -> BinaryTree comparable -> BinaryTree comparable
remove =
removeAt 0
removeAt : Int -> comparable -> BinaryTree comparable -> BinaryTree comparable
removeAt index value tree =
case Dict.get index tree of
Just nodeValue ->
if value < nodeValue then
removeAt (leftChild index) value tree
else if value > nodeValue then
removeAt (rightChild index) value tree
else
case ( Dict.get (leftChild index) tree, Dict.get (rightChild index) tree ) of
( Just leftValue, _ ) ->
Dict.insert index leftValue (removeAt (leftChild index) leftValue tree)
( _, Just rightValue ) ->
Dict.insert index rightValue (removeAt (rightChild index) rightValue tree)
( Nothing, Nothing ) ->
Dict.remove index tree
_ ->
tree
leftChild : Int -> Int
leftChild index =
2 * index + 1
rightChild : Int -> Int
rightChild index =
2 * index + 2
type BinaryTree comparable
= Node
{ value : comparable
, left : BinaryTree comparable
, right : BinaryTree comparable
}
| Empty
empty : BinaryTree comparable
empty =
Empty
new : comparable -> BinaryTree comparable
new value =
Node
{ value = value
, left = Empty
, right = Empty
}
member : comparable -> BinaryTree comparable -> Bool
member value tree =
case tree of
Node node ->
if value < node.value then
member value node.left
else if value > node.value then
member value node.right
else
value == node.value
Empty ->
False
insert : comparable -> BinaryTree comparable -> BinaryTree comparable
insert value tree =
case tree of
Node node ->
if value < node.value then
Node
{ value = node.value
, left = insert value node.left
, right = node.right
}
else if value > node.value then
Node
{ value = node.value
, left = node.left
, right = insert value node.right
}
else
Node node
Empty ->
new value
remove : comparable -> BinaryTree comparable -> BinaryTree comparable
remove value tree =
case tree of
Node node ->
if value < node.value then
Node
{ value = node.value
, left = remove value node.left
, right = node.right
}
else if value > node.value then
Node
{ value = node.value
, left = node.left
, right = remove value node.right
}
else
case ( node.left, node.right ) of
( Empty, Empty ) ->
empty
( Empty, Node rightTree ) ->
Node rightTree
( Node leftTree, Empty ) ->
Node leftTree
( Node leftTree, Node rightTree ) ->
Node
{ value = rightTree.value
, left = Node leftTree
, right = remove rightTree.value (Node rightTree)
}
Empty ->
Empty
type BinaryTree comparable
= Node comparable (BinaryTree comparable) (BinaryTree comparable)
| Empty
empty : BinaryTree comparable
empty =
Empty
new : comparable -> BinaryTree comparable
new value =
Node value empty empty
member : comparable -> BinaryTree comparable -> Bool
member value tree =
case tree of
Node nodeValue left right ->
if value < nodeValue then
member value left
else if value > nodeValue then
member value right
else
value == nodeValue
Empty ->
False
insert : comparable -> BinaryTree comparable -> BinaryTree comparable
insert value tree =
case tree of
Node nodeValue left right ->
if value < nodeValue then
Node nodeValue (insert value left) right
else if value > nodeValue then
Node nodeValue left (insert value right)
else
Node nodeValue left right
Empty ->
new value
remove : comparable -> BinaryTree comparable -> BinaryTree comparable
remove value tree =
case tree of
Node nodeValue left right ->
if value < nodeValue then
Node nodeValue (remove value left) right
else if value > nodeValue then
Node nodeValue left (remove value left)
else
case ( left, right ) of
( Empty, Empty ) ->
empty
( Empty, (Node _ _ _) as rightChild ) ->
rightChild
( (Node _ _ _) as leftChild, Empty ) ->
leftChild
( Node _ _ _, (Node rightChildValue _ _) as rightChild ) ->
Node rightChildValue left (remove value rightChild)
Empty ->
Empty
@t_kelly9