From 7eccd5cf6893d4f47417bc9920427e01cfa2f402 Mon Sep 17 00:00:00 2001 From: Sam Date: Mon, 24 Feb 2020 20:30:15 -0800 Subject: [PATCH 1/3] all required methods --- lib/tree.rb | 120 +++++++++++++++++++++------- test/tree_test.rb | 196 +++++++++++++++++++++++----------------------- 2 files changed, 189 insertions(+), 127 deletions(-) diff --git a/lib/tree.rb b/lib/tree.rb index c0d4b51..058e419 100644 --- a/lib/tree.rb +++ b/lib/tree.rb @@ -1,13 +1,13 @@ class TreeNode attr_reader :key, :value attr_accessor :left, :right - - def initialize(key, val) + + def initialize(key, val) @key = key @value = val @left = nil @right = nil - end + end end class Tree @@ -15,50 +15,112 @@ class Tree def initialize @root = nil end - - # Time Complexity: - # Space Complexity: + + # Time Complexity: O(log n) + # Space Complexity: O(1) + def add_helper(current_node, key, value) + return TreeNode.new(key,value) if current_node.nil? + + if key < current_node.key + current_node.left = add_helper(current_node.left, key, value) + else + current_node.right = add_helper(current_node.right, key, value) + end + + return current_node + end + def add(key, value) - raise NotImplementedError + @root = add_helper(@root, key, value) end - - # Time Complexity: - # Space Complexity: + + # Time Complexity: O(log n) + # Space Complexity: O(1) + def find_helper(current_node, key) + return nil if current_node.nil? + + if key > current_node.key + current_node.right = find_helper(current_node.right, key) + elsif key < current_node.key + current_node.left = find_helper(current_node.left, key) + else + return current_node.value + end + end + def find(key) - raise NotImplementedError + @root = find_helper(@root, key) end - - # Time Complexity: - # Space Complexity: + + # Time Complexity: O(n) + # Space Complexity: O(n) def inorder - raise NotImplementedError + return inorder_helper(@root, []) end - - # Time Complexity: - # Space Complexity: + + def inorder_helper(current_node, list) + return list if current_node.nil? + + inorder_helper(current_node.left, list) + list << {key: current_node.key, value: current_node.value} + + inorder_helper(current_node.right, list) + return list + end + + # Time Complexity: O(n) + # Space Complexity: O(n) def preorder - raise NotImplementedError + return pre_order_helper(@root, []) end - - # Time Complexity: - # Space Complexity: + + def pre_order_helper(current_node, list) + return list if current_node.nil? + + list << {key: current_node.key, value: current_node.value} + pre_order_helper(current_node.left, list) + pre_order_helper(current_node.right, list) + return list + end + + # Time Complexity: O(n) + # Space Complexity: O(n) def postorder - raise NotImplementedError + return post_order_helper(@root, []) end - - # Time Complexity: - # Space Complexity: + + def post_order_helper(current_node, list) + return list if current_node.nil? + + post_order_helper(current_node.left, list) + post_order_helper(current_node.right, list) + list << {key: current_node.key, value: current_node.value} + return list + end + + # Time Complexity: O(n) + # Space Complexity: O(n) + def height_helper(current_node) + return 0 if current_node.nil? + + if height_helper(current_node.right) > height_helper(current_node.left) + return height_helper(current_node.right) + 1 + else + return height_helper(current_node.left) + 1 + end + end + def height - raise NotImplementedError + return height_helper(@root) end - + # Optional Method # Time Complexity: # Space Complexity: def bfs raise NotImplementedError end - + # Useful for printing def to_s return "#{self.inorder}" diff --git a/test/tree_test.rb b/test/tree_test.rb index 345bf66..8b1336a 100644 --- a/test/tree_test.rb +++ b/test/tree_test.rb @@ -2,121 +2,121 @@ describe Tree do let (:tree) {Tree.new} - + let (:tree_with_nodes) { + tree.add(5, "Peter") + tree.add(3, "Paul") + tree.add(1, "Mary") + tree.add(10, "Karla") + tree.add(15, "Ada") + tree.add(25, "Kari") + tree +} + +describe "add and find" do + it "add & find values" do tree.add(5, "Peter") - tree.add(3, "Paul") - tree.add(1, "Mary") - tree.add(10, "Karla") + expect(tree.find(5)).must_equal "Peter" + tree.add(15, "Ada") - tree.add(25, "Kari") - tree - } - - describe "add and find" do - it "add & find values" do - tree.add(5, "Peter") - expect(tree.find(5)).must_equal "Peter" - - tree.add(15, "Ada") - expect(tree.find(15)).must_equal "Ada" - - tree.add(3, "Paul") - expect(tree.find(3)).must_equal "Paul" - end - - it "can't find anything when the tree is empty" do - expect(tree.find(50)).must_be_nil - end + expect(tree.find(15)).must_equal "Ada" + + tree.add(3, "Paul") + expect(tree.find(3)).must_equal "Paul" end - - describe "inorder" do - it "will give an empty array for an empty tree" do - expect(tree.inorder).must_equal [] - end - - it "will return the tree in order" do - 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"}] - end + + it "can't find anything when the tree is empty" do + expect(tree.find(50)).must_be_nil end +end +describe "inorder" do + it "will give an empty array for an empty tree" do + expect(tree.inorder).must_equal [] + end + + it "will return the tree in order" do + 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"}] + end +end - describe "preorder" do - it "will give an empty array for an empty tree" do - expect(tree.preorder).must_equal [] - end - it "will return the tree in preorder" do - expect(tree_with_nodes.preorder).must_equal [{:key=>5, :value=>"Peter"}, {:key=>3, :value=>"Paul"}, - {:key=>1, :value=>"Mary"}, {:key=>10, :value=>"Karla"}, - {:key=>15, :value=>"Ada"}, {:key=>25, :value=>"Kari"}] - end +describe "preorder" do + it "will give an empty array for an empty tree" do + expect(tree.preorder).must_equal [] end + + it "will return the tree in preorder" do + expect(tree_with_nodes.preorder).must_equal [{:key=>5, :value=>"Peter"}, {:key=>3, :value=>"Paul"}, + {:key=>1, :value=>"Mary"}, {:key=>10, :value=>"Karla"}, + {:key=>15, :value=>"Ada"}, {:key=>25, :value=>"Kari"}] + end +end - describe "postorder" do - it "will give an empty array for an empty tree" do - expect(tree.postorder).must_equal [] - end - - it "will return the tree in postorder" do - expect(tree_with_nodes.postorder).must_equal [{:key=>1, :value=>"Mary"}, {:key=>3, :value=>"Paul"}, - {:key=>25, :value=>"Kari"}, {:key=>15, :value=>"Ada"}, - {:key=>10, :value=>"Karla"}, {:key=>5, :value=>"Peter"}] - end +describe "postorder" do + it "will give an empty array for an empty tree" do + expect(tree.postorder).must_equal [] + end + + it "will return the tree in postorder" do + expect(tree_with_nodes.postorder).must_equal [{:key=>1, :value=>"Mary"}, {:key=>3, :value=>"Paul"}, + {:key=>25, :value=>"Kari"}, {:key=>15, :value=>"Ada"}, + {:key=>10, :value=>"Karla"}, {:key=>5, :value=>"Peter"}] end +end - describe "breadth first search" do - it "will give an empty array for an empty tree" do - expect(tree.bfs).must_equal [] - end +xdescribe "breadth first search" do + it "will give an empty array for an empty tree" do + expect(tree.bfs).must_equal [] + end + + it "will return an array of a level-by-level output of the tree" do + expect(tree_with_nodes.bfs).must_equal [{:key=>5, :value=>"Peter"}, {:key=>3, :value=>"Paul"}, + {:key=>10, :value=>"Karla"}, {:key=>1, :value=>"Mary"}, + {:key=>15, :value=>"Ada"}, {:key=>25, :value=>"Kari"}] + end +end - it "will return an array of a level-by-level output of the tree" do - expect(tree_with_nodes.bfs).must_equal [{:key=>5, :value=>"Peter"}, {:key=>3, :value=>"Paul"}, - {:key=>10, :value=>"Karla"}, {:key=>1, :value=>"Mary"}, - {:key=>15, :value=>"Ada"}, {:key=>25, :value=>"Kari"}] - end +describe "height" do + it "will return 0 if tree is empty" do + expect(tree.height()).must_equal 0 end - describe "height" do - it "will return 0 if tree is empty" do - expect(tree.height()).must_equal 0 - end + it "will return the nuber of nodes in the longest path" do + expect(tree_with_nodes.height).must_equal 4 + tree_with_nodes.add(60, "sam") + tree_with_nodes.add(58, "penny") + tree_with_nodes.add(65, "sam") + expect(tree_with_nodes.height).must_equal 6 + 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 - it "will return the nuber of nodes in the longest path" do - expect(tree_with_nodes.height).must_equal 4 - tree_with_nodes.add(60, "sam") - tree_with_nodes.add(58, "penny") - tree_with_nodes.add(65, "sam") - expect(tree_with_nodes.height).must_equal 6 - end +xdescribe "delete" do + it "can delete a note in the tree" do + # Arrange & Assert + expect(tree_with_nodes.find(15)).must_equal "Ada" + + # Act + tree_with_nodes.delete(15) - 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 + # Assert + expect(tree_with_nodes.find(15)).must_be_nil end - - describe "delete" do - it "can delete a note in the tree" do - # Arrange & Assert - expect(tree_with_nodes.find(15)).must_equal "Ada" - - # Act - tree_with_nodes.delete(15) - - # Assert - expect(tree_with_nodes.find(15)).must_be_nil - end - - it "will return nil if the node is not in the tree when it's deleted" do - # Arrange & Act - answer = tree_with_nodes.delete(47) - - # Assert - expect(answer).must_be_nil - expect(tree_with_nodes.find(47)).must_be_nil - end + + it "will return nil if the node is not in the tree when it's deleted" do + # Arrange & Act + answer = tree_with_nodes.delete(47) + + # Assert + expect(answer).must_be_nil + expect(tree_with_nodes.find(47)).must_be_nil end end +end From 59bec11ce4f23ecbb6ae3a9082ba317190dc846d Mon Sep 17 00:00:00 2001 From: Sam Date: Mon, 24 Feb 2020 20:38:25 -0800 Subject: [PATCH 2/3] all tests pass --- lib/tree.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/tree.rb b/lib/tree.rb index 058e419..14fed63 100644 --- a/lib/tree.rb +++ b/lib/tree.rb @@ -19,7 +19,7 @@ def initialize # Time Complexity: O(log n) # Space Complexity: O(1) def add_helper(current_node, key, value) - return TreeNode.new(key,value) if current_node.nil? + return TreeNode.new(key, value) if current_node.nil? if key < current_node.key current_node.left = add_helper(current_node.left, key, value) @@ -49,7 +49,7 @@ def find_helper(current_node, key) end def find(key) - @root = find_helper(@root, key) + return find_helper(@root, key) end # Time Complexity: O(n) From 1ca0aca8b1370ad605a83bdb979657dd266e98e7 Mon Sep 17 00:00:00 2001 From: Sam Date: Sun, 1 Mar 2020 12:16:50 -0800 Subject: [PATCH 3/3] added bfs method and fixed space complexity --- lib/tree.rb | 42 ++++++++++++++++++++++++++++++++++-------- test/tree_test.rb | 2 +- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/lib/tree.rb b/lib/tree.rb index 14fed63..822abbe 100644 --- a/lib/tree.rb +++ b/lib/tree.rb @@ -16,8 +16,8 @@ def initialize @root = nil end - # Time Complexity: O(log n) - # Space Complexity: O(1) + # Time Complexity: O(logn) + # Space Complexity: O(logn) if tree is balanced and O(n) if it's not balanced. def add_helper(current_node, key, value) return TreeNode.new(key, value) if current_node.nil? @@ -34,8 +34,8 @@ def add(key, value) @root = add_helper(@root, key, value) end - # Time Complexity: O(log n) - # Space Complexity: O(1) + # Time Complexity: O(logn) + # Space Complexity: O(logn) if tree is balanced and O(n) if it's not balanced. def find_helper(current_node, key) return nil if current_node.nil? @@ -99,7 +99,7 @@ def post_order_helper(current_node, list) end # Time Complexity: O(n) - # Space Complexity: O(n) + # Space Complexity: O(logn) if tree is balanced and O(n) if it's not balanced. def height_helper(current_node) return 0 if current_node.nil? @@ -115,12 +115,38 @@ def height end # Optional Method - # Time Complexity: - # Space Complexity: + # Time Complexity: O(n) + # Space Complexity: O(n) def bfs - raise NotImplementedError + list = [] + return list if @root.nil? + queue = [@root] + + until queue.empty? + current = queue.shift + queue.push(current.left) unless current.left.nil? + queue.push(current.right) unless current.right.nil? + + list << {key: current.key, value: current.value} + end + return list end + # Time Complexity: + # Space Complexity: + def find_largest(current) + current = current_root + + while current.right + current = current.right + end + return current + end + + # def delete(key) + # raise NotImplementedError + # end + # Useful for printing def to_s return "#{self.inorder}" diff --git a/test/tree_test.rb b/test/tree_test.rb index 8b1336a..51c7678 100644 --- a/test/tree_test.rb +++ b/test/tree_test.rb @@ -67,7 +67,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