diff --git a/lib/tree.rb b/lib/tree.rb index c0d4b51..601b61b 100644 --- a/lib/tree.rb +++ b/lib/tree.rb @@ -14,42 +14,114 @@ class Tree attr_reader :root def initialize @root = nil + @nodes = [] end - # Time Complexity: - # Space Complexity: + # Time Complexity: O(log n) for balanced trees, O(n) for unbalanced trees; where n is the number of nodes + # Space Complexity: O(n), where n is the height def add(key, value) - raise NotImplementedError + new_node = TreeNode.new(key, value) + return @root = new_node if !@root + add_helper(@root, new_node) end - # Time Complexity: - # Space Complexity: - def find(key) - raise NotImplementedError + def add_helper(current, new_node) + if new_node.key <= current.key + return current.left = new_node if !current.left + add_helper(current.left, new_node) + else + return current.right = new_node if !current.right + add_helper(current.right, new_node) + end end - # Time Complexity: - # Space Complexity: + # Time Complexity: O(log n) for balanced trees, O(n) for unbalanced trees; where n is the number of nodes + # Space Complexity: O(n), where n is the height + def find(key, current = @root) + return if !@root + return current.value if current.key == key + + key <= current.key ? find(key, current.left) : find(key, current.right) + end + + # Time Complexity: O(n), where n is the number of nodes + # Space Complexity: O(n), where n is the height def inorder - raise NotImplementedError + return @nodes if !@root + inorder_helper(@root) + return @nodes end - # Time Complexity: - # Space Complexity: + def inorder_helper(current) + return if !current + # traverse the left subtree + inorder_helper(current.left) + # visit the current node + @nodes.push( + { + key: current.key, + value: current.value + } + ) + #traverse the right subtree + inorder_helper(current.right) + end + + # Time Complexity: O(n), where n is the number of nodes + # Space Complexity: O(n), where n is the height def preorder - raise NotImplementedError + return @nodes if !@root + preorder_helper(@root) + return @nodes end - # Time Complexity: - # Space Complexity: + def preorder_helper(current) + return if !current + # visit the current node + @nodes.push( + { + key: current.key, + value: current.value + } + ) + # traverse the left subtree + preorder_helper(current.left) + #traverse the right subtree + preorder_helper(current.right) + end + + # Time Complexity: O(n), where n is the number of nodes + # Space Complexity: O(n), where n is the height def postorder - raise NotImplementedError + return @nodes if !@root + postorder_helper(@root) + return @nodes end - # Time Complexity: - # Space Complexity: - def height - raise NotImplementedError + def postorder_helper(current) + return if !current + # traverse the left subtree + postorder_helper(current.left) + #traverse the right subtree + postorder_helper(current.right) + # visit the current node + @nodes.push( + { + key: current.key, + value: current.value + } + ) + end + + # Time Complexity: O(n), where n is the number of nodes + # Space Complexity: O(n), where n is the height + def height(current = @root, height = 0) + # If the current node is nil return 0 + return height if !current + # Otherwise return 1 plus the maximum of the heights of the right and left subtrees + left = height(current.left, height + 1) + right = height(current.right, height + 1) + return left >= right ? left : right end # Optional Method