ruby_structures 1.0.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/data_structures/binary_tree.rb +89 -0
- data/lib/data_structures/linked_list.rb +28 -31
- data/lib/data_structures/lru_cache.rb +80 -0
- data/lib/ruby_structures.rb +2 -0
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6782ad1fced1c7fb1843ea6d4c768f19398c4bfc
|
4
|
+
data.tar.gz: 8c4c4c5cffc4a05184b38076032b18f7916ceb82
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 94a8daae5487dc44c589b3f2e2b0083e93758508c5a502b9da6ce7df9b67da44d35dd0e7d951a0d9abfb7332433a3da66f12504db62959450ba5dcce1a57001c
|
7
|
+
data.tar.gz: d880a0579d69066e63e1be514dc1718d2cf3d341ad404e52ff653deb544a537cfbc23b128bad425f81cde638ae0b436076350065d40875cddf7d423655756771
|
@@ -0,0 +1,89 @@
|
|
1
|
+
class BinaryTree
|
2
|
+
def self.from_array(array)
|
3
|
+
binary_tree = BinaryTree.new
|
4
|
+
return binary_tree if array.empty?
|
5
|
+
|
6
|
+
head_node = BinaryTreeNode.new(array.first)
|
7
|
+
binary_tree.send(:head=, head_node)
|
8
|
+
return binary_tree if array.length == 1
|
9
|
+
|
10
|
+
current_node = head_node
|
11
|
+
node_arr = []
|
12
|
+
array[1..-1].each do |el|
|
13
|
+
node = BinaryTreeNode.new(el, current_node)
|
14
|
+
node_arr << node
|
15
|
+
binary_tree.send(:leaves) << node
|
16
|
+
current_node.send(:left_child).nil? ? current_node.send(:left_child=, node) : current_node.send(:right_child=, node)
|
17
|
+
binary_tree.send(:leaves).delete(current_node)
|
18
|
+
current_node = node_arr.shift if current_node.send(:right_child)
|
19
|
+
end
|
20
|
+
|
21
|
+
binary_tree
|
22
|
+
end
|
23
|
+
|
24
|
+
def initialize
|
25
|
+
@head = nil
|
26
|
+
@leaves = []
|
27
|
+
end
|
28
|
+
|
29
|
+
def depth_first_search(target=nil, &prc)
|
30
|
+
raise ArgumentError.new('Must pass either a target value or a block') unless (target || prc) && !(target && prc)
|
31
|
+
prc ||= Proc.new { |node| node.send(:val) == target }
|
32
|
+
|
33
|
+
return nil if @head.nil?
|
34
|
+
@head.send(:depth_first_search, &prc)
|
35
|
+
end
|
36
|
+
|
37
|
+
def breadth_first_search(target=nil, &prc)
|
38
|
+
raise ArgumentError.new('Must pass either a target value or a block') unless (target || prc) && !(target && prc)
|
39
|
+
prc ||= Proc.new { |node| node.send(:val) == target }
|
40
|
+
|
41
|
+
nodes = [@head]
|
42
|
+
until nodes.empty?
|
43
|
+
node = nodes.shift
|
44
|
+
next if node.nil?
|
45
|
+
return node if prc.call(node)
|
46
|
+
nodes.concat([node.send(:left_child), node.send(:right_child)])
|
47
|
+
end
|
48
|
+
|
49
|
+
nil
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
attr_accessor :head
|
55
|
+
attr_reader :leaves
|
56
|
+
end
|
57
|
+
|
58
|
+
class BinaryTreeNode
|
59
|
+
def initialize(val=nil, parent=nil, left_child=nil, right_child=nil)
|
60
|
+
@val = val
|
61
|
+
@parent = parent
|
62
|
+
@left_child = left_child
|
63
|
+
@right_child = right_child
|
64
|
+
end
|
65
|
+
|
66
|
+
def to_s
|
67
|
+
@val
|
68
|
+
end
|
69
|
+
|
70
|
+
def inspect
|
71
|
+
@val
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def depth_first_search(&prc)
|
77
|
+
return self if prc.call(self)
|
78
|
+
|
79
|
+
[@left_child, @right_child].each do |child|
|
80
|
+
next if child.nil?
|
81
|
+
result = child.send(:depth_first_search, &prc)
|
82
|
+
return result unless result.nil?
|
83
|
+
end
|
84
|
+
|
85
|
+
nil
|
86
|
+
end
|
87
|
+
|
88
|
+
attr_accessor :val, :parent, :left_child, :right_child
|
89
|
+
end
|
@@ -16,14 +16,14 @@ class LinkedList
|
|
16
16
|
return "-" if self.empty?
|
17
17
|
|
18
18
|
vals = self.to_a { |n| n.send(:val) }
|
19
|
-
vals.join('
|
19
|
+
vals.join(' <=> ')
|
20
20
|
end
|
21
21
|
|
22
22
|
def inspect
|
23
23
|
return "-" if self.empty?
|
24
24
|
|
25
25
|
vals = self.to_a { |n| n.send(:val) }
|
26
|
-
vals.join('
|
26
|
+
vals.join(' <=> ')
|
27
27
|
end
|
28
28
|
|
29
29
|
def empty?
|
@@ -40,8 +40,8 @@ class LinkedList
|
|
40
40
|
last == @head ? nil : last
|
41
41
|
end
|
42
42
|
|
43
|
-
def append(val=nil)
|
44
|
-
node = LinkedListNode.new(val)
|
43
|
+
def append(key=nil, val=nil)
|
44
|
+
node = LinkedListNode.new(key, val)
|
45
45
|
last = @tail.send(:prev)
|
46
46
|
|
47
47
|
last.send(:next=, node)
|
@@ -53,8 +53,8 @@ class LinkedList
|
|
53
53
|
node
|
54
54
|
end
|
55
55
|
|
56
|
-
def prepend(val=nil)
|
57
|
-
node = LinkedListNode.new(val)
|
56
|
+
def prepend(key=nil, val=nil)
|
57
|
+
node = LinkedListNode.new(key, val)
|
58
58
|
first = @head.send(:next)
|
59
59
|
|
60
60
|
first.send(:prev=, node)
|
@@ -66,18 +66,28 @@ class LinkedList
|
|
66
66
|
node
|
67
67
|
end
|
68
68
|
|
69
|
-
def
|
69
|
+
def find_by_key(key)
|
70
|
+
self.each { |node| return node if node.send(:key) == key }
|
71
|
+
nil
|
72
|
+
end
|
73
|
+
|
74
|
+
def find_by_val(val)
|
70
75
|
self.each { |node| return node if node.send(:val) == val }
|
71
76
|
nil
|
72
77
|
end
|
73
78
|
|
74
|
-
def
|
79
|
+
def include_key?(key)
|
80
|
+
self.each { |node| return true if node.send(:key) == key }
|
81
|
+
false
|
82
|
+
end
|
83
|
+
|
84
|
+
def include_val?(val)
|
75
85
|
self.each { |node| return true if node.send(:val) == val }
|
76
86
|
false
|
77
87
|
end
|
78
88
|
|
79
|
-
def remove(
|
80
|
-
node = self.
|
89
|
+
def remove(key)
|
90
|
+
node = self.find_by_key(key)
|
81
91
|
return nil if node.nil?
|
82
92
|
|
83
93
|
prev_node = node.send(:prev)
|
@@ -89,9 +99,9 @@ class LinkedList
|
|
89
99
|
node
|
90
100
|
end
|
91
101
|
|
92
|
-
def update(
|
93
|
-
node = self.
|
94
|
-
raise ArgumentError.new("Couldn't find Node with
|
102
|
+
def update(key, new_val)
|
103
|
+
node = self.find_by_key(key)
|
104
|
+
raise ArgumentError.new("Couldn't find Node with key=#{key}") if node.nil?
|
95
105
|
|
96
106
|
node.send(:val=, new_val)
|
97
107
|
node
|
@@ -108,38 +118,25 @@ class LinkedList
|
|
108
118
|
|
109
119
|
self
|
110
120
|
end
|
111
|
-
|
112
|
-
def map(&prc)
|
113
|
-
new_linked_list = LinkedList.new
|
114
|
-
current_node = @head.send(:next)
|
115
|
-
return new_linked_list if current_node.nil?
|
116
|
-
|
117
|
-
while current_node != @tail
|
118
|
-
val = prc.call(current_node)
|
119
|
-
new_linked_list.append(val)
|
120
|
-
current_node = current_node.send(:next)
|
121
|
-
end
|
122
|
-
|
123
|
-
new_linked_list
|
124
|
-
end
|
125
121
|
end
|
126
122
|
|
127
123
|
class LinkedListNode
|
128
|
-
def initialize(val=nil, next_node=nil, prev_node=nil)
|
124
|
+
def initialize(key=nil, val=nil, next_node=nil, prev_node=nil)
|
125
|
+
@key = key
|
129
126
|
@val = val
|
130
127
|
@next = next_node
|
131
128
|
@prev = prev_node
|
132
129
|
end
|
133
130
|
|
134
131
|
def to_s
|
135
|
-
val
|
132
|
+
@val
|
136
133
|
end
|
137
134
|
|
138
135
|
def inspect
|
139
|
-
val
|
136
|
+
@val
|
140
137
|
end
|
141
138
|
|
142
139
|
private
|
143
140
|
|
144
|
-
attr_accessor :val, :next, :prev
|
141
|
+
attr_accessor :key, :val, :next, :prev
|
145
142
|
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require_relative 'linked_list'
|
2
|
+
|
3
|
+
class LRUCache
|
4
|
+
def initialize(max_size)
|
5
|
+
@max_size = max_size
|
6
|
+
@size = 0
|
7
|
+
@hash = {}
|
8
|
+
@linked_list = LinkedList.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_a
|
12
|
+
@linked_list.to_a
|
13
|
+
end
|
14
|
+
|
15
|
+
def empty?
|
16
|
+
@size == 0
|
17
|
+
end
|
18
|
+
|
19
|
+
def first
|
20
|
+
@linked_list.first
|
21
|
+
end
|
22
|
+
|
23
|
+
def last
|
24
|
+
@linked_list.last
|
25
|
+
end
|
26
|
+
|
27
|
+
def find(key)
|
28
|
+
@hash[key]
|
29
|
+
end
|
30
|
+
|
31
|
+
def include?(key)
|
32
|
+
@hash.has_key?(key)
|
33
|
+
end
|
34
|
+
|
35
|
+
def append(key, val)
|
36
|
+
node = @linked_list.append(key, val)
|
37
|
+
@hash[key] = node
|
38
|
+
|
39
|
+
@size += 1
|
40
|
+
if @size > @max_size
|
41
|
+
first_node_key = @linked_list.first.send(:key)
|
42
|
+
@linked_list.remove(first_node_key)
|
43
|
+
@hash.delete(first_node_key)
|
44
|
+
@size -= 1
|
45
|
+
end
|
46
|
+
|
47
|
+
node
|
48
|
+
end
|
49
|
+
|
50
|
+
def prepend(key, val)
|
51
|
+
node = @linked_list.prepend(key, val)
|
52
|
+
@hash[key] = node
|
53
|
+
|
54
|
+
@size += 1
|
55
|
+
if @size > @max_size
|
56
|
+
last_node_key = @linked_list.last.send(:key)
|
57
|
+
@linked_list.remove(last_node_key)
|
58
|
+
@hash.delete(last_node_key)
|
59
|
+
@size -= 1
|
60
|
+
end
|
61
|
+
|
62
|
+
node
|
63
|
+
end
|
64
|
+
|
65
|
+
def remove(key)
|
66
|
+
node = self.find(key)
|
67
|
+
return nil if node.nil?
|
68
|
+
|
69
|
+
@linked_list.remove(key)
|
70
|
+
@hash.delete(key)
|
71
|
+
@size -= 1
|
72
|
+
|
73
|
+
node
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
attr_accessor :max_size, :size
|
79
|
+
attr_reader :hash, :linked_list
|
80
|
+
end
|
data/lib/ruby_structures.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby_structures
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jason Numeroff
|
@@ -10,17 +10,20 @@ bindir: bin
|
|
10
10
|
cert_chain: []
|
11
11
|
date: 2018-05-08 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
|
-
description: Ruby implementations of a Stack, Queue
|
13
|
+
description: Ruby implementations of a Stack, Queue, Linked List, Binary Tree and
|
14
|
+
LRU Cache. More to come!
|
14
15
|
email: jnumeroff@hotmail.com
|
15
16
|
executables: []
|
16
17
|
extensions: []
|
17
18
|
extra_rdoc_files: []
|
18
19
|
files:
|
20
|
+
- lib/data_structures/binary_tree.rb
|
19
21
|
- lib/data_structures/linked_list.rb
|
22
|
+
- lib/data_structures/lru_cache.rb
|
20
23
|
- lib/data_structures/queue.rb
|
21
24
|
- lib/data_structures/stack.rb
|
22
25
|
- lib/ruby_structures.rb
|
23
|
-
homepage: https://github.com/Numie/
|
26
|
+
homepage: https://github.com/Numie/RubyStructures
|
24
27
|
licenses:
|
25
28
|
- MIT
|
26
29
|
metadata: {}
|