diff --git a/lib/tree.rb b/lib/tree.rb index c0d4b51..e633f7c 100644 --- a/lib/tree.rb +++ b/lib/tree.rb @@ -1,3 +1,5 @@ +require_relative '../../stacks-queues/lib/queue' + class TreeNode attr_reader :key, :value attr_accessor :left, :right @@ -11,52 +13,112 @@ def initialize(key, val) end class Tree - attr_reader :root + attr_reader :root, :size def initialize @root = nil + @size = 0 end - # Time Complexity: - # Space Complexity: + # Time Complexity: O(n) + # Space Complexity: O(1) def add(key, value) - raise NotImplementedError + if @root.nil? + @root = TreeNode.new(key, value) + else + current = @root + prev = @root + + while current + prev = current + if key < current.key + current = current.left + else + current = current.right + end + end + if key < prev.key + prev.left = TreeNode.new(key, value) + else + prev.right = TreeNode.new(key, value) + end + end + @size += 1 end - # Time Complexity: - # Space Complexity: + # Time Complexity: worst case: O(n), best case: O(log n) + # Space Complexity: O(1) def find(key) - raise NotImplementedError + current = @root + while current + if current.key == key + return current.value + elsif key > current.key + current = current.right + else + current = current.left + end + end + return nil end - # Time Complexity: - # Space Complexity: - def inorder - raise NotImplementedError + # Time Complexity: O(n) + # Space Complexity: O(n) + def inorder(array=[], current=@root) + return array if current == nil + inorder(array, current.left) + array << {key: current.key, value: current.value} + inorder(array, current.right) end - # Time Complexity: - # Space Complexity: - def preorder - raise NotImplementedError + # Time Complexity: O(n) + # Space Complexity: O(n) + def preorder(array=[],current=@root) + return array if current.nil? + array << {key: current.key, value: current.value} + preorder(array, current.left) + preorder(array, current.right) end - # Time Complexity: - # Space Complexity: - def postorder - raise NotImplementedError + # Time Complexity: O(n) + # Space Complexity: O(n) + def postorder(array=[], current=@root) + return array if current.nil? + postorder(array, current.left) + postorder(array, current.right) + array << {key: current.key, value: current.value} end - # Time Complexity: - # Space Complexity: - def height - raise NotImplementedError + # Time Complexity: O(n) + # Space Complexity: O(n) + def height(current=@root) + return 0 if current.nil? + return 1 if current.right.nil? && current.left.nil? + + left_count = 0 + right_count = 0 + left_count += 1 + height(current.left) + right_count += 1 + height(current.right) + left_count > right_count ? left_count : right_count end # Optional Method - # Time Complexity: - # Space Complexity: + # Time Complexity: O(n) + # Space Complexity: O(n) def bfs - raise NotImplementedError + array = [] + return array if @root.nil? + queue = [@root] + while !queue.empty? + current = queue.shift + array << {key: current.key, value: current.value} + unless current.left.nil? + queue.push(current.left) + end + unless current.right.nil? + queue.push(current.right) + end + end + return array end # Useful for printing diff --git a/test/tree_test.rb b/test/tree_test.rb index 60f5981..9c1fb89 100644 --- a/test/tree_test.rb +++ b/test/tree_test.rb @@ -91,7 +91,7 @@ it "will return 1 for a tree of height 1" do my_tree = Tree.new - my_tree.add(100) + my_tree.add(100, "bruno") expect(my_tree.height).must_equal 1 end @@ -102,11 +102,11 @@ it "will report the height for unbalanced trees" do my_tree = Tree.new - my_tree.add(100) - my_tree.add(110) - my_tree.add(120) - my_tree.add(130) - my_tree.add(140) + my_tree.add(100, "bella") + my_tree.add(110, "rocky") + my_tree.add(120, "snowball") + my_tree.add(130, "mr. whiskers") + my_tree.add(140, "bebe") expect(my_tree.height).must_equal 5 @@ -114,11 +114,11 @@ my_tree = Tree.new - my_tree.add(100) - my_tree.add(90) - my_tree.add(80) - my_tree.add(70) - my_tree.add(60) + my_tree.add(100, "bruno") + my_tree.add(90, "bella") + my_tree.add(80, "arbor") + my_tree.add(70, "teal") + my_tree.add(60, "josh") expect(my_tree.height).must_equal 5 end