From eae4b20836f9b92fc207c1be5afccaac3d5a4d22 Mon Sep 17 00:00:00 2001 From: Tatiana Date: Mon, 2 Sep 2019 21:05:09 -0700 Subject: [PATCH 1/8] add and find methods implemenented --- lib/tree.rb | 35 +++++++++++++++++++++++++++++++---- test/tree_test.rb | 10 +++++----- 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/lib/tree.rb b/lib/tree.rb index c0d4b51..3cee5a3 100644 --- a/lib/tree.rb +++ b/lib/tree.rb @@ -16,16 +16,43 @@ def initialize @root = nil end - # Time Complexity: - # Space Complexity: + # Time Complexity: O(log n) - traverse only half of dataset + # Space Complexity: O - just adding a node def add(key, value) - raise NotImplementedError + if @root.nil? + new_tree_node = TreeNode.new(key, value) + @root = new_tree_node + return + end + + current_node = @root + add_node = TreeNode.new(key, value) + if add_node.key <= current_node.key + current_node.left = add_node + else + current_node.right = add_node + end end # Time Complexity: # Space Complexity: def find(key) - raise NotImplementedError + #begin with root node, returns value + return unless !@root.nil? + + current_node = @root + + while current_node != nil + if key == current_node.key + return current_node.value + elsif key <= current_node.key + current_node = current_node.left + else + current_node = current_node.right + end + end + + return nil end # Time Complexity: diff --git a/test/tree_test.rb b/test/tree_test.rb index 8811f14..e4e6e73 100644 --- a/test/tree_test.rb +++ b/test/tree_test.rb @@ -1,5 +1,5 @@ require_relative 'test_helper' - +require "minitest/skip_dsl" Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new @@ -31,7 +31,7 @@ expect(tree.find(50)).must_be_nil end - describe "inorder" do + xdescribe "inorder" do it "will give an empty array for an empty tree" do expect(tree.inorder).must_equal [] end @@ -45,7 +45,7 @@ end - describe "preorder" do + xdescribe "preorder" do it "will give an empty array for an empty tree" do expect(tree.preorder).must_equal [] end @@ -57,7 +57,7 @@ end end - describe "postorder" do + xdescribe "postorder" do it "will give an empty array for an empty tree" do expect(tree.postorder).must_equal [] end @@ -69,7 +69,7 @@ end end - describe "breadth first search" do + xdescribe "breadth first search" do it "will give an empty array for an empty tree" do expect(tree.bfs).must_equal [] end From ed691eb07dcd8b41ce657062e9f571441f5f49f4 Mon Sep 17 00:00:00 2001 From: TATIANA QUINTANA Date: Thu, 5 Sep 2019 14:11:33 -0700 Subject: [PATCH 2/8] added inorder traversal --- lib/tree.rb | 43 ++++++++++++++++++++++++++++++++++--------- test/tree_test.rb | 2 +- 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/lib/tree.rb b/lib/tree.rb index 3cee5a3..15edee6 100644 --- a/lib/tree.rb +++ b/lib/tree.rb @@ -19,19 +19,33 @@ def initialize # Time Complexity: O(log n) - traverse only half of dataset # Space Complexity: O - just adding a node def add(key, value) + if key.nil? || value.nil? + return nil + end + if @root.nil? - new_tree_node = TreeNode.new(key, value) - @root = new_tree_node + @root = TreeNode.new(key, value) return end - current_node = @root - add_node = TreeNode.new(key, value) - if add_node.key <= current_node.key - current_node.left = add_node - else - current_node.right = add_node + insert_node = TreeNode.new(key, value) + current_root = @root + + while !current_root.nil? + trailing_node = current_root + + if key <= current_root.key + current_root = current_root.left + else + current_root = current_root.right end + end + + if key <= trailing_node.key + trailing_node.left = insert_node + else + trailing_node.right = insert_node + end end # Time Complexity: @@ -58,9 +72,20 @@ def find(key) # Time Complexity: # Space Complexity: def inorder - raise NotImplementedError + root_node = @root + array = [] + inorder_array = bst_inorder(root_node, array) + end + + def bst_inorder(node, arr) + return arr if !node + bst_inorder(node.left, arr) + arr << {:key => node.key, :value => node.value} + bst_inorder(node.right, arr) end + + # Time Complexity: # Space Complexity: def preorder diff --git a/test/tree_test.rb b/test/tree_test.rb index e4e6e73..474c705 100644 --- a/test/tree_test.rb +++ b/test/tree_test.rb @@ -31,7 +31,7 @@ expect(tree.find(50)).must_be_nil end - xdescribe "inorder" do + describe "inorder" do it "will give an empty array for an empty tree" do expect(tree.inorder).must_equal [] end From 6627c91c554f53a35623d56febb19340565346a8 Mon Sep 17 00:00:00 2001 From: TATIANA QUINTANA Date: Thu, 5 Sep 2019 14:33:44 -0700 Subject: [PATCH 3/8] added post-order and pre-order --- lib/tree.rb | 23 +++++++++++++++++++++-- test/tree_test.rb | 4 ++-- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/lib/tree.rb b/lib/tree.rb index 15edee6..bf589e0 100644 --- a/lib/tree.rb +++ b/lib/tree.rb @@ -89,13 +89,32 @@ def bst_inorder(node, arr) # Time Complexity: # Space Complexity: def preorder - raise NotImplementedError + array = [] + root_node = @root + preorder_arr = bst_preorder(root_node, array) + end + + def bst_preorder(node, arr) + return arr if !node + arr << {:key => node.key, :value => node.value} + bst_preorder(node.left, arr) + bst_preorder(node.right, arr) end # Time Complexity: # Space Complexity: def postorder - raise NotImplementedError + array = [] + root_node = @root + postorder = bst_postorder(root_node, array) + end + + def bst_postorder(node, arr) + return arr if !node + bst_postorder(node.left, arr) + bst_postorder(node.right, arr) + arr << {:key => node.key, :value => node.value} + end # Time Complexity: diff --git a/test/tree_test.rb b/test/tree_test.rb index 474c705..4df5ea1 100644 --- a/test/tree_test.rb +++ b/test/tree_test.rb @@ -45,7 +45,7 @@ end - xdescribe "preorder" do + describe "preorder" do it "will give an empty array for an empty tree" do expect(tree.preorder).must_equal [] end @@ -57,7 +57,7 @@ end end - xdescribe "postorder" do + describe "postorder" do it "will give an empty array for an empty tree" do expect(tree.postorder).must_equal [] end From 03c5ec03df543e8a50ac70fef32c712ec2858564 Mon Sep 17 00:00:00 2001 From: TATIANA QUINTANA Date: Thu, 5 Sep 2019 15:12:37 -0700 Subject: [PATCH 4/8] added breadth first search --- lib/tree.rb | 25 ++++++++++++++++++++++--- test/tree_test.rb | 2 +- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/lib/tree.rb b/lib/tree.rb index bf589e0..ae9ef52 100644 --- a/lib/tree.rb +++ b/lib/tree.rb @@ -106,7 +106,7 @@ def bst_preorder(node, arr) def postorder array = [] root_node = @root - postorder = bst_postorder(root_node, array) + postorder_arr = bst_postorder(root_node, array) end def bst_postorder(node, arr) @@ -120,14 +120,33 @@ def bst_postorder(node, arr) # Time Complexity: # Space Complexity: def height - raise NotImplementedError + end # Optional Method # Time Complexity: # Space Complexity: def bfs - raise NotImplementedError + node = @root + array = [] + bfs_arr = breadth_first(node, array) + end + + def breadth_first(node, arr) + current = node + levels_list = [] + i = 0 + + return arr if node.nil? + # add level by level + while i <= levels_list.length + arr << {:key => current.key, :value => current.value} + levels_list << current.left if current.left + levels_list << current.right if current.right + current = levels_list[i] + i+= 1 + end + return arr end # Useful for printing diff --git a/test/tree_test.rb b/test/tree_test.rb index 4df5ea1..174863d 100644 --- a/test/tree_test.rb +++ b/test/tree_test.rb @@ -69,7 +69,7 @@ end end - xdescribe "breadth first search" do + describe "breadth first search" do it "will give an empty array for an empty tree" do expect(tree.bfs).must_equal [] end From eb91c160fe25b0bb81576a8e9bf8ec68e2bb239e Mon Sep 17 00:00:00 2001 From: TATIANA QUINTANA Date: Thu, 5 Sep 2019 21:05:21 -0700 Subject: [PATCH 5/8] added height method --- lib/tree.rb | 58 +++++++++++++++++++++++++++++++---------------- test/tree_test.rb | 12 ++++++++++ 2 files changed, 50 insertions(+), 20 deletions(-) diff --git a/lib/tree.rb b/lib/tree.rb index ae9ef52..2a1f24e 100644 --- a/lib/tree.rb +++ b/lib/tree.rb @@ -16,8 +16,8 @@ def initialize @root = nil end - # Time Complexity: O(log n) - traverse only half of dataset - # Space Complexity: O - just adding a node + # Time Complexity: O(log n) - omit half of dataset to add a value if tree is balanced + # Space Complexity: O(1) to insert a node def add(key, value) if key.nil? || value.nil? return nil @@ -48,8 +48,8 @@ def add(key, value) end end - # Time Complexity: - # Space Complexity: + # Time Complexity: Ologn - omit half of dataset (if balanced) to find a value + # Space Complexity: O(1) Constant def find(key) #begin with root node, returns value return unless !@root.nil? @@ -69,12 +69,12 @@ def find(key) return nil end - # Time Complexity: - # Space Complexity: + # Time Complexity: O(n) because we visit each node once + # Space Complexity: O(h) where h is equal to height of tree unless tree is imbalanced, then O(n) def inorder root_node = @root array = [] - inorder_array = bst_inorder(root_node, array) + return bst_inorder(root_node, array) end def bst_inorder(node, arr) @@ -86,12 +86,12 @@ def bst_inorder(node, arr) - # Time Complexity: - # Space Complexity: + # Time Complexity: O(n) because we visit each node once + # Space Complexity: O(h) where h is equal to height of tree unless tree is imbalanced, then O(n) def preorder array = [] root_node = @root - preorder_arr = bst_preorder(root_node, array) + return bst_preorder(root_node, array) end def bst_preorder(node, arr) @@ -101,12 +101,12 @@ def bst_preorder(node, arr) bst_preorder(node.right, arr) end - # Time Complexity: - # Space Complexity: + # Time Complexity: O(n) because we visit each node once + # Space Complexity: O(h) where h is equal to height of tree unless tree is imbalanced, then O(n) def postorder array = [] root_node = @root - postorder_arr = bst_postorder(root_node, array) + return bst_postorder(root_node, array) end def bst_postorder(node, arr) @@ -114,22 +114,40 @@ def bst_postorder(node, arr) bst_postorder(node.left, arr) bst_postorder(node.right, arr) arr << {:key => node.key, :value => node.value} - end - # Time Complexity: + # Time Complexity: O(n) because you have to check each node/subtree in the tree to determine height # Space Complexity: def height - + current = @root + return 0 if @root.nil? + + h = tree_height(current) + puts h + return h + end + + def tree_height(node) + #find the height of the largest subtree + root node + height_left = 0 + height_right = 0 + + if node == nil + return 0 + else + height_left = tree_height(node.left) if node.left + height_right = tree_height(node.right) if node.right + height_left > height_right ? 1 + height_left : 1 + height_right + end end # Optional Method - # Time Complexity: - # Space Complexity: + # Time Complexity: O(n) because we visit every node + # Space Complexity: O(n) because I am storing all bfs nodes in an array def bfs node = @root array = [] - bfs_arr = breadth_first(node, array) + return breadth_first(node, array) end def breadth_first(node, arr) @@ -151,6 +169,6 @@ def breadth_first(node, arr) # Useful for printing def to_s - return "#{self.inorder}" + puts "#{self.inorder}" end end diff --git a/test/tree_test.rb b/test/tree_test.rb index 174863d..4ded659 100644 --- a/test/tree_test.rb +++ b/test/tree_test.rb @@ -80,4 +80,16 @@ {:key=>15, :value=>"Ada"}, {:key=>25, :value=>"Kari"}] end end + + describe "bst height" do + it "will return 0 if the root node is nil" do + expect(tree.height).must_equal 0 + end + + it "will give the correct height of a binary search tree" do + expect(tree_with_nodes.height).must_equal 4 + end + + end + end \ No newline at end of file From f8a0f937db6657f672598c899cbd495c4df3e4d2 Mon Sep 17 00:00:00 2001 From: TATIANA QUINTANA Date: Thu, 5 Sep 2019 21:07:04 -0700 Subject: [PATCH 6/8] added test for height --- lib/tree.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tree.rb b/lib/tree.rb index 2a1f24e..a21c1ea 100644 --- a/lib/tree.rb +++ b/lib/tree.rb @@ -117,7 +117,7 @@ def bst_postorder(node, arr) end # Time Complexity: O(n) because you have to check each node/subtree in the tree to determine height - # Space Complexity: + # Space Complexity: O(logn) unless unbalanced, then O(n) def height current = @root return 0 if @root.nil? From 5249b913b90126d3e66b277f36ab34d3b12d8fb9 Mon Sep 17 00:00:00 2001 From: TATIANA QUINTANA Date: Thu, 5 Sep 2019 21:08:53 -0700 Subject: [PATCH 7/8] added an aditional test for height --- lib/tree.rb | 5 ++--- test/tree_test.rb | 5 +++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/tree.rb b/lib/tree.rb index a21c1ea..19c6c5d 100644 --- a/lib/tree.rb +++ b/lib/tree.rb @@ -122,9 +122,8 @@ def height current = @root return 0 if @root.nil? - h = tree_height(current) - puts h - return h + return tree_height(current) + end def tree_height(node) diff --git a/test/tree_test.rb b/test/tree_test.rb index 4ded659..ddf786c 100644 --- a/test/tree_test.rb +++ b/test/tree_test.rb @@ -90,6 +90,11 @@ expect(tree_with_nodes.height).must_equal 4 end + it "will give the correct height of a binary search tree" do + tree_with_nodes.add(30, "Tatiana") + expect(tree_with_nodes.height).must_equal 5 + end + end end \ No newline at end of file From 81e33272c8782c5d95d2ccf76fd004413a1868fe Mon Sep 17 00:00:00 2001 From: TATIANA QUINTANA Date: Sun, 8 Sep 2019 12:13:47 -0700 Subject: [PATCH 8/8] adding nil checks --- lib/tree.rb | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/lib/tree.rb b/lib/tree.rb index 19c6c5d..825a70d 100644 --- a/lib/tree.rb +++ b/lib/tree.rb @@ -78,10 +78,12 @@ def inorder end def bst_inorder(node, arr) - return arr if !node - bst_inorder(node.left, arr) - arr << {:key => node.key, :value => node.value} - bst_inorder(node.right, arr) + if node + bst_inorder(node.left, arr) if node.left + arr << {:key => node.key, :value => node.value} + bst_inorder(node.right, arr) if node.right + end + return arr end @@ -95,10 +97,13 @@ def preorder end def bst_preorder(node, arr) - return arr if !node - arr << {:key => node.key, :value => node.value} - bst_preorder(node.left, arr) - bst_preorder(node.right, arr) + if !node + arr << {:key => node.key, :value => node.value} + bst_preorder(node.left, arr) if node.left + bst_preorder(node.right, arr) if node.right + end + + return arr end # Time Complexity: O(n) because we visit each node once @@ -110,10 +115,12 @@ def postorder end def bst_postorder(node, arr) - return arr if !node - bst_postorder(node.left, arr) - bst_postorder(node.right, arr) - arr << {:key => node.key, :value => node.value} + if node + bst_postorder(node.left, arr) if node.left + bst_postorder(node.right, arr) if node.right + arr << {:key => node.key, :value => node.value} + end + return arr end # Time Complexity: O(n) because you have to check each node/subtree in the tree to determine height