From 64f3ddd31bfe82491090557e6cf80a0ff4125e4a Mon Sep 17 00:00:00 2001 From: Kareha Agesa Date: Sat, 27 Mar 2021 16:00:23 -0700 Subject: [PATCH 1/9] starting add and in order --- lib/tree.rb | 38 ++++++++++++++++++++++++++++++++++++-- test/tree_test.rb | 15 ++++++++------- 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/lib/tree.rb b/lib/tree.rb index c0d4b51..3d8a755 100644 --- a/lib/tree.rb +++ b/lib/tree.rb @@ -19,7 +19,30 @@ def initialize # Time Complexity: # Space Complexity: def add(key, value) - raise NotImplementedError + + # wrong think about why + # @root = TreeNode.new(key, value) unless root + # return add_helper(@root, key, value) + + unless root + @root = TreeNode.new(key, value) + else + add_helper(@root, key, value) + end + end + + def add_helper(current, key, value) + return TreeNode.new(key, value) unless current + + if key < current.key + current.left = add_helper(current.left, key, value) + else + current.right = add_helper(current.right, key, value) + end + + # needed idk why + # return current + end # Time Complexity: @@ -31,7 +54,18 @@ def find(key) # Time Complexity: # Space Complexity: def inorder - raise NotImplementedError + tree_in_order = [] + return inorder_helper(tree_in_order, @root) + end + + def inorder_helper(tree, current) + return tree unless current + + inorder_helper(tree, current.left) + tree.push({:key=>current.key, :value=>current.value}) + inorder_helper(tree, current.right) + + return tree end # Time Complexity: diff --git a/test/tree_test.rb b/test/tree_test.rb index dbf3447..42fa79e 100644 --- a/test/tree_test.rb +++ b/test/tree_test.rb @@ -14,9 +14,10 @@ tree.add(15, "Ada") tree.add(25, "Kari") tree + # print tree } - it "add & find values" do + xit "add & find values" do tree.add(5, "Peter") expect(tree.find(5)).must_equal "Peter" @@ -27,7 +28,7 @@ expect(tree.find(3)).must_equal "Paul" end - it "can't find anything when the tree is empty" do + xit "can't find anything when the tree is empty" do expect(tree.find(50)).must_be_nil end @@ -37,7 +38,7 @@ end it "will return the tree in order" do - + print(tree_with_nodes) expect(tree_with_nodes.inorder).must_equal [{:key=>1, :value=>"Mary"}, {:key=>3, :value=>"Paul"}, {:key=>5, :value=>"Peter"}, {:key=>10, :value=>"Karla"}, {:key=>15, :value=>"Ada"}, {:key=>25, :value=>"Kari"}] @@ -45,7 +46,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 +58,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 +70,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 @@ -81,7 +82,7 @@ end end - describe "height" do + xdescribe "height" do it "will return 0 for an empty tree" do my_tree = Tree.new From 815173ce33b12757d2ed1355daeb8650e53de465 Mon Sep 17 00:00:00 2001 From: Kareha Agesa Date: Sun, 28 Mar 2021 12:35:53 -0700 Subject: [PATCH 2/9] depth first traversals passing --- lib/tree.rb | 54 ++++++++++++++++++++++++++++++++++++----------- test/tree_test.rb | 6 ++---- 2 files changed, 44 insertions(+), 16 deletions(-) diff --git a/lib/tree.rb b/lib/tree.rb index 3d8a755..5cec79e 100644 --- a/lib/tree.rb +++ b/lib/tree.rb @@ -16,14 +16,10 @@ def initialize @root = nil end - # Time Complexity: - # Space Complexity: + # Time Complexity: O(logn) + # Space Complexity: O(logn) def add(key, value) - # wrong think about why - # @root = TreeNode.new(key, value) unless root - # return add_helper(@root, key, value) - unless root @root = TreeNode.new(key, value) else @@ -40,8 +36,8 @@ def add_helper(current, key, value) current.right = add_helper(current.right, key, value) end - # needed idk why - # return current + # still working through why this needed + return current end @@ -51,8 +47,8 @@ def find(key) raise NotImplementedError end - # Time Complexity: - # Space Complexity: + # Time Complexity: O(n) + # Space Complexity: O(n^2)???? O(n) recursive calls but creating array of size n? - maybe O(2n?) def inorder tree_in_order = [] return inorder_helper(tree_in_order, @root) @@ -71,13 +67,35 @@ def inorder_helper(tree, current) # Time Complexity: # Space Complexity: def preorder - raise NotImplementedError + tree_pre_order = [] + return preorder_helper(@root, tree_pre_order) + end + + def preorder_helper(current, tree) + return tree unless current + + tree.push({:key=>current.key, :value=>current.value}) + preorder_helper(current.left, tree) + preorder_helper(current.right, tree) + + return tree end # Time Complexity: # Space Complexity: def postorder - raise NotImplementedError + tree_post_order = [] + return postorder_helper(@root, tree_post_order) + end + + def postorder_helper(current, tree) + return tree unless current + + postorder_helper(current.left, tree) + postorder_helper(current.right, tree) + tree.push({:key=>current.key, :value=>current.value}) + + return tree end # Time Complexity: @@ -98,3 +116,15 @@ def to_s return "#{self.inorder}" end end + +# tree = Tree.new() +# tree.add(5, "Peter") +# print("#{tree}\n") + +# tree.add(3, "Paul") +# print(tree) +# p "#{tree.root.key}" + +# tree.add(1, "Mary") +# print(tree) +# p "#{tree.root.key}" \ No newline at end of file diff --git a/test/tree_test.rb b/test/tree_test.rb index 42fa79e..8294aab 100644 --- a/test/tree_test.rb +++ b/test/tree_test.rb @@ -14,7 +14,6 @@ tree.add(15, "Ada") tree.add(25, "Kari") tree - # print tree } xit "add & find values" do @@ -38,7 +37,6 @@ end it "will return the tree in order" do - print(tree_with_nodes) expect(tree_with_nodes.inorder).must_equal [{:key=>1, :value=>"Mary"}, {:key=>3, :value=>"Paul"}, {:key=>5, :value=>"Peter"}, {:key=>10, :value=>"Karla"}, {:key=>15, :value=>"Ada"}, {:key=>25, :value=>"Kari"}] @@ -46,7 +44,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 @@ -58,7 +56,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 70ae25c1528b6bd37c3a3df8df0323243963d18a Mon Sep 17 00:00:00 2001 From: Kareha Agesa Date: Sun, 28 Mar 2021 13:14:23 -0700 Subject: [PATCH 3/9] working through find --- lib/tree.rb | 29 +++++++++++++++++++++++------ test/tree_test.rb | 4 ++-- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/lib/tree.rb b/lib/tree.rb index 5cec79e..537a17b 100644 --- a/lib/tree.rb +++ b/lib/tree.rb @@ -44,7 +44,21 @@ def add_helper(current, key, value) # Time Complexity: # Space Complexity: def find(key) - raise NotImplementedError + return find_helper(@root, key) + end + + def find_helper(current, key) + return current unless current + return current.value if key == current.key + + if current.key < key + find_helper(current.right, key) + else + find_helper(current.left, key) + end + + # why isnt a return needed here? + # not working back up stack? end # Time Complexity: O(n) @@ -117,14 +131,17 @@ def to_s end end -# tree = Tree.new() -# tree.add(5, "Peter") +tree = Tree.new() +# p tree.find(8) +tree.add(5, "Peter") # print("#{tree}\n") -# tree.add(3, "Paul") +tree.add(3, "Paul") # print(tree) # p "#{tree.root.key}" -# tree.add(1, "Mary") +tree.add(1, "Mary") # print(tree) -# p "#{tree.root.key}" \ No newline at end of file +# p "#{tree.root.key}" + +p tree.find(1) \ No newline at end of file diff --git a/test/tree_test.rb b/test/tree_test.rb index 8294aab..75cebb8 100644 --- a/test/tree_test.rb +++ b/test/tree_test.rb @@ -16,7 +16,7 @@ tree } - xit "add & find values" do + it "add & find values" do tree.add(5, "Peter") expect(tree.find(5)).must_equal "Peter" @@ -27,7 +27,7 @@ expect(tree.find(3)).must_equal "Paul" end - xit "can't find anything when the tree is empty" do + it "can't find anything when the tree is empty" do expect(tree.find(50)).must_be_nil end From 0628f134bdb80eeaab3a02e2348a03ccd76314c3 Mon Sep 17 00:00:00 2001 From: Kareha Agesa Date: Mon, 29 Mar 2021 09:11:48 -0700 Subject: [PATCH 4/9] just working through this recursion --- lib/tree.rb | 68 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 59 insertions(+), 9 deletions(-) diff --git a/lib/tree.rb b/lib/tree.rb index 537a17b..cd31830 100644 --- a/lib/tree.rb +++ b/lib/tree.rb @@ -19,7 +19,6 @@ def initialize # Time Complexity: O(logn) # Space Complexity: O(logn) def add(key, value) - unless root @root = TreeNode.new(key, value) else @@ -36,13 +35,37 @@ def add_helper(current, key, value) current.right = add_helper(current.right, key, value) end - # still working through why this needed + # still working through why this needed/what would happen with no return return current + # i think needed bc you assign current.left/right + # to the return of add_helper + # this assignment is needed because you will need + # to connect the new node to a leaf node + # (set that leaf node's .left/.right) + # so for a given current node, you need to know what + # it should be linked to (ie it's .left/right) + # which means that on the next iteration, just return + # that current's value to fill this in later + # ^ bad explanation - but if current = 97, and current.left is 91 + # you need to return 91 on the next recursive call (when current is 91) + # so that way when you work back up the callstack, you'll know that when + # current is 97, set 97.left to be 91 (bc 91 is returned from helper(97.left)) + + # if you didn't return current + # just return -> going back up the callstack would be setting current.left/right to nil + # no return -> i think bc of implicit returns in ruby, it would just carry the + # assignment from the base case all the way up + # so like in find for ex, once you find it, it just carries that val all the way up + # when you're assigning, it takes the old leaf nodes assignment of .left/.right and just carries + # that all the way up + # this is why when i was playing around with it (without a return), in the case of adding a 3rd(+) node, + # the code would just set what root.left/right's left/right to be the node i was adding + # it basically takes that assignment from the base case and carries it all the way up end - # Time Complexity: - # Space Complexity: + # Time Complexity: O(logn) + # Space Complexity: O(logn) def find(key) return find_helper(@root, key) end @@ -56,9 +79,11 @@ def find_helper(current, key) else find_helper(current.left, key) end - + # why isnt a return needed here? - # not working back up stack? + # i think bc it just carries that return current all the way back up + # implicit returns in ruby + end # Time Complexity: O(n) @@ -115,7 +140,17 @@ def postorder_helper(current, tree) # Time Complexity: # Space Complexity: def height - raise NotImplementedError + return 0 unless @root + left = height_helper(@root) + right = height_helper() + + + end + + def height_helper(current, count) + + # + end # Optional Method @@ -140,8 +175,23 @@ def to_s # print(tree) # p "#{tree.root.key}" -tree.add(1, "Mary") +# note this prints the root -> bc of the return current +p tree.add(1, "Mary") # print(tree) # p "#{tree.root.key}" -p tree.find(1) \ No newline at end of file +# p tree.find(1) + +# def huh(x) +# y = 0 + +# if x < 1 +# y = 4 +# else +# y = 3 +# end +# x + +# end + +# p huh(9) \ No newline at end of file From 380945ee1708deb89b5655e30d1cb643e8eeef36 Mon Sep 17 00:00:00 2001 From: Kareha Agesa Date: Thu, 1 Apr 2021 20:21:21 -0700 Subject: [PATCH 5/9] height and bfs --- lib/tree.rb | 69 +++++++++++++++++++---------------------------- test/tree_test.rb | 8 +++--- 2 files changed, 31 insertions(+), 46 deletions(-) diff --git a/lib/tree.rb b/lib/tree.rb index cd31830..33d4881 100644 --- a/lib/tree.rb +++ b/lib/tree.rb @@ -18,7 +18,7 @@ def initialize # Time Complexity: O(logn) # Space Complexity: O(logn) - def add(key, value) + def add(key, value = nil) unless root @root = TreeNode.new(key, value) else @@ -137,61 +137,46 @@ def postorder_helper(current, tree) return tree end - # Time Complexity: - # Space Complexity: + # Time Complexity: O(n) + # Space Complexity: O(n) def height - return 0 unless @root - left = height_helper(@root) - right = height_helper() - - + return height_helper(@root) end - def height_helper(current, count) + def height_helper(current) + return 0 unless current - # + left_height = height_helper(current.left) + right_height = height_helper(current.right) + return left_height < right_height ? right_height + 1 : left_height + 1 end # Optional Method # Time Complexity: # Space Complexity: def bfs - raise NotImplementedError - end - - # Useful for printing - def to_s - return "#{self.inorder}" - end -end - -tree = Tree.new() -# p tree.find(8) -tree.add(5, "Peter") -# print("#{tree}\n") + q = [] + tree_bfs = [] + return tree_bfs unless @root -tree.add(3, "Paul") -# print(tree) -# p "#{tree.root.key}" + q.push(@root) + + until q.empty? + current = q.shift -# note this prints the root -> bc of the return current -p tree.add(1, "Mary") -# print(tree) -# p "#{tree.root.key}" + tree_bfs.push({:key=>current.key, :value=>current.value}) -# p tree.find(1) - -# def huh(x) -# y = 0 + q.push(current.left) if current.left + q.push(current.right) if current.right + end -# if x < 1 -# y = 4 -# else -# y = 3 -# end -# x + return tree_bfs -# end + end -# p huh(9) \ No newline at end of file + # Useful for printing + def to_s + return "#{self.inorder}" + end +end \ No newline at end of file diff --git a/test/tree_test.rb b/test/tree_test.rb index 75cebb8..339c38b 100644 --- a/test/tree_test.rb +++ b/test/tree_test.rb @@ -68,7 +68,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 @@ -80,7 +80,7 @@ end end - xdescribe "height" do + describe "height" do it "will return 0 for an empty tree" do my_tree = Tree.new @@ -94,8 +94,8 @@ expect(my_tree.height).must_equal 1 end - it "will report the height for a balanced tree" do - expect(tree_with_nodes.height).must_equal 3 + it "will report the height for a tree with height 4 on right and 3 on left" do + expect(tree_with_nodes.height).must_equal 4 end it "will report the height for unbalanced trees" do From 727e30e58b845551527850ae9011330ce66bcedc Mon Sep 17 00:00:00 2001 From: Kareha Agesa Date: Fri, 2 Apr 2021 08:19:29 -0700 Subject: [PATCH 6/9] adding time/space complexities --- lib/tree.rb | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/tree.rb b/lib/tree.rb index 33d4881..275b478 100644 --- a/lib/tree.rb +++ b/lib/tree.rb @@ -87,7 +87,7 @@ def find_helper(current, key) end # Time Complexity: O(n) - # Space Complexity: O(n^2)???? O(n) recursive calls but creating array of size n? - maybe O(2n?) + # Space Complexity: O(n) def inorder tree_in_order = [] return inorder_helper(tree_in_order, @root) @@ -103,8 +103,8 @@ def inorder_helper(tree, current) return tree end - # Time Complexity: - # Space Complexity: + # Time Complexity: O(n) + # Space Complexity: O(n) def preorder tree_pre_order = [] return preorder_helper(@root, tree_pre_order) @@ -120,8 +120,8 @@ def preorder_helper(current, tree) return tree end - # Time Complexity: - # Space Complexity: + # Time Complexity: O(n) + # Space Complexity: O(n) def postorder tree_post_order = [] return postorder_helper(@root, tree_post_order) @@ -153,8 +153,8 @@ def height_helper(current) end # Optional Method - # Time Complexity: - # Space Complexity: + # Time Complexity: O(n^2) + # Space Complexity: O(n) def bfs q = [] tree_bfs = [] From 9bf871076283cd0c508ccbebb83cb752319314d2 Mon Sep 17 00:00:00 2001 From: Kareha Agesa Date: Fri, 2 Apr 2021 08:25:38 -0700 Subject: [PATCH 7/9] remove comments --- lib/tree.rb | 32 +------------------------------- 1 file changed, 1 insertion(+), 31 deletions(-) diff --git a/lib/tree.rb b/lib/tree.rb index 275b478..4a8752d 100644 --- a/lib/tree.rb +++ b/lib/tree.rb @@ -35,32 +35,7 @@ def add_helper(current, key, value) current.right = add_helper(current.right, key, value) end - # still working through why this needed/what would happen with no return return current - # i think needed bc you assign current.left/right - # to the return of add_helper - # this assignment is needed because you will need - # to connect the new node to a leaf node - # (set that leaf node's .left/.right) - # so for a given current node, you need to know what - # it should be linked to (ie it's .left/right) - # which means that on the next iteration, just return - # that current's value to fill this in later - # ^ bad explanation - but if current = 97, and current.left is 91 - # you need to return 91 on the next recursive call (when current is 91) - # so that way when you work back up the callstack, you'll know that when - # current is 97, set 97.left to be 91 (bc 91 is returned from helper(97.left)) - - # if you didn't return current - # just return -> going back up the callstack would be setting current.left/right to nil - # no return -> i think bc of implicit returns in ruby, it would just carry the - # assignment from the base case all the way up - # so like in find for ex, once you find it, it just carries that val all the way up - # when you're assigning, it takes the old leaf nodes assignment of .left/.right and just carries - # that all the way up - # this is why when i was playing around with it (without a return), in the case of adding a 3rd(+) node, - # the code would just set what root.left/right's left/right to be the node i was adding - # it basically takes that assignment from the base case and carries it all the way up end @@ -79,11 +54,6 @@ def find_helper(current, key) else find_helper(current.left, key) end - - # why isnt a return needed here? - # i think bc it just carries that return current all the way back up - # implicit returns in ruby - end # Time Complexity: O(n) @@ -153,7 +123,7 @@ def height_helper(current) end # Optional Method - # Time Complexity: O(n^2) + # Time Complexity: O(n*m) # Space Complexity: O(n) def bfs q = [] From f8b61096b1a942d78ed8043d33230a8e51dc913e Mon Sep 17 00:00:00 2001 From: Kareha Agesa Date: Thu, 13 May 2021 08:40:03 -0700 Subject: [PATCH 8/9] adding back some comments for myself --- lib/tree.rb | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/lib/tree.rb b/lib/tree.rb index 4a8752d..3335472 100644 --- a/lib/tree.rb +++ b/lib/tree.rb @@ -35,7 +35,33 @@ def add_helper(current, key, value) current.right = add_helper(current.right, key, value) end + # still working through why this needed/what would happen with no return return current + # i think needed bc you assign current.left/right + # to the return of add_helper + # this assignment is needed because you will need + # to connect the new node to a leaf node + # (set that leaf node's .left/.right) + # so for a given current node, you need to know what + # it should be linked to (ie it's .left/right) + # which means that on the next iteration, just return + # that current's value to fill this in later + # ^ bad explanation - but if current = 97, and current.left is 91 + # you need to return 91 on the next recursive call (when current is 91) + # so that way when you work back up the callstack, you'll know that when + # current is 97, set 97.left to be 91 (bc 91 is returned from helper(97.left)) + + # if you didn't return current + # just return -> going back up the callstack would be setting current.left/right to nil + # no return -> i think bc of implicit returns in ruby, it would just carry the + # assignment from the base case all the way up + # so like in find for ex, once you find it, it just carries that val all the way up + # when you're assigning, it takes the old leaf nodes assignment of .left/.right and just carries + # that all the way up + # this is why when i was playing around with it (without a return), in the case of adding a 3rd(+) node, + # the code would just set what root.left/right's left/right to be the node i was adding + # it basically takes that assignment from the base case and carries it all the way up + # see ex on line 186, when you dont have a return after an if block, the method just returns what the if block returned (when you print it) end @@ -54,6 +80,10 @@ def find_helper(current, key) else find_helper(current.left, key) end + + # Q: why isnt a return needed here? + # A: i think bc it just carries that return current all the way back up + # implicit returns in ruby end # Time Complexity: O(n) @@ -64,6 +94,7 @@ def inorder end def inorder_helper(tree, current) + # needed to ensure don't return nil in case of empty tree return tree unless current inorder_helper(tree, current.left) @@ -149,4 +180,18 @@ def bfs def to_s return "#{self.inorder}" end -end \ No newline at end of file +end + + +def test(x, y) + if x == 1 + x = 3 + # p (y) + else + x = 4 + # p ("no") + end + # return +end + +p test(1, 2) \ No newline at end of file From 3de61c52b7db659f9889b2bf26edcbce2b8d2a3e Mon Sep 17 00:00:00 2001 From: Kareha Agesa Date: Tue, 18 May 2021 08:04:54 -0700 Subject: [PATCH 9/9] some returns i dont need --- lib/tree.rb | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/lib/tree.rb b/lib/tree.rb index 3335472..aadb3b2 100644 --- a/lib/tree.rb +++ b/lib/tree.rb @@ -90,18 +90,17 @@ def find_helper(current, key) # Space Complexity: O(n) def inorder tree_in_order = [] - return inorder_helper(tree_in_order, @root) + inorder_helper(tree_in_order, @root) end def inorder_helper(tree, current) - # needed to ensure don't return nil in case of empty tree return tree unless current inorder_helper(tree, current.left) tree.push({:key=>current.key, :value=>current.value}) inorder_helper(tree, current.right) - return tree + # return tree end # Time Complexity: O(n) @@ -194,4 +193,22 @@ def test(x, y) # return end -p test(1, 2) \ No newline at end of file +# p test(1, 2) + + +tree = Tree.new() +tree.add(5, "5") +tree.add(3, "3") +tree.add(1, "1") +# 5 +# 3 +# 1 +p tree.inorder + +tree = Tree.new() +tree.add(1, "1") +tree.add(3, "3") +tree.add(5, "5") + # 1 + # 3 5 +p tree.inorder \ No newline at end of file