data-struct 0.0.6
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 +7 -0
- data/lib/data-struct.rb +13 -0
- data/lib/doubly_linked_list.rb +61 -0
- data/lib/dynamic_array.rb +118 -0
- data/lib/max_stack.rb +24 -0
- data/lib/min_max_stack.rb +33 -0
- data/lib/singly_linked_list.rb +63 -0
- data/lib/stack_queue.rb +28 -0
- metadata +53 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 5061a74197d99c6e371bcef1d8b0f2c7d14c8075
|
4
|
+
data.tar.gz: 8b63a07ed7dcd06a2a390b1ffe7d8800ca4a2c8a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7494f81c1eead45e555f4213174c5618b1d1d8449d46685557cd4d4c34a92057dd79e1d07417a0920324cf9f3eb848da7028755b8ca07ae1f86a8e957440fc70
|
7
|
+
data.tar.gz: e8fd26c9a28b9705aa9319a6e5683073abfc7e33135904825dba7c654b475e1c21431525b9618632629f18aefeabe4e3c483d9ac0ee059b924ed8d496ab01f48
|
data/lib/data-struct.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
|
2
|
+
require_relative "doubly_linked_list"
|
3
|
+
require_relative "dynamic_array"
|
4
|
+
require_relative "max_stack"
|
5
|
+
require_relative "min_max_stack"
|
6
|
+
require_relative "min_max_queue"
|
7
|
+
require_relative "singly_linked_list"
|
8
|
+
require_relative "stack_queue"
|
9
|
+
|
10
|
+
module DataStruct
|
11
|
+
class DynamicArray < DynamicArray
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
#doubly linked list
|
2
|
+
class LinkedList
|
3
|
+
attr_reader :begin_sentinel, :last_sentinel
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@begin_sentinel = Link.new(nil)
|
7
|
+
@last_sentinel = Link.new(nil)
|
8
|
+
end
|
9
|
+
|
10
|
+
def pop
|
11
|
+
last_link = @last_sentinel.prev
|
12
|
+
val = last_link.val
|
13
|
+
@last_sentinel.prev = last_link.prev
|
14
|
+
|
15
|
+
val
|
16
|
+
end
|
17
|
+
|
18
|
+
def push(val)
|
19
|
+
link = Link.new(val)
|
20
|
+
last_link = @last_sentinel.prev
|
21
|
+
unless last_link.nil?
|
22
|
+
last_link.next, link.prev = link, @last_sentinel.prev
|
23
|
+
else
|
24
|
+
@begin_sentinel.next = link
|
25
|
+
end
|
26
|
+
@last_sentinel.prev = link
|
27
|
+
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
def unshift(val)
|
32
|
+
link = Link.new(val)
|
33
|
+
first_link = @begin_sentinel.next
|
34
|
+
unless first_link.nil?
|
35
|
+
first_link.prev, link.next = link, first_link
|
36
|
+
else
|
37
|
+
@last_sentinel.prev = link
|
38
|
+
end
|
39
|
+
@begin_sentinel.next = link
|
40
|
+
|
41
|
+
self
|
42
|
+
end
|
43
|
+
|
44
|
+
def shift
|
45
|
+
first_link = @begin_sentinel.next
|
46
|
+
return nil if first_link.nil?
|
47
|
+
@begin_sentinel.next = first_link.next
|
48
|
+
|
49
|
+
first_link.val
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class Link
|
54
|
+
attr_accessor :next, :prev, :val
|
55
|
+
|
56
|
+
def initialize(val)
|
57
|
+
@val = val
|
58
|
+
@next = nil
|
59
|
+
@prev = nil
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
class DynamicArray
|
2
|
+
# dynamic array with ring buffer
|
3
|
+
attr_accessor :store, :size, :start
|
4
|
+
attr_reader :num_items
|
5
|
+
|
6
|
+
def initialize(size)
|
7
|
+
@num_items = 0
|
8
|
+
@size = size
|
9
|
+
@start = 0
|
10
|
+
@store = Array.new(size)
|
11
|
+
end
|
12
|
+
|
13
|
+
def empty?
|
14
|
+
# will refactor to check num_items because I'm not testing that variable right now
|
15
|
+
return @store.empty?
|
16
|
+
end
|
17
|
+
|
18
|
+
def insert(val, idx)
|
19
|
+
# O(n) because you need to copy
|
20
|
+
idx += @start
|
21
|
+
validate_idx(idx)
|
22
|
+
resize! if @num_items == @size
|
23
|
+
|
24
|
+
queue = [val]
|
25
|
+
count = 0 # in case @store is full, then @store[idx] will never be nil,
|
26
|
+
# break you move all the way around
|
27
|
+
|
28
|
+
until queue.empty? || count > @num_items
|
29
|
+
count += 1
|
30
|
+
queue.push(@store[idx]) unless @store[idx].nil?
|
31
|
+
@store[idx] = queue.shift
|
32
|
+
idx += 1
|
33
|
+
end
|
34
|
+
@num_items += 1
|
35
|
+
|
36
|
+
@store
|
37
|
+
end
|
38
|
+
|
39
|
+
def pop
|
40
|
+
# O(1)
|
41
|
+
@num_items -= 1
|
42
|
+
idx = @start + @num_items
|
43
|
+
val, @store[idx] = @store[idx], nil
|
44
|
+
|
45
|
+
val
|
46
|
+
end
|
47
|
+
|
48
|
+
def push(val)
|
49
|
+
# O(1) ammortized; not called on every push
|
50
|
+
resize! if @num_items == @size
|
51
|
+
idx = (@start + @num_items) % @size
|
52
|
+
@num_items += 1
|
53
|
+
@store[idx] = val
|
54
|
+
|
55
|
+
@store
|
56
|
+
end
|
57
|
+
|
58
|
+
# def remove(idx)
|
59
|
+
# p "here"
|
60
|
+
# # O(n) because you need to copy
|
61
|
+
# idx += @start
|
62
|
+
# validate_idx(idx)
|
63
|
+
|
64
|
+
# queue = [@store[idx + 1]]
|
65
|
+
|
66
|
+
# until queue.empty?
|
67
|
+
# @store[idx] = queue.shift
|
68
|
+
# idx += 1
|
69
|
+
# queue.push(@store[idx]) unless @store[idx].nil?
|
70
|
+
# end
|
71
|
+
|
72
|
+
# @store
|
73
|
+
# end
|
74
|
+
|
75
|
+
def shift
|
76
|
+
# O(1)
|
77
|
+
val, @store[@start] = @store[@start], nil
|
78
|
+
@num_items -= 1
|
79
|
+
@start += 1
|
80
|
+
|
81
|
+
val
|
82
|
+
end
|
83
|
+
|
84
|
+
def unshift(val)
|
85
|
+
# O(1) ammortized; not called on every unshift
|
86
|
+
resize! if @num_items == @size
|
87
|
+
@start -= 1
|
88
|
+
idx = (@start) % @size
|
89
|
+
@num_items += 1
|
90
|
+
@store[idx] = val
|
91
|
+
|
92
|
+
@store
|
93
|
+
end
|
94
|
+
|
95
|
+
private
|
96
|
+
|
97
|
+
def resize!
|
98
|
+
# O(n) because it copies the whole array into new store
|
99
|
+
new_size = @size * 2
|
100
|
+
new_store = Array.new(new_size)
|
101
|
+
old_idx = @start
|
102
|
+
new_idx = 0
|
103
|
+
|
104
|
+
@size.times do
|
105
|
+
new_store[new_idx], @store[old_idx] = @store[old_idx], nil
|
106
|
+
new_idx = (new_idx + 1) % @num_items
|
107
|
+
old_idx = (old_idx + 1) % @num_items
|
108
|
+
end
|
109
|
+
|
110
|
+
@start = 0
|
111
|
+
@size = new_size
|
112
|
+
@store = new_store
|
113
|
+
end
|
114
|
+
|
115
|
+
def validate_idx(idx)
|
116
|
+
raise "invalid index, not in range" if idx < @start || idx > (@start + @num_items - 1)
|
117
|
+
end
|
118
|
+
end
|
data/lib/max_stack.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
class MaxStack
|
2
|
+
attr_reader :store
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
@store = []
|
6
|
+
end
|
7
|
+
|
8
|
+
def push(val)
|
9
|
+
if @store.empty?
|
10
|
+
@store << [val, val]
|
11
|
+
else
|
12
|
+
max_val = [val, self.max].max
|
13
|
+
@store << [val, max_val]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def pop
|
18
|
+
@store.pop[0]
|
19
|
+
end
|
20
|
+
|
21
|
+
def max
|
22
|
+
@store[-1][1]
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
class MinMaxStack
|
2
|
+
attr_reader :store
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
@store = []
|
6
|
+
end
|
7
|
+
|
8
|
+
def length
|
9
|
+
@store.length
|
10
|
+
end
|
11
|
+
|
12
|
+
def max
|
13
|
+
@store.empty? ? nil : @store[-1][2]
|
14
|
+
end
|
15
|
+
|
16
|
+
def min
|
17
|
+
@store.empty? ? nil : @store[-1][1]
|
18
|
+
end
|
19
|
+
|
20
|
+
def pop
|
21
|
+
val, _ = @store.pop
|
22
|
+
|
23
|
+
val
|
24
|
+
end
|
25
|
+
|
26
|
+
def push(val)
|
27
|
+
if @store.empty?
|
28
|
+
@store << [val, val, val]
|
29
|
+
else
|
30
|
+
@store << [val, [self.min, val].min, [self.max, val].max]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# singly linked list
|
2
|
+
class SingleLinkedList
|
3
|
+
attr_reader :sentinel
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@sentinel = SingleLink.new(nil)
|
7
|
+
end
|
8
|
+
|
9
|
+
def pop
|
10
|
+
prev, last = walkthrough
|
11
|
+
raise "cannot pop from empty list" if prev.nil?
|
12
|
+
prev.next = nil
|
13
|
+
|
14
|
+
last.val
|
15
|
+
end
|
16
|
+
|
17
|
+
def push(val)
|
18
|
+
link = SingleLink.new(val)
|
19
|
+
_, last_link = walkthrough
|
20
|
+
last_link.next = link
|
21
|
+
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def shift
|
26
|
+
first_link = @sentinel.next
|
27
|
+
raise "cannot shift from empty list" if prev.nil?
|
28
|
+
val = first_link.val
|
29
|
+
@sentinel.next = first_link.next
|
30
|
+
|
31
|
+
val
|
32
|
+
end
|
33
|
+
|
34
|
+
def unshift(val)
|
35
|
+
link = SingleLink.new(val)
|
36
|
+
@sentinel.next, link.next = link, @sentinel.next
|
37
|
+
|
38
|
+
self
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def walkthrough
|
44
|
+
# walksthrough and returns array of second last and last link
|
45
|
+
current = @sentinel
|
46
|
+
until current.next.nil?
|
47
|
+
prev = current
|
48
|
+
current = current.next
|
49
|
+
end
|
50
|
+
|
51
|
+
[prev, current]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class SingleLink
|
56
|
+
attr_accessor :next, :val
|
57
|
+
|
58
|
+
def initialize(val)
|
59
|
+
@val = val
|
60
|
+
@next = nil
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
data/lib/stack_queue.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
class StackQueue
|
2
|
+
|
3
|
+
attr_reader :in, :out
|
4
|
+
def initialize
|
5
|
+
@in, @out = [], []
|
6
|
+
end
|
7
|
+
|
8
|
+
# O(1) ammortized
|
9
|
+
def push(val)
|
10
|
+
@in << val
|
11
|
+
end
|
12
|
+
|
13
|
+
# WC: O(n)
|
14
|
+
def shift
|
15
|
+
if @out.empty?
|
16
|
+
flip!
|
17
|
+
end
|
18
|
+
|
19
|
+
@out.pop
|
20
|
+
end
|
21
|
+
|
22
|
+
# O(n)
|
23
|
+
def flip!
|
24
|
+
@in.length.times do
|
25
|
+
@out << @in.pop
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
metadata
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: data-struct
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.6
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Kevin Wang
|
8
|
+
- Daniel Ng
|
9
|
+
- Conan Tzou
|
10
|
+
- Karen Ling
|
11
|
+
autorequire:
|
12
|
+
bindir: bin
|
13
|
+
cert_chain: []
|
14
|
+
date: 2015-07-16 00:00:00.000000000 Z
|
15
|
+
dependencies: []
|
16
|
+
description: A simple gem that provides several useful implementations of data structures
|
17
|
+
email: kevinwang2400@gmail.com
|
18
|
+
executables: []
|
19
|
+
extensions: []
|
20
|
+
extra_rdoc_files: []
|
21
|
+
files:
|
22
|
+
- lib/data-struct.rb
|
23
|
+
- lib/doubly_linked_list.rb
|
24
|
+
- lib/dynamic_array.rb
|
25
|
+
- lib/max_stack.rb
|
26
|
+
- lib/min_max_stack.rb
|
27
|
+
- lib/singly_linked_list.rb
|
28
|
+
- lib/stack_queue.rb
|
29
|
+
homepage: http://rubygems.org/gems/data-struct
|
30
|
+
licenses:
|
31
|
+
- MIT
|
32
|
+
metadata: {}
|
33
|
+
post_install_message:
|
34
|
+
rdoc_options: []
|
35
|
+
require_paths:
|
36
|
+
- lib
|
37
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
requirements: []
|
48
|
+
rubyforge_project:
|
49
|
+
rubygems_version: 2.4.3
|
50
|
+
signing_key:
|
51
|
+
specification_version: 4
|
52
|
+
summary: Data structures, some up and running, not fully tested
|
53
|
+
test_files: []
|