Skip to content
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

Cyndi #15

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions lib/example.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
class TreeNode

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's this file for?

attr_accessor :value, :left, :right

def initialize(val)
@value = val
@left = nil
@right = nil
end
end

class Tree
attr_reader :root

def initialize
@root = nil
end

def add(value)
new_node = TreeNode.new(value)
if @root.nil?
@root = new_node
else
add_helper(@root, new_node)
end
end

def add_helper(current, new_node)
return new_node if current.nil?
if new_node <= current.value
current.left = add_helper(current.left, new_node)
else
current.right = add_helper(current.right, new_node)
end

return current
end

def inorder(current, array)
if current == nil
return
else
inorder(current.left, array)
array << current.value
inorder(current.right, array)
end
end

def loop_traverse(root)
stack = []
output = []
current = root
while (current || !stack.empty?)
while (current)
stack.push(current)
current = current.left
end
current = stack.pop
output.push(current.value); #storing the data
current = current.right
end
puts "loop_traverse:" #prints out the output
puts output.join(" ")
end
end
176 changes: 153 additions & 23 deletions lib/tree.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,61 +2,191 @@ 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: if balanced, O(log h) where h is the height of the tree
# Space Complexity: if balanced, O(log h) where h is the height of the tree
def add(key, value)
raise NotImplementedError
new_node = TreeNode.new(key, value)
if @root.nil?
@root = new_node
else
add_helper(@root, new_node)
end
end

def add_helper(current, new_node)
if new_node.key <= current.key
if current.left
add_helper(current.left, new_node)
else
current.left = new_node
end
else
if current.right
add_helper(current.right, new_node)
else
current.right = new_node
end
end
end

# Time Complexity:
# Space Complexity:
# Time Complexity: O(h) if balanced, where h is the height of the tree
# Space Complexity: O(1)
def find(key)
raise NotImplementedError
return nil if @root.nil?
current = @root
while !current.nil?
if key == current.key
return current.value
elsif key <= current.key
current = current.left
else
current = current.right
end
end
end

# Time Complexity:
# Space Complexity:
# Time Complexity: O(n^2) where n is the number of nodes
# Space Complexity: O(n)
def inorder
raise NotImplementedError
stack = []
output = []
current = root
while current || !stack.empty?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's neat how you used stacks here to avoid the recursive solution.

while !current.nil?
stack.push(current)
current = current.left
end
current = stack.pop
new_hash = Hash.new
new_hash[:key] = current.key
new_hash[:value] = current.value
output.push(new_hash); #storing the data
current = current.right
end
return output
end

# Time Complexity:
# Space Complexity:
# Time Complexity: if well balanced, O(h) where h is the height of the tree

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could also say O(log n) if it's balanced, except that since you're going to visit each node in the tree, it has to be O(n)

# Space Complexity: O(h)
def preorder
raise NotImplementedError
stack = []
output = []

current = @root

return [] if current.nil?
stack.push(current)

while !stack.empty?
current = stack.pop()
new_hash = Hash.new
new_hash[:key] = current.key
new_hash[:value] = current.value
output.push(new_hash)
if current.right
stack.push(current.right)
end
if current.left
stack.push(current.left)
end
end
return output
end

# Time Complexity:
# Space Complexity:
# Time Complexity: if balanced, O(h) where h is the height of the tree
# Space Complexity: O(h)
def postorder
raise NotImplementedError
stack = []
output = []
return [] if @root.nil?
stack.push(@root)
while !stack.empty?
current = stack.pop()
new_hash = Hash.new
new_hash[:key] = current.key
new_hash[:value] = current.value
output.push(new_hash)
if current.left
stack.push(current.left)
end
if current.right
stack.push(current.right)
end
end
return output.reverse
end

# Time Complexity:
# Space Complexity:
# Time Complexity: if balanced, O(h) where h is the height of the tree

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you have to visit each node to figure out the height, it's O(n) for time complexity. Space is different.

# Space Complexity: O(h)
def height
raise NotImplementedError
stack = []
current = @root
stack.push(current)
count_left = 0
count_right = 0
max_count = 0
while !stack.empty?
current = stack.pop
if current.left
count_left += 1
stack.push(current.left)
else
if count_left > max_count
max_count = count_left
count_left = 0
end
end
if current.right
count_right += 1
stack.push(current.right)
else
if count_right > max_count
max_count = count_right
count_right = 0
end
end
end
return max_count
end

