From 43e810024cce9e979288f2970e3b705e6c0dc089 Mon Sep 17 00:00:00 2001 From: mjh <61671361+mjh316@users.noreply.github.com> Date: Wed, 20 Apr 2022 06:49:18 -0700 Subject: [PATCH] datatypes: fix bst child access, when .root is 0 (#14080) --- vlib/datatypes/bstree.v | 20 ++++++++++- vlib/datatypes/bstree_test.v | 2 ++ .../tests/check_err_msg_with_generics.out | 36 +++++++++---------- 3 files changed, 39 insertions(+), 19 deletions(-) diff --git a/vlib/datatypes/bstree.v b/vlib/datatypes/bstree.v index 6d56d3ea54..93d65e5ccb 100644 --- a/vlib/datatypes/bstree.v +++ b/vlib/datatypes/bstree.v @@ -113,7 +113,7 @@ fn (bst &BSTree) contains_helper(node &BSTreeNode, value T) bool { // remove removes an element with `value` from the BST. pub fn (mut bst BSTree) remove(value T) bool { - if bst.root == 0 { + if bst.is_empty() { return false } return bst.remove_helper(mut bst.root, value, false) @@ -153,6 +153,9 @@ fn (mut bst BSTree) remove_helper(mut node BSTreeNode, value T, left bool) // get_max_from_right returns the max element of the BST following the right branch. fn (bst &BSTree) get_max_from_right(node &BSTreeNode) &BSTreeNode { + if node == 0 { + return new_none_node(false) + } right_node := node.right if right_node == 0 || !right_node.is_init { return node @@ -162,6 +165,9 @@ fn (bst &BSTree) get_max_from_right(node &BSTreeNode) &BSTreeNode { // get_min_from_left returns the min element of the BST by following the left branch. fn (bst &BSTree) get_min_from_left(node &BSTreeNode) &BSTreeNode { + if node == 0 { + return new_none_node(false) + } left_node := node.left if left_node == 0 || !left_node.is_init { return node @@ -251,6 +257,9 @@ fn (bst &BSTree) get_node(node &BSTreeNode, value T) &BSTreeNode { // left_value, exist := bst.to_left(10) //``` pub fn (bst &BSTree) to_left(value T) ?T { + if bst.is_empty() { + return none + } node := bst.get_node(bst.root, value) if !node.is_init { return none @@ -267,6 +276,9 @@ pub fn (bst &BSTree) to_left(value T) ?T { // left_value, exist := bst.to_right(10) //``` pub fn (bst &BSTree) to_right(value T) ?T { + if bst.is_empty() { + return none + } node := bst.get_node(bst.root, value) if !node.is_init { return none @@ -278,6 +290,9 @@ pub fn (bst &BSTree) to_right(value T) ?T { // max return the max element inside the BST. // Time complexity O(N) if the BST is not balanced pub fn (bst &BSTree) max() ?T { + if bst.is_empty() { + return none + } max := bst.get_max_from_right(bst.root) if !max.is_init { return none @@ -288,6 +303,9 @@ pub fn (bst &BSTree) max() ?T { // min return the minimum element in the BST. // Time complexity O(N) if the BST is not balanced. pub fn (bst &BSTree) min() ?T { + if bst.is_empty() { + return none + } min := bst.get_min_from_left(bst.root) if !min.is_init { return none diff --git a/vlib/datatypes/bstree_test.v b/vlib/datatypes/bstree_test.v index 6ceabd6fbd..6309afdde1 100644 --- a/vlib/datatypes/bstree_test.v +++ b/vlib/datatypes/bstree_test.v @@ -116,6 +116,7 @@ fn test_remove_from_bst_two() { // check if we are able to get the max from the BST. fn test_get_max_in_bst() { mut bst := BSTree{} + assert (bst.max() or { -1 }) == -1 assert bst.insert(10) assert bst.insert(20) 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. fn test_get_min_in_bst() { mut bst := BSTree{} + assert (bst.min() or { -1 }) == -1 assert bst.insert(10) assert bst.insert(20) assert bst.insert(21) diff --git a/vlib/v/checker/tests/check_err_msg_with_generics.out b/vlib/v/checker/tests/check_err_msg_with_generics.out index f4587a294a..53e78ea384 100644 --- a/vlib/v/checker/tests/check_err_msg_with_generics.out +++ b/vlib/v/checker/tests/check_err_msg_with_generics.out @@ -4,24 +4,24 @@ vlib/v/checker/tests/check_err_msg_with_generics.vv:15:10: error: cannot cast st 15 | println(int(typ)) | ~~~~~~~~ 16 | } -vlib/datatypes/bstree.v:190:17: error: cannot append `T` to `[]T` - 188 | } - 189 | bst.in_order_traversal_helper(node.left, mut result) - 190 | result << node.value +vlib/datatypes/bstree.v:196:17: error: cannot append `T` to `[]T` + 194 | } + 195 | bst.in_order_traversal_helper(node.left, mut result) + 196 | result << node.value | ~~~~~ - 191 | bst.in_order_traversal_helper(node.right, mut result) - 192 | } -vlib/datatypes/bstree.v:210:17: error: cannot append `T` to `[]T` - 208 | bst.post_order_traversal_helper(node.left, mut result) - 209 | bst.post_order_traversal_helper(node.right, mut result) - 210 | result << node.value + 197 | bst.in_order_traversal_helper(node.right, mut result) + 198 | } +vlib/datatypes/bstree.v:216:17: error: cannot append `T` to `[]T` + 214 | bst.post_order_traversal_helper(node.left, mut result) + 215 | bst.post_order_traversal_helper(node.right, mut result) + 216 | result << node.value | ~~~~~ - 211 | } - 212 | -vlib/datatypes/bstree.v:226:17: error: cannot append `T` to `[]T` - 224 | return - 225 | } - 226 | result << node.value + 217 | } + 218 | +vlib/datatypes/bstree.v:232:17: error: cannot append `T` to `[]T` + 230 | return + 231 | } + 232 | result << node.value | ~~~~~ - 227 | bst.pre_order_traversal_helper(node.left, mut result) - 228 | bst.pre_order_traversal_helper(node.right, mut result) + 233 | bst.pre_order_traversal_helper(node.left, mut result) + 234 | bst.pre_order_traversal_helper(node.right, mut result) \ No newline at end of file