From baf438e23af626b8099ddf1bc9a46fadd481872f Mon Sep 17 00:00:00 2001 From: Evelynn Kaplan Date: Wed, 4 Sep 2019 21:24:12 -0700 Subject: [PATCH 1/4] wrote add and find, having a hard time with the others --- lib/tree.rb | 99 +++++++++++++++++++++++++++++++-------- test/tree_test.rb | 116 +++++++++++++++++++++++----------------------- 2 files changed, 137 insertions(+), 78 deletions(-) diff --git a/lib/tree.rb b/lib/tree.rb index c0d4b51..1b57536 100644 --- a/lib/tree.rb +++ b/lib/tree.rb @@ -2,59 +2,118 @@ 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(log n) if the tree is balanced, where n is the number of nodes in the tree. + # Space Complexity: O(1) def add(key, value) - raise NotImplementedError + new_node = TreeNode.new(key, value) + + current = @root + + if current == nil + @root = new_node + elsif new_node.key <= current.key + if current.left == nil + current.left = new_node + else + return self.add(key, value) + end + else + if current.right == nil + current.right = new_node + else + return self.add(key, value) + end + end end - # Time Complexity: - # Space Complexity: + # Time Complexity: O(log n) if the tree is balanced, where n is the number of nodes in the tree. + # Space Complexity: O(1) def find(key) - raise NotImplementedError + current = @root + + if current == nil + return nil + end + + 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: + # Space Complexity: + # left root right def inorder - raise NotImplementedError + current = @root + tree_nodes = [] + + # get current to farthest left node + until current.left == nil + current = current.left + end + + tree_nodes << current + + current = current.right + + tree_nodes << current + + current = current.right + + tree_nodes << current end - # Time Complexity: - # Space Complexity: + # Time Complexity: + # Space Complexity: def preorder raise NotImplementedError end - # Time Complexity: - # Space Complexity: + # Time Complexity: + # Space Complexity: def postorder raise NotImplementedError end - # Time Complexity: - # Space Complexity: + # Time Complexity: + # Space Complexity: def height - raise NotImplementedError + tree_height = 0 + current = @root + + if current == nil + return tree_height + end + + if current.left == nil && current.right == nil + + return tree_height end # Optional Method - # Time Complexity: - # Space Complexity: + # Time Complexity: + # Space Complexity: def bfs raise NotImplementedError end diff --git a/test/tree_test.rb b/test/tree_test.rb index 222b693..5d9c31f 100644 --- a/test/tree_test.rb +++ b/test/tree_test.rb @@ -31,63 +31,63 @@ expect(tree.find(50)).must_be_nil end - describe "inorder" do - it "will give an empty array for an empty tree" do - expect(tree.inorder).must_equal [] - 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"}] - 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"}] - end - end - - describe "postorder" do - it "will give an empty array for an empty tree" do - expect(tree.postorder).must_equal [] - 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"}] - end - end + # describe "inorder" do + # it "will give an empty array for an empty tree" do + # expect(tree.inorder).must_equal [] + # 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"}] + # 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"}] + # end + # end + + # describe "postorder" do + # it "will give an empty array for an empty tree" do + # expect(tree.postorder).must_equal [] + # 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"}] + # end + # end - describe "height" do - it "returns 0 for an empty tree" do - expect(tree.height).must_equal 0 - end - - it "returns correct height of tree" 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 [] - 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"}] - end - end + # describe "height" do + # it "returns 0 for an empty tree" do + # expect(tree.height).must_equal 0 + # end + + # it "returns correct height of tree" 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 [] + # 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"}] + # end + # end end From ecfc31d5d7c0d586973bbeee47474b4eae89d735 Mon Sep 17 00:00:00 2001 From: Evelynn Kaplan Date: Sat, 7 Sep 2019 16:08:50 -0700 Subject: [PATCH 2/4] wrote all methods, passes all tests --- lib/tree.rb | 166 +++++++++++++++++++++++++++++++--------------- test/tree_test.rb | 121 ++++++++++++++++----------------- 2 files changed, 170 insertions(+), 117 deletions(-) diff --git a/lib/tree.rb b/lib/tree.rb index 1b57536..25d2e2b 100644 --- a/lib/tree.rb +++ b/lib/tree.rb @@ -1,3 +1,5 @@ +require "pry" + class TreeNode attr_reader :key, :value attr_accessor :left, :right @@ -8,6 +10,59 @@ def initialize(key, val) @left = nil @right = nil end + + def add(key, value) + new_node = TreeNode.new(key, value) + if new_node.key <= @key + if @left == nil + @left = new_node + else + @left.add(key, value) + end + else + if @right == nil + @right = new_node + else + @right.add(key, value) + end + end + end + + def inorder(array) + if @left != nil + @left.inorder(array) + end + + array << {key: @key, value: @value} + + if @right != nil + @right.inorder(array) + end + end + + def preorder(array) + array << {key: @key, value: @value} + + if @left != nil + @left.preorder(array) + end + + if @right != nil + @right.preorder(array) + end + end + + def postorder(array) + if @left != nil + @left.postorder(array) + end + + if @right != nil + @right.postorder(array) + end + + array << {key: @key, value: @value} + end end class Tree @@ -20,24 +75,10 @@ def initialize # Time Complexity: O(log n) if the tree is balanced, where n is the number of nodes in the tree. # Space Complexity: O(1) def add(key, value) - new_node = TreeNode.new(key, value) - - current = @root - - if current == nil - @root = new_node - elsif new_node.key <= current.key - if current.left == nil - current.left = new_node - else - return self.add(key, value) - end + if @root == nil + @root = TreeNode.new(key, value) else - if current.right == nil - current.right = new_node - else - return self.add(key, value) - end + @root.add(key, value) end end @@ -61,61 +102,76 @@ def find(key) end end - # Time Complexity: - # Space Complexity: + # Time Complexity: O(n) where n is the number of nodes in the tree + # Space Complexity: O(n) where n is the number of nodes in the tree # left root right def inorder current = @root - tree_nodes = [] - - # get current to farthest left node - until current.left == nil - current = current.left + values = [] + if current != nil + current.inorder(values) end - - tree_nodes << current - - current = current.right - - tree_nodes << current - - current = current.right - - tree_nodes << current + return values end - # Time Complexity: - # Space Complexity: + # Time Complexity: O(n) where n is the number of nodes in the tree + # Space Complexity: O(n) where n is the number of nodes in the tree def preorder - raise NotImplementedError + current = @root + values = [] + if current != nil + current.preorder(values) + end + return values end - # Time Complexity: - # Space Complexity: + # Time Complexity: O(n) where n is the number of nodes in the tree + # Space Complexity: O(n) where n is the number of nodes in the tree def postorder - raise NotImplementedError + current = @root + values = [] + if current != nil + current.postorder(values) + end + return values end - # Time Complexity: - # Space Complexity: - def height - tree_height = 0 - current = @root - - if current == nil - return tree_height + # Time Complexity: O(n) where n is the number of nodes in the tree + # Space Complexity: O(1) + def height(node) + if node == nil + return 0 + else + left_height = height(node.left) + right_height = height(node.right) + if left_height >= right_height + return 1 + left_height + else + return 1 + right_height + end end - - if current.left == nil && current.right == nil - - return tree_height end # Optional Method - # Time Complexity: - # Space Complexity: + # Time Complexity: O(n) where n is the number of nodes in the tree + # Space Complexity: O(n) where n is the number of nodes in the tree def bfs - raise NotImplementedError + if @root == nil + return [] + end + + queue = [@root] + bfs_values = [] + + while queue.length > 0 + node = queue[0] + bfs_values << {key: node.key, value: node.value} + queue << node.left unless node.left == nil + queue << node.right unless node.right == nil + queue.delete_at(0) + end + + return bfs_values end # Useful for printing diff --git a/test/tree_test.rb b/test/tree_test.rb index 5d9c31f..a491220 100644 --- a/test/tree_test.rb +++ b/test/tree_test.rb @@ -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") @@ -31,63 +30,61 @@ expect(tree.find(50)).must_be_nil end - # describe "inorder" do - # it "will give an empty array for an empty tree" do - # expect(tree.inorder).must_equal [] - # 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"}] - # 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"}] - # end - # end - - # describe "postorder" do - # it "will give an empty array for an empty tree" do - # expect(tree.postorder).must_equal [] - # 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"}] - # end - # end - - # describe "height" do - # it "returns 0 for an empty tree" do - # expect(tree.height).must_equal 0 - # end - - # it "returns correct height of tree" 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 [] - # 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"}] - # end - # end + describe "inorder" do + it "will give an empty array for an empty tree" do + expect(tree.inorder).must_equal [] + 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"}] + 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"}] + end + end + + describe "postorder" do + it "will give an empty array for an empty tree" do + expect(tree.postorder).must_equal [] + 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"}] + end + end + + describe "height" do + it "returns 0 for an empty tree" do + expect(tree.height(tree.root)).must_equal 0 + end + + it "returns correct height of tree" do + expect(tree_with_nodes.height(tree.root)).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 [] + 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"}] + end + end end From 215681a69e27fdf1fcae495c46c1b9ec2d06c96a Mon Sep 17 00:00:00 2001 From: Evelynn Kaplan Date: Sat, 7 Sep 2019 16:09:54 -0700 Subject: [PATCH 3/4] remove pry --- lib/tree.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/tree.rb b/lib/tree.rb index 25d2e2b..25a31c4 100644 --- a/lib/tree.rb +++ b/lib/tree.rb @@ -1,5 +1,3 @@ -require "pry" - class TreeNode attr_reader :key, :value attr_accessor :left, :right From 544c06b7f5eb086f36209c24d8aacbbf02648153 Mon Sep 17 00:00:00 2001 From: Evelynn Kaplan Date: Sun, 8 Sep 2019 00:09:15 -0700 Subject: [PATCH 4/4] implemented bfs with queue --- lib/tree.rb | 80 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 74 insertions(+), 6 deletions(-) diff --git a/lib/tree.rb b/lib/tree.rb index 25a31c4..d89068e 100644 --- a/lib/tree.rb +++ b/lib/tree.rb @@ -1,3 +1,70 @@ +QUEUE_SIZE = 20 + +class Queue + def initialize + @store = Array.new(QUEUE_SIZE) + @front = @rear = -1 + end + + def enqueue(element) + if @front == -1 # Q is empty + @rear = 1 + @front = 0 + @store[@front] = element + elsif @front == @rear && !self.empty? + raise Error, "Q IS FULL" + else #not empty + new_rear = (@rear + 1) % QUEUE_SIZE + @store[@rear] = element + @rear = new_rear + end + end + + def dequeue + if @front == -1 + return nil + end + index_to_remove = @front + value_to_remove = @store[index_to_remove] + @store[index_to_remove] = nil + @front += 1 + return value_to_remove + end + + def front + return @store[@front] + end + + def size + size = 0 + return 0 if self.empty? + + @store.each do |i| + if i != nil + size += 1 + end + end + + return size + end + + def empty? + return true if self.to_s == "[]" + return false + end + + def to_s + values = [] + @store.each do |i| + if i != nil + values << i + end + end + + return values.to_s + end +end + class TreeNode attr_reader :key, :value attr_accessor :left, :right @@ -158,15 +225,16 @@ def bfs return [] end - queue = [@root] + queue = Queue.new + queue.enqueue(@root) bfs_values = [] - while queue.length > 0 - node = queue[0] + while queue.size > 0 + node = queue.front bfs_values << {key: node.key, value: node.value} - queue << node.left unless node.left == nil - queue << node.right unless node.right == nil - queue.delete_at(0) + queue.enqueue(node.left) unless node.left == nil + queue.enqueue(node.right) unless node.right == nil + queue.dequeue end return bfs_values