# Optional Method
# Time Complexity:
# Space Complexity:
# Time Complexity: if balanced, O(h) where h is the height of the tree
# Space Complexity: O(h)
def bfs
raise NotImplementedError
return [] if @root.nil?
queue = []
output = []
queue.push(@root)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Niiice!

while !queue.empty?
current = queue[0]
new_hash = Hash.new
new_hash[:key] = current.key
new_hash[:value] = current.value
output.push(new_hash)
if current.left
queue.push(current.left)
end
if current.right
queue.push(current.right)
end
queue = queue[1..-1]
end
return output
end

# Useful for printing
Expand Down
41 changes: 23 additions & 18 deletions test/tree_test.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
require_relative 'test_helper'

require_relative "test_helper"

Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new

describe Tree do
let (:tree) {Tree.new}
let (:tree) { Tree.new }

let (:tree_with_nodes) {
tree.add(5, "Peter")
Expand Down Expand Up @@ -37,23 +36,21 @@
end

it "will return the tree in order" do

expect(tree_with_nodes.inorder).must_equal [{:key=>1, :value=>"Mary"}, {:key=>3, :value=>"Paul"},
{:key=>5, :value=>"Peter"}, {:key=>10, :value=>"Karla"},
{:key=>15, :value=>"Ada"}, {:key=>25, :value=>"Kari"}]
expect(tree_with_nodes.inorder).must_equal [{ :key => 1, :value => "Mary" }, { :key => 3, :value => "Paul" },
{ :key => 5, :value => "Peter" }, { :key => 10, :value => "Karla" },
{ :key => 15, :value => "Ada" }, { :key => 25, :value => "Kari" }]
end
end


describe "preorder" do
it "will give an empty array for an empty tree" do
expect(tree.preorder).must_equal []
end

it "will return the tree in preorder" do
expect(tree_with_nodes.preorder).must_equal [{:key=>5, :value=>"Peter"}, {:key=>3, :value=>"Paul"},
{:key=>1, :value=>"Mary"}, {:key=>10, :value=>"Karla"},
{:key=>15, :value=>"Ada"}, {:key=>25, :value=>"Kari"}]
expect(tree_with_nodes.preorder).must_equal [{ :key => 5, :value => "Peter" }, { :key => 3, :value => "Paul" },
{ :key => 1, :value => "Mary" }, { :key => 10, :value => "Karla" },
{ :key => 15, :value => "Ada" }, { :key => 25, :value => "Kari" }]
end
end

Expand All @@ -63,9 +60,9 @@
end

it "will return the tree in postorder" do
expect(tree_with_nodes.postorder).must_equal [{:key=>1, :value=>"Mary"}, {:key=>3, :value=>"Paul"},
{:key=>25, :value=>"Kari"}, {:key=>15, :value=>"Ada"},
{:key=>10, :value=>"Karla"}, {:key=>5, :value=>"Peter"}]
expect(tree_with_nodes.postorder).must_equal [{ :key => 1, :value => "Mary" }, { :key => 3, :value => "Paul" },
{ :key => 25, :value => "Kari" }, { :key => 15, :value => "Ada" },
{ :key => 10, :value => "Karla" }, { :key => 5, :value => "Peter" }]
end
end

Expand All @@ -75,9 +72,17 @@
end

it "will return an array of a level-by-level output of the tree" do
expect(tree_with_nodes.bfs).must_equal [{:key=>5, :value=>"Peter"}, {:key=>3, :value=>"Paul"},
{:key=>10, :value=>"Karla"}, {:key=>1, :value=>"Mary"},
{:key=>15, :value=>"Ada"}, {:key=>25, :value=>"Kari"}]
expect(tree_with_nodes.bfs).must_equal [{ :key => 5, :value => "Peter" }, { :key => 3, :value => "Paul" },
{ :key => 10, :value => "Karla" }, { :key => 1, :value => "Mary" },
{ :key => 15, :value => "Ada" }, { :key => 25, :value => "Kari" }]
end
end

describe "height" do
it "will calc height" do
tree.add(4, "maya")
tree.add(4.5, "chelsea")
expect(tree_with_nodes.height).must_equal 5
end
end
end
end