diff --git a/lib/tree.rb b/lib/tree.rb index c0d4b51..9e493ba 100644 --- a/lib/tree.rb +++ b/lib/tree.rb @@ -16,45 +16,127 @@ def initialize @root = nil end - # Time Complexity: - # Space Complexity: + # Time Complexity: O(logn) if the tree is balanced (best case), O(n) if tree is unbalanced (worst case) + # Space Complexity: O(1) def add(key, value) - raise NotImplementedError + if !@root + new_node = TreeNode.new(key, value) + @root = new_node + return + end + + current = @root + new_node = TreeNode.new(key, value) + + until !current + if new_node.key <= current.key # GO LEFT + if !current.left + current.left = new_node + return + else + current = current.left + end + else # new_node.value > current.value # GO RIGHT + if !current.right + current.right = new_node + return + else + current = current.right + end + end + end end - # Time Complexity: - # Space Complexity: + # Time Complexity: O(logn) where n is the length of the array if the tree is balanced. O(n) if not. + # Space Complexity: O(1) def find(key) - raise NotImplementedError + return nil if !@root + current = @root + + until current == nil + return current.value if key == current.key + key < current.key ? current = current.left : current = current.right + end + end - # Time Complexity: - # Space Complexity: + # Time Complexity: O(n-squared) + # Space Complexity: O(n) where n is the height of the recursion stack def inorder - raise NotImplementedError + @output = [] + current = @root + + return @output if !@root + + def analyzeInorder(current) + analyzeInorder(current.left) if current.left + @output << {:key => current.key, :value => current.value} + analyzeInorder(current.right) if current.right + end + + analyzeInorder(current) + + return @output end - # Time Complexity: - # Space Complexity: + # Time Complexity: O(n-squared) + # Space Complexity: O(n) where n is the height of the recursion stack def preorder - raise NotImplementedError + @output = [] + current = @root + + return @output if !@root + + def analyzePreorder(current) + @output << {:key => current.key, :value => current.value} + analyzePreorder(current.left) if current.left + analyzePreorder(current.right) if current.right + end + + analyzePreorder(current) + + return @output end - # Time Complexity: - # Space Complexity: + # Time Complexity: O(n-squared) + # Space Complexity: O(n) where n is the height of the recursion stack def postorder - raise NotImplementedError + @output = [] + current = @root + + return @output if !@root + + def analyzePostorder(current) + analyzePostorder(current.left) if current.left + analyzePostorder(current.right) if current.right + @output << {:key => current.key, :value => current.value} + end + + analyzePostorder(current) + + return @output end - # Time Complexity: - # Space Complexity: + # Time Complexity: O(log n) if tree is balanced, O(n) if unbalanced + # Space Complexity: O(1) def height - raise NotImplementedError + return 0 if !@root + + def findMaxHeight(node) + return 0 if !node + + height_left = findMaxHeight(node.left) + height_right = findMaxHeight(node.right) + + return height_left > height_right ? (height_left + 1) : (height_right + 1) + end + + findMaxHeight(@root) end # Optional Method - # Time Complexity: - # Space Complexity: + # Time Complexity: + # Space Complexity: def bfs raise NotImplementedError end diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..48e341a --- /dev/null +++ b/package-lock.json @@ -0,0 +1,3 @@ +{ + "lockfileVersion": 1 +} diff --git a/test/tree_test.rb b/test/tree_test.rb index 8811f14..07c8c3e 100644 --- a/test/tree_test.rb +++ b/test/tree_test.rb @@ -1,6 +1,7 @@ +require 'minitest/autorun' +require 'minitest/skip_dsl' require_relative 'test_helper' - Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new describe Tree do @@ -10,7 +11,9 @@ tree.add(5, "Peter") tree.add(3, "Paul") tree.add(1, "Mary") + # tree.add(4, "Elle") tree.add(10, "Karla") + # tree.add(9, "Brad") tree.add(15, "Ada") tree.add(25, "Kari") tree @@ -38,8 +41,8 @@ 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"}, + 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 @@ -51,8 +54,8 @@ 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"}, + 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 @@ -63,21 +66,31 @@ 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"}, + 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 + describe "height" do + it "returns 0 for an empty tree" do + expect(tree.height).must_equal 0 + end + + it "returns correct height of tree" do + expect(tree_with_nodes.height).must_equal 4 + end + end + + xdescribe "breadth first search" do # optional 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"}, + 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