diff --git a/lib/tree.rb b/lib/tree.rb index c0d4b51..c4b9518 100644 --- a/lib/tree.rb +++ b/lib/tree.rb @@ -1,66 +1,170 @@ +# frozen_string_literal: true + 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 print_root(node = @root) + if node.nil? + puts 'root is nil' + else + puts node.value + puts node.key + end + end + + + # Time Complexity: + # Space Complexity: def add(key, value) - raise NotImplementedError + current_node = @root + + @root = TreeNode.new(key, value) if current_node.nil? + + until current_node.nil? + if (key < current_node.key) && current_node.left.nil? + current_node.left = TreeNode.new(key, value) + elsif (key > current_node.key) && current_node.right.nil? + current_node.right = TreeNode.new(key, value) + elsif key < current_node.key + current_node = current_node.left + elsif key > current_node.key + current_node = current_node.right + else + return + end + end + end + + # Time Complexity: O(n) + # Space Complexity: O(n) + + def find_recursive(current, key) + return nil if current.nil? + + return current.value if key == current.key + + if key < current.key + find_recursive(current.left, key) + elsif key > current.key + find_recursive(current.right, key) + end end - # Time Complexity: - # Space Complexity: def find(key) - raise NotImplementedError + find_recursive(@root, key) + end + + # Time Complexity: O(n) + # Space Complexity: O(n) + + def inorder_recursion(current, traverse_array) + return if current.nil? + + inorder_recursion(current.left, traverse_array) + + traverse_array << { key: current.key, value: current.value } + + inorder_recursion(current.right, traverse_array) end - # Time Complexity: - # Space Complexity: def inorder - raise NotImplementedError + traverse_array = [] + + inorder_recursion(@root, traverse_array) + + traverse_array + end + + # Time Complexity: O(n) + # Space Complexity: O(n) + def preorder_recursion(current, traverse_array) + return if current.nil? + + traverse_array << { key: current.key, value: current.value } + preorder_recursion(current.left, traverse_array) + preorder_recursion(current.right, traverse_array) end - # Time Complexity: - # Space Complexity: def preorder - raise NotImplementedError + traverse_array = [] + + preorder_recursion(@root, traverse_array) + + traverse_array + end + + # Time Complexity: O(n) + # Space Complexity: O(n) + def postorder_recursion(current, traverse_array) + return if current.nil? + + postorder_recursion(current.left, traverse_array) + postorder_recursion(current.right, traverse_array) + traverse_array << { key: current.key, value: current.value } end - # Time Complexity: - # Space Complexity: def postorder - raise NotImplementedError + traverse_array = [] + + postorder_recursion(@root, traverse_array) + + traverse_array end - # Time Complexity: - # Space Complexity: + # Time Complexity: + # Space Complexity: + def height - raise NotImplementedError + count_right = 0 + count_left = 0 + node = @root + return count_left if node.nil? + + count_left = height_helper(node, 'left', count_left) + count_right = height_helper(node, 'right', count_right) + if count_right > count_left + count_right + else + count_left + end + end + + def height_helper(node, side, count) + return count if node.nil? + + count += 1 + if side == 'left' + height_helper(node.left, 'left', count) + else + height_helper(node.right, 'right', count) + end end # Optional Method - # Time Complexity: - # Space Complexity: + # Time Complexity: + # Space Complexity: def bfs raise NotImplementedError end # Useful for printing def to_s - return "#{self.inorder}" + inorder.to_s end end