diff --git a/lib/tree.rb b/lib/tree.rb index c0d4b51..3e2f8b6 100644 --- a/lib/tree.rb +++ b/lib/tree.rb @@ -16,47 +16,131 @@ def initialize @root = nil end - # Time Complexity: - # Space Complexity: + # Time Complexity: O(h), where h is the maximum height of the binary tree. + # In a balanced tree, this would be O(log n) + # Space Complexity: O(1), the method will always create one(1) new node def add(key, value) - raise NotImplementedError + new_node = TreeNode.new(key, value) + if !@root + @root = new_node + return + end + current = @root + while current + if key <= current.key + if current.left + current = current.left + else + current.left = new_node + break + end + else + if current.right + current = current.right + else + current.right = new_node + break + end + end + end end - # Time Complexity: - # Space Complexity: + # Time Complexity: O(h), where h is the maximum height of the binary tree. + # In a balanced tree, this would be O(log n) + # Space Complexity: O(1), no new nodes are created def find(key) - raise NotImplementedError + current = @root + while current + if key == current.key + return current.value + elsif key < current.key + current = current.left + else + current = current.right + end + end + return end - # Time Complexity: - # Space Complexity: + # Time Complexity: O(n) where n is the number of nodes + # Space Complexity: O(n) where n is the number of nodes def inorder - raise NotImplementedError + nodes = [] + if @root + add_nodes_inorder(root, nodes) + end + return nodes end - # Time Complexity: - # Space Complexity: + def add_nodes_inorder(node, array) + return if !node + add_nodes_inorder(node.left, array) + array << { key: node.key, value: node.value } + add_nodes_inorder(node.right, array) + end + + # Time Complexity: O(n) where n is the number of nodes + # Space Complexity: O(n) where n is the number of nodes def preorder - raise NotImplementedError + nodes = [] + if @root + add_nodes_preorder(root, nodes) + end + return nodes + end + + def add_nodes_preorder(node, array) + return if !node + array << { key: node.key, value: node.value } + add_nodes_preorder(node.left, array) + add_nodes_preorder(node.right, array) end - # Time Complexity: - # Space Complexity: + # Time Complexity: O(n) where n is the number of nodes + # Space Complexity: O(n) where n is the number of nodes def postorder - raise NotImplementedError + nodes = [] + if @root + add_nodes_postorder(root, nodes) + end + return nodes end - # Time Complexity: - # Space Complexity: + def add_nodes_postorder(node, array) + return if !node + add_nodes_postorder(node.left, array) + add_nodes_postorder(node.right, array) + array << { key: node.key, value: node.value } + end + + # Time Complexity: O(n) where n is the number of nodes + # Space Complexity: O(n) where n is the number of nodes def height - raise NotImplementedError + return max_depth(@root) end + def max_depth(node) + return 0 if !node + right = max_depth(node.right) + left = max_depth(node.left) + return [right, left].max + 1 + end # Optional Method - # Time Complexity: - # Space Complexity: + # Time Complexity: O(n) where n is the number of nodes + # Space Complexity: O(n) where n is the number of nodes def bfs - raise NotImplementedError + return [] if !@root + queue = [] + nodes = [] + + queue.push(@root) + while !queue.empty? + current = queue.shift + nodes << { key: current.key, value: current.value } + queue.push(current.left) if current.left + queue.push(current.right) if current.right + end + return nodes end # Useful for printing diff --git a/test/tree_test.rb b/test/tree_test.rb index 8811f14..8902e6d 100644 --- a/test/tree_test.rb +++ b/test/tree_test.rb @@ -69,6 +69,16 @@ 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 number of edges from the root to the deepest leaf" 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 expect(tree.bfs).must_equal []