-
Notifications
You must be signed in to change notification settings - Fork 43
Branches - Eve #42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Branches - Eve #42
Changes from all commits
1087614
63ddb53
5a24df7
fa15c0f
d592866
8f2cf62
0d166c6
135ebdd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,66 +1,235 @@ | ||
| 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: | ||
| # Time Complexity: O(logn) in best case | ||
| # Space Complexity: O(1) | ||
| def add(key, value) | ||
| raise NotImplementedError | ||
| current_and_parent_pair = find_current_and_parent_nodes(key) | ||
| if current_and_parent_pair[:current] | ||
| # update new value if key exists | ||
| current_and_parent_pair[:current].value = value | ||
| else | ||
| new_node = TreeNode.new(key,value) | ||
| parent = current_and_parent_pair[:parent] | ||
| link_node_to_parent(parent, new_node) | ||
| end | ||
| end | ||
|
|
||
| # Time Complexity: | ||
| # Space Complexity: | ||
|
|
||
| # IN CLASS PRACTICE: add() recursive | ||
| # def add_helper(current_node, key, value) | ||
| # return TreeNode.new(key, value) if !current_node | ||
| # if current_node.key > key | ||
| # current_node.left = add_helper(current_node.left, key, value) | ||
| # else | ||
| # current_node.right = add_helper(current_node.right, key, value) | ||
| # end | ||
| # return current_node | ||
| # end | ||
|
|
||
| # def add(key, value) | ||
| # @root = add_helper(@root, key, value) | ||
| # end | ||
|
|
||
| # Time Complexity: O(logn) in best case | ||
| # Space Complexity: O(1) | ||
| def find(key) | ||
|
Comment on lines
+48
to
50
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
| raise NotImplementedError | ||
| current_and_parent_pair = find_current_and_parent_nodes(key) | ||
| if current_and_parent_pair[:current] | ||
| return current_and_parent_pair[:current].value | ||
| else | ||
| return nil | ||
| end | ||
| end | ||
|
|
||
| # Time Complexity: | ||
| # Space Complexity: | ||
| # Time Complexity: O(n) with n is the number of nodes in the tree | ||
| # Space Complexity: O(n) | ||
| def inorder | ||
|
Comment on lines
+59
to
61
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nicely done with a loop! |
||
| raise NotImplementedError | ||
| list = [] | ||
| stack = [] | ||
|
|
||
| current = @root | ||
| while current | ||
| stack << current | ||
| current = current.left | ||
| end | ||
|
|
||
| while !stack.empty? | ||
| top = stack.pop | ||
| list << {key: top.key, value: top.value} | ||
|
|
||
| if top.right | ||
| stack << top.right | ||
|
|
||
| current = top.right.left | ||
| while current | ||
| stack << current | ||
| current = current.left | ||
| end | ||
| end | ||
| end | ||
|
|
||
| return list | ||
| end | ||
|
|
||
| # Time Complexity: | ||
| # Space Complexity: | ||
|
|
||
| # IN CLASS PRACTICE: inorder() recursive | ||
| # def inorder_helper(current_node, list = []) | ||
| # return list if !current_node | ||
| # inorder_helper(current_node.left, list) | ||
| # list << {key: current_node.key, value: current_node.value} | ||
| # inorder_helper(current_node.right, list) | ||
| # return list | ||
| # end | ||
|
|
||
| # def inorder | ||
| # return inorder_helper(@root) | ||
| # end | ||
|
|
||
| # Time Complexity: O(n) with n is the number of nodes in the tree | ||
| # Space Complexity: O(n) | ||
| def preorder_helper(current_node, list = []) | ||
| return list if !current_node | ||
| list << {key: current_node.key, value: current_node.value} | ||
| preorder_helper(current_node.left, list) | ||
| preorder_helper(current_node.right, list) | ||
| return list | ||
| end | ||
|
|
||
| def preorder | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
| raise NotImplementedError | ||
| return preorder_helper(@root) | ||
| end | ||
|
|
||
| # Time Complexity: | ||
| # Space Complexity: | ||
|
|
||
| # Time Complexity: O(n) with n is the number of nodes in the tree | ||
| # Space Complexity: O(n) | ||
| def postorder_helper(current_node, list = []) | ||
| return list if !current_node | ||
| postorder_helper(current_node.left, list) | ||
| postorder_helper(current_node.right, list) | ||
| list << {key: current_node.key, value: current_node.value} | ||
| return list | ||
| end | ||
|
|
||
| def postorder | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
| raise NotImplementedError | ||
| return postorder_helper(@root) | ||
| end | ||
|
|
||
| # Time Complexity: | ||
| # Space Complexity: | ||
|
|
||
| # Time Complexity: O(n) with n is the number of nodes in the tree | ||
| # Space Complexity: O(logn) which is also the height of the tree. | ||
| def height_helper(current_node, level = 0) | ||
|
Comment on lines
+130
to
+132
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 Nicely done! |
||
| return level if !current_node | ||
| level = [height_helper(current_node.left, level + 1), height_helper(current_node.right, level + 1)].max | ||
| return level | ||
| end | ||
|
|
||
| def height | ||
| raise NotImplementedError | ||
| return height_helper(@root) | ||
| end | ||
|
|
||
| # Optional Method | ||
| # Time Complexity: | ||
| # Space Complexity: | ||
| # Time Complexity: O(n) | ||
| # Space Complexity: O(n) | ||
| def bfs | ||
|
Comment on lines
+143
to
145
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
| raise NotImplementedError | ||
| list = [] | ||
| if @root | ||
| queue = [] | ||
| queue << @root | ||
| queue.each do |current| | ||
| list << {key: current.key, value: current.value} | ||
| queue << current.left if current.left | ||
| queue << current.right if current.right | ||
| end | ||
| end | ||
| return list | ||
| end | ||
|
|
||
| def delete(key) | ||
| current_and_parent_pair = find_current_and_parent_nodes(key) | ||
| current = current_and_parent_pair[:current] | ||
| parent = current_and_parent_pair[:parent] | ||
| if current | ||
| remove_child(parent, current) | ||
| new_subtree = nil | ||
| # rearrange new subtree from children if current is not a leaf node | ||
| if current.left || current.right | ||
| left = current.left | ||
| right = current.right | ||
| right_subtree_leftmost = find_leftmost_node(right) | ||
| right_subtree_leftmost.left = left if right_subtree_leftmost | ||
|
|
||
| new_subtree = right_subtree_leftmost ? right : left | ||
tofuandeve marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| end | ||
|
|
||
| link_node_to_parent(parent, new_subtree) | ||
| end | ||
| end | ||
|
|
||
| # Useful for printing | ||
| def to_s | ||
| return "#{self.inorder}" | ||
| end | ||
|
|
||
| private | ||
| def find_current_and_parent_nodes(key) | ||
| current = @root | ||
| parent = nil | ||
|
|
||
| while current | ||
| if current.key == key | ||
| return {current: current, parent: parent} | ||
| elsif current.key > key | ||
| parent = current | ||
| current = current.left | ||
| else | ||
| parent = current | ||
| current = current.right | ||
| end | ||
| end | ||
|
|
||
| return {current: current, parent: parent} | ||
| end | ||
|
|
||
| def find_leftmost_node(current_node) | ||
| leftmost = current_node | ||
| while leftmost && leftmost.left | ||
| leftmost = leftmost.left | ||
| end | ||
| return leftmost | ||
| end | ||
|
|
||
| def link_node_to_parent(parent, node) | ||
| return if !node | ||
| if !parent | ||
| @root = node | ||
| elsif parent.key > node.key | ||
| parent.left = node | ||
| else | ||
| parent.right = node | ||
| end | ||
| end | ||
|
|
||
| def remove_child(parent, current) | ||
| if !parent | ||
| @root = nil | ||
| elsif current | ||
| if parent.key > current.key | ||
| parent.left = nil | ||
| else | ||
| parent.right = nil | ||
| end | ||
| end | ||
| end | ||
| end | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