From fcf4ebd625b489180f430145eee5e55f44d25508 Mon Sep 17 00:00:00 2001 From: Kim Fasbender Date: Sun, 25 Aug 2019 20:31:31 -0700 Subject: [PATCH 1/5] implemented add and find methods with passing tests --- lib/tree.rb | 67 +++++++++++++++++++++++++++++++++-------------- test/tree_test.rb | 40 ++++++++++++++++------------ 2 files changed, 70 insertions(+), 37 deletions(-) diff --git a/lib/tree.rb b/lib/tree.rb index c0d4b51..3ab8890 100644 --- a/lib/tree.rb +++ b/lib/tree.rb @@ -2,59 +2,86 @@ 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 attr_reader :root + def initialize @root = nil end - # Time Complexity: - # Space Complexity: - def add(key, value) - raise NotImplementedError + # Time Complexity: + # Space Complexity: + def add(key, value, current = @root) + new_node = TreeNode.new(key, value) + + if !@root + @root = new_node + else + if current.key <= key + if !current.left + current.left = new_node + else + self.add(key, value, current.left) + end + else + if !current.right + current.right = new_node + else + self.add(key, value, current.right) + end + end + end end - # Time Complexity: - # Space Complexity: - def find(key) - raise NotImplementedError + # Time Complexity: + # Space Complexity: + def find(key, current = @root) + if !@root + return nil + elsif current.key == key + return current.value + elsif current.key <= key + self.find(key, current.left) + else + self.find(key, current.right) + end end - # Time Complexity: - # Space Complexity: + # Time Complexity: + # Space Complexity: def inorder raise NotImplementedError end - # Time Complexity: - # Space Complexity: + # Time Complexity: + # Space Complexity: def preorder raise NotImplementedError end - # Time Complexity: - # Space Complexity: + # Time Complexity: + # Space Complexity: def postorder raise NotImplementedError end - # Time Complexity: - # Space Complexity: + # Time Complexity: + # Space Complexity: def height raise NotImplementedError end # Optional Method - # Time Complexity: - # Space Complexity: + # Time Complexity: + # Space Complexity: def bfs raise NotImplementedError end diff --git a/test/tree_test.rb b/test/tree_test.rb index 8811f14..e539bf7 100644 --- a/test/tree_test.rb +++ b/test/tree_test.rb @@ -1,10 +1,9 @@ -require_relative 'test_helper' - +require_relative "test_helper" Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new describe Tree do - let (:tree) {Tree.new} + let (:tree) { Tree.new } let (:tree_with_nodes) { tree.add(5, "Peter") @@ -33,51 +32,58 @@ describe "inorder" do it "will give an empty array for an empty tree" do + skip expect(tree.inorder).must_equal [] end it "will return the tree in order" do + skip - 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"}] + 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 + skip 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"}] + skip + 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 + skip 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"}] + skip + 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 + skip 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"}] + skip + 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 -end \ No newline at end of file +end From 0de1852e505aa6ae3ca238665266c8b11f31a5c5 Mon Sep 17 00:00:00 2001 From: Kim Fasbender Date: Sat, 31 Aug 2019 13:39:51 -0700 Subject: [PATCH 2/5] fixed bug in add and find methods where nodes were being added to the wrong side of the root node --- lib/tree.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/tree.rb b/lib/tree.rb index 3ab8890..c295540 100644 --- a/lib/tree.rb +++ b/lib/tree.rb @@ -25,17 +25,17 @@ def add(key, value, current = @root) if !@root @root = new_node else - if current.key <= key + if key <= current.key if !current.left current.left = new_node else - self.add(key, value, current.left) + add(key, value, current.left) end else if !current.right current.right = new_node else - self.add(key, value, current.right) + add(key, value, current.right) end end end @@ -48,10 +48,10 @@ def find(key, current = @root) return nil elsif current.key == key return current.value - elsif current.key <= key - self.find(key, current.left) + elsif key <= current.key + find(key, current.left) else - self.find(key, current.right) + find(key, current.right) end end From 29fdf06d2f6d2664f8b42ff8fef7701c57e28e4d Mon Sep 17 00:00:00 2001 From: Kim Fasbender Date: Sat, 31 Aug 2019 14:49:00 -0700 Subject: [PATCH 3/5] implemented inorder, preorder, postorder, and height functions with corresponding tests passing --- lib/tree.rb | 42 +++++++++++++++++++++++++++++++++--------- test/tree_test.rb | 16 +++++++++------- 2 files changed, 42 insertions(+), 16 deletions(-) diff --git a/lib/tree.rb b/lib/tree.rb index c295540..940f289 100644 --- a/lib/tree.rb +++ b/lib/tree.rb @@ -57,33 +57,57 @@ def find(key, current = @root) # Time Complexity: # Space Complexity: - def inorder - raise NotImplementedError + def inorder(current = @root, array = []) + if !current + return array + else + inorder(current.left, array) + array << { key: current.key, value: current.value } + inorder(current.right, array) + end end # Time Complexity: # Space Complexity: - def preorder - raise NotImplementedError + def preorder(current = @root, array = []) + if !current + return array + else + array << { key: current.key, value: current.value } + preorder(current.left, array) + preorder(current.right, array) + end end # Time Complexity: # Space Complexity: - def postorder - raise NotImplementedError + def postorder(current = @root, array = []) + if !current + return array + else + postorder(current.left, array) + postorder(current.right, array) + array << { key: current.key, value: current.value } + end end # Time Complexity: # Space Complexity: - def height - raise NotImplementedError + def height(current = @root) + if !current + return 0 + else + left_height = height(current.left) + right_height = height(current.right) + + return (left_height > right_height ? left_height : right_height) + 1 + end end # Optional Method # Time Complexity: # Space Complexity: def bfs - raise NotImplementedError end # Useful for printing diff --git a/test/tree_test.rb b/test/tree_test.rb index e539bf7..b9ba069 100644 --- a/test/tree_test.rb +++ b/test/tree_test.rb @@ -32,13 +32,10 @@ describe "inorder" do it "will give an empty array for an empty tree" do - skip expect(tree.inorder).must_equal [] end it "will return the tree in order" do - skip - 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" }] @@ -47,12 +44,10 @@ describe "preorder" do it "will give an empty array for an empty tree" do - skip expect(tree.preorder).must_equal [] end it "will return the tree in preorder" do - skip 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" }] @@ -61,18 +56,25 @@ describe "postorder" do it "will give an empty array for an empty tree" do - skip expect(tree.postorder).must_equal [] end it "will return the tree in postorder" do - skip 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 "height" do + it "will return 0 for an empty tree" do + expect(tree.height).must_equal 0 + end + it "will return the height of the tree" do + expect(tree_with_nodes.height).must_equal 4 + end + end + describe "breadth first search" do it "will give an empty array for an empty tree" do skip From 05f0470ecc1f19ef4717f955d93f0bbd83e11b24 Mon Sep 17 00:00:00 2001 From: Kim Fasbender Date: Mon, 2 Sep 2019 15:36:22 -0700 Subject: [PATCH 4/5] completed all time and space complexity questions --- lib/tree.rb | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/lib/tree.rb b/lib/tree.rb index 940f289..2ac72cc 100644 --- a/lib/tree.rb +++ b/lib/tree.rb @@ -17,8 +17,9 @@ def initialize @root = nil end - # Time Complexity: - # Space Complexity: + # Time Complexity: O(log n) if the tree is balanced, O(n) if the tree is unbalanced + # - where n is equal to the number of TreeNodes in the tree + # Space Complexity: O(1) - constant def add(key, value, current = @root) new_node = TreeNode.new(key, value) @@ -41,8 +42,9 @@ def add(key, value, current = @root) end end - # Time Complexity: - # Space Complexity: + # Time Complexity: O(log n) if the tree is balance, O(n) is the tree is unbalanced + # - where n is equal to the number of TreeNodes in the tree + # Space Complexity: O(1) - constant def find(key, current = @root) if !@root return nil @@ -55,8 +57,8 @@ def find(key, current = @root) end end - # Time Complexity: - # Space Complexity: + # Time Complexity: O(n) - where n is equal to the number of TreeNodes in the tree + # Space Complexity: O(n) where n is equal to the number of TreeNodes in the tree def inorder(current = @root, array = []) if !current return array @@ -67,8 +69,8 @@ def inorder(current = @root, array = []) end end - # Time Complexity: - # Space Complexity: + # Time Complexity: O(n) - where n is equal to the number of TreeNodes in the tree + # Space Complexity: O(n) where n is equal to the number of TreeNodes in the tree def preorder(current = @root, array = []) if !current return array @@ -79,8 +81,8 @@ def preorder(current = @root, array = []) end end - # Time Complexity: - # Space Complexity: + # Time Complexity: O(n) - where n is equal to the number of TreeNodes in the tree + # Space Complexity: O(n) where n is equal to the number of TreeNodes in the tree def postorder(current = @root, array = []) if !current return array @@ -91,8 +93,8 @@ def postorder(current = @root, array = []) end end - # Time Complexity: - # Space Complexity: + # Time Complexity: O(n) - where n is equal to the number of TreeNodes in the tree + # Space Complexity: O(1) - constant def height(current = @root) if !current return 0 From 14ce9a9fb8b72652ff2177338d57851e53cd753f Mon Sep 17 00:00:00 2001 From: Kim Fasbender Date: Mon, 2 Sep 2019 16:25:22 -0700 Subject: [PATCH 5/5] refactored methods --- lib/tree.rb | 58 ++++++++++++++++++++++++----------------------------- 1 file changed, 26 insertions(+), 32 deletions(-) diff --git a/lib/tree.rb b/lib/tree.rb index 2ac72cc..a12bad9 100644 --- a/lib/tree.rb +++ b/lib/tree.rb @@ -23,22 +23,14 @@ def initialize def add(key, value, current = @root) new_node = TreeNode.new(key, value) - if !@root - @root = new_node - else + if @root if key <= current.key - if !current.left - current.left = new_node - else - add(key, value, current.left) - end + current.left ? add(key, value, current.left) : current.left = new_node else - if !current.right - current.right = new_node - else - add(key, value, current.right) - end + current.right ? add(key, value, current.right) : current.right = new_node end + else + @root = new_node end end @@ -46,63 +38,65 @@ def add(key, value, current = @root) # - where n is equal to the number of TreeNodes in the tree # Space Complexity: O(1) - constant def find(key, current = @root) - if !@root - return nil - elsif current.key == key - return current.value - elsif key <= current.key - find(key, current.left) + if current + if current.key == key + return current.value + elsif key <= current.key + find(key, current.left) + elsif key > current.key + find(key, current.right) + end else - find(key, current.right) + return end end # Time Complexity: O(n) - where n is equal to the number of TreeNodes in the tree # Space Complexity: O(n) where n is equal to the number of TreeNodes in the tree def inorder(current = @root, array = []) - if !current - return array - else + if current inorder(current.left, array) array << { key: current.key, value: current.value } inorder(current.right, array) + else + return array end end # Time Complexity: O(n) - where n is equal to the number of TreeNodes in the tree # Space Complexity: O(n) where n is equal to the number of TreeNodes in the tree def preorder(current = @root, array = []) - if !current - return array - else + if current array << { key: current.key, value: current.value } preorder(current.left, array) preorder(current.right, array) + else + return array end end # Time Complexity: O(n) - where n is equal to the number of TreeNodes in the tree # Space Complexity: O(n) where n is equal to the number of TreeNodes in the tree def postorder(current = @root, array = []) - if !current - return array - else + if current postorder(current.left, array) postorder(current.right, array) array << { key: current.key, value: current.value } + else + return array end end # Time Complexity: O(n) - where n is equal to the number of TreeNodes in the tree # Space Complexity: O(1) - constant def height(current = @root) - if !current - return 0 - else + if current left_height = height(current.left) right_height = height(current.right) return (left_height > right_height ? left_height : right_height) + 1 + else + return 0 end end