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 // sum up all node values
fn sum(tree Tree) f64 { fn sum(tree Tree) f64 {
return match tree { 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) } Node { tree.value + sum(tree.left) + sum(tree.right) }
} }
} }

View File

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

View File

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