datatypes: fix bst child access, when .root is 0 (#14080)

mjh 2022-04-20 06:49:18 -07:00 committed by Jef Roosens
parent 1cb4fe5a0a
commit 43e810024c
Signed by: Jef Roosens
GPG Key ID: B75D4F293C7052DB
3 changed files with 39 additions and 19 deletions

View File

@ -113,7 +113,7 @@ fn (bst &BSTree<T>) contains_helper(node &BSTreeNode<T>, value T) bool {
// remove removes an element with `value` from the BST. // remove removes an element with `value` from the BST.
pub fn (mut bst BSTree<T>) remove(value T) bool { pub fn (mut bst BSTree<T>) remove(value T) bool {
if bst.root == 0 { if bst.is_empty() {
return false return false
} }
return bst.remove_helper(mut bst.root, value, false) return bst.remove_helper(mut bst.root, value, false)
@ -153,6 +153,9 @@ fn (mut bst BSTree<T>) remove_helper(mut node BSTreeNode<T>, value T, left bool)
// get_max_from_right returns the max element of the BST following the right branch. // get_max_from_right returns the max element of the BST following the right branch.
fn (bst &BSTree<T>) get_max_from_right(node &BSTreeNode<T>) &BSTreeNode<T> { fn (bst &BSTree<T>) get_max_from_right(node &BSTreeNode<T>) &BSTreeNode<T> {
if node == 0 {
return new_none_node<T>(false)
}
right_node := node.right right_node := node.right
if right_node == 0 || !right_node.is_init { if right_node == 0 || !right_node.is_init {
return node return node
@ -162,6 +165,9 @@ fn (bst &BSTree<T>) get_max_from_right(node &BSTreeNode<T>) &BSTreeNode<T> {
// get_min_from_left returns the min element of the BST by following the left branch. // get_min_from_left returns the min element of the BST by following the left branch.
fn (bst &BSTree<T>) get_min_from_left(node &BSTreeNode<T>) &BSTreeNode<T> { fn (bst &BSTree<T>) get_min_from_left(node &BSTreeNode<T>) &BSTreeNode<T> {
if node == 0 {
return new_none_node<T>(false)
}
left_node := node.left left_node := node.left
if left_node == 0 || !left_node.is_init { if left_node == 0 || !left_node.is_init {
return node return node
@ -251,6 +257,9 @@ fn (bst &BSTree<T>) get_node(node &BSTreeNode<T>, value T) &BSTreeNode<T> {
// left_value, exist := bst.to_left(10) // left_value, exist := bst.to_left(10)
//``` //```
pub fn (bst &BSTree<T>) to_left(value T) ?T { pub fn (bst &BSTree<T>) to_left(value T) ?T {
if bst.is_empty() {
return none
}
node := bst.get_node(bst.root, value) node := bst.get_node(bst.root, value)
if !node.is_init { if !node.is_init {
return none return none
@ -267,6 +276,9 @@ pub fn (bst &BSTree<T>) to_left(value T) ?T {
// left_value, exist := bst.to_right(10) // left_value, exist := bst.to_right(10)
//``` //```
pub fn (bst &BSTree<T>) to_right(value T) ?T { pub fn (bst &BSTree<T>) to_right(value T) ?T {
if bst.is_empty() {
return none
}
node := bst.get_node(bst.root, value) node := bst.get_node(bst.root, value)
if !node.is_init { if !node.is_init {
return none return none
@ -278,6 +290,9 @@ pub fn (bst &BSTree<T>) to_right(value T) ?T {
// max return the max element inside the BST. // max return the max element inside the BST.
// Time complexity O(N) if the BST is not balanced // Time complexity O(N) if the BST is not balanced
pub fn (bst &BSTree<T>) max() ?T { pub fn (bst &BSTree<T>) max() ?T {
if bst.is_empty() {
return none
}
max := bst.get_max_from_right(bst.root) max := bst.get_max_from_right(bst.root)
if !max.is_init { if !max.is_init {
return none return none
@ -288,6 +303,9 @@ pub fn (bst &BSTree<T>) max() ?T {
// min return the minimum element in the BST. // min return the minimum element in the BST.
// Time complexity O(N) if the BST is not balanced. // Time complexity O(N) if the BST is not balanced.
pub fn (bst &BSTree<T>) min() ?T { pub fn (bst &BSTree<T>) min() ?T {
if bst.is_empty() {
return none
}
min := bst.get_min_from_left(bst.root) min := bst.get_min_from_left(bst.root)
if !min.is_init { if !min.is_init {
return none return none

View File

@ -116,6 +116,7 @@ fn test_remove_from_bst_two() {
// check if we are able to get the max from the BST. // check if we are able to get the max from the BST.
fn test_get_max_in_bst() { fn test_get_max_in_bst() {
mut bst := BSTree<int>{} mut bst := BSTree<int>{}
assert (bst.max() or { -1 }) == -1
assert bst.insert(10) assert bst.insert(10)
assert bst.insert(20) assert bst.insert(20)
assert bst.insert(21) assert bst.insert(21)
@ -127,6 +128,7 @@ fn test_get_max_in_bst() {
// check if we are able to get the min from the BST. // check if we are able to get the min from the BST.
fn test_get_min_in_bst() { fn test_get_min_in_bst() {
mut bst := BSTree<int>{} mut bst := BSTree<int>{}
assert (bst.min() or { -1 }) == -1
assert bst.insert(10) assert bst.insert(10)
assert bst.insert(20) assert bst.insert(20)
assert bst.insert(21) assert bst.insert(21)

View File

@ -4,24 +4,24 @@ vlib/v/checker/tests/check_err_msg_with_generics.vv:15:10: error: cannot cast st
15 | println(int(typ)) 15 | println(int(typ))
| ~~~~~~~~ | ~~~~~~~~
16 | } 16 | }
vlib/datatypes/bstree.v:190:17: error: cannot append `T` to `[]T` vlib/datatypes/bstree.v:196:17: error: cannot append `T` to `[]T`
188 | } 194 | }
189 | bst.in_order_traversal_helper(node.left, mut result) 195 | bst.in_order_traversal_helper(node.left, mut result)
190 | result << node.value 196 | result << node.value
| ~~~~~ | ~~~~~
191 | bst.in_order_traversal_helper(node.right, mut result) 197 | bst.in_order_traversal_helper(node.right, mut result)
192 | } 198 | }
vlib/datatypes/bstree.v:210:17: error: cannot append `T` to `[]T` vlib/datatypes/bstree.v:216:17: error: cannot append `T` to `[]T`
208 | bst.post_order_traversal_helper(node.left, mut result) 214 | bst.post_order_traversal_helper(node.left, mut result)
209 | bst.post_order_traversal_helper(node.right, mut result) 215 | bst.post_order_traversal_helper(node.right, mut result)
210 | result << node.value 216 | result << node.value
| ~~~~~ | ~~~~~
211 | } 217 | }
212 | 218 |
vlib/datatypes/bstree.v:226:17: error: cannot append `T` to `[]T` vlib/datatypes/bstree.v:232:17: error: cannot append `T` to `[]T`
224 | return 230 | return
225 | } 231 | }
226 | result << node.value 232 | result << node.value
| ~~~~~ | ~~~~~
227 | bst.pre_order_traversal_helper(node.left, mut result) 233 | bst.pre_order_traversal_helper(node.left, mut result)
228 | bst.pre_order_traversal_helper(node.right, mut result) 234 | bst.pre_order_traversal_helper(node.right, mut result)