example: improve binary search tree example (#10226)

pull/10233/head
Ruofan XU 2021-05-28 01:13:02 +08:00 committed by GitHub
parent 2b62dca000
commit 4e55b9c08e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 32 additions and 24 deletions

View File

@ -2367,7 +2367,7 @@ type Tree = Empty | Node
// sum up all node values
fn sum(tree Tree) f64 {
return match tree {
Empty { f64(0) } // TODO: as match gets smarter just remove f64()
Empty { 0 }
Node { tree.value + sum(tree.left) + sum(tree.right) }
}
}

View File

@ -1,8 +1,6 @@
// Binary Search Tree example by @SleepyRoy
// TODO: make Node.value generic once it's robust enough
// TODO: `return match` instead of returns everywhere inside match
struct Empty {}
struct Node {
@ -16,20 +14,19 @@ type Tree = Empty | Node
// return size(number of nodes) of BST
fn size(tree Tree) int {
return match tree {
// TODO: remove int() once match gets smarter
Empty { int(0) }
Empty { 0 }
Node { 1 + size(tree.left) + size(tree.right) }
}
}
// insert a value to BST
fn insert(tree Tree, x f64) Tree {
match tree {
return match tree {
Empty {
return Node{x, tree, tree}
Node{x, tree, tree}
}
Node {
return if x == tree.value {
if x == tree.value {
tree
} else if x < tree.value {
Node{
@ -48,12 +45,12 @@ fn insert(tree Tree, x f64) Tree {
// whether able to find a value in BST
fn search(tree Tree, x f64) bool {
match tree {
return match tree {
Empty {
return false
false
}
Node {
return if x == tree.value {
if x == tree.value {
true
} else if x < tree.value {
search(tree.left, x)
@ -66,21 +63,29 @@ fn search(tree Tree, x f64) bool {
// find the minimal value of a BST
fn min(tree Tree) f64 {
match tree {
Empty { return 1e100 }
Node { return if tree.value < min(tree.left) { tree.value } else { min(tree.left) } }
return match tree {
Empty {
1e100
}
Node {
if tree.value < min(tree.left) {
tree.value
} else {
min(tree.left)
}
}
}
}
// delete a value in BST (if nonexistant do nothing)
fn delete(tree Tree, x f64) Tree {
match tree {
return match tree {
Empty {
return tree
tree
}
Node {
if tree.left is Node && tree.right is Node {
return if x < tree.value {
if x < tree.value {
Node{
...tree
left: delete(tree.left, x)
@ -98,7 +103,7 @@ fn delete(tree Tree, x f64) Tree {
}
}
} else if tree.left is Node {
return if x == tree.value {
if x == tree.value {
tree.left
} else {
Node{
@ -108,9 +113,9 @@ fn delete(tree Tree, x f64) Tree {
}
} else {
if x == tree.value {
return tree.right
tree.right
} else {
return Node{
Node{
...tree
right: delete(tree.right, x)
}

View File

@ -11,8 +11,7 @@ type Tree = Empty | Node
// return size(number of nodes) of BST
fn size(tree Tree) int {
return match tree {
// TODO: remove int() once match gets smarter
Empty { int(0) }
Empty { 0 }
Node { 1 + size(tree.left) + size(tree.right) }
}
}
@ -131,20 +130,24 @@ fn test_match_with_complex_sumtype_exprs() {
}
print('[1] after insertion tree size is ') // 11
println(size(tree))
assert size(tree) == 11
del := [-0.3, 0.0, 0.3, 0.6, 1.0, 1.5]
for i in del {
tree = delete(tree, i)
}
print('[2] after deletion tree size is ') // 7
print(size(tree))
print(', and these elements were deleted: ') // 0.0 0.3 0.6 1.0
assert size(tree) == 7
print(', and these elements were deleted: ') // 0.0 0.3 0.6 1.0
mut deleted := []f64{}
for i in input {
if !search(tree, i) {
print(i)
print(' ')
deleted << i
}
}
deleted.sort()
assert deleted == [0.0, 0.3, 0.6, 1.0]
println('')
assert true
}