data_structures_101 0.1.0 → 0.2.1
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/.travis.yml +10 -2
- data/_config.yml +1 -0
- data/lib/data_structures_101.rb +4 -0
- data/lib/data_structures_101/chained_hash_table.rb +40 -0
- data/lib/data_structures_101/hash/base_hash_table.rb +62 -0
- data/lib/data_structures_101/hash/bucket.rb +52 -0
- data/lib/data_structures_101/linked_list.rb +9 -25
- data/lib/data_structures_101/probe_hash_table.rb +79 -0
- data/lib/data_structures_101/version.rb +1 -1
- metadata +8 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f215d1362121ff577224993028a8870cd3fd1b82
|
4
|
+
data.tar.gz: 9785b4159ec72926f1fb81c5baeda8281d2840cb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 005a8f910dad00e6db443761b725eac89b384e1f6f79a0deb94d526c511d791b1b110d111159c80d202d142f3b0d2cb11aac984e925e468e25158fd3416f89e3
|
7
|
+
data.tar.gz: f477fe15da1f404dc753690b7d0ae27861f9785d81bcf6725ce2d8f862a8ad491075871e2883ac122d0a6f29edbe35ce35477975c1657afe39995b4df952b5b2
|
data/.travis.yml
CHANGED
@@ -1,6 +1,14 @@
|
|
1
1
|
sudo: false
|
2
2
|
language: ruby
|
3
3
|
rvm:
|
4
|
-
|
5
|
-
before_install: gem install bundler -v 1.14.6
|
4
|
+
- 2.4.0
|
6
5
|
script: bundle exec rspec
|
6
|
+
deploy:
|
7
|
+
provider: rubygems
|
8
|
+
api_key:
|
9
|
+
secure: YDkCNjnzyBTEcZLjKqt6ep1rIHYGF6tbqwNVUXEOFiBpQA534xl8AcsNIcb4MZGcNzn9ZeJiHstIeHKKP135sLKnA00RptoVtNAHn9F5hBgDyPc5GyIEzml4wDv7NM+jcM4df39CEBIyYi+77vRUvUfrOJ+0RF7CxvlGX4ZUvbI+5edFXjt9ioVPOhG+V6FyTbGlNEG2Rj4lx6jjUF3HYVVhwHCva3F4uXNh/3CjZXvcJ6ZahKCiO0/pqxZsS6L/xfDaih/jg/8B3nQ2L7Lx+g5A8uNLCZ4u2G4SPoCg0a+mrttJAkIgTNC8reVBAbS9V7BV6/OJcJwwhJKNQ+UsleTv0oDdOWsSFgL8I2qtUJb7r1cpmFHi/LC5fnfpfC6xcoRk7sxrFboYsbm8yGt2KEk68Jregl9j0EqrHynog/9zFKx9Sfcrw2Fo+6oMACDYm3NzlcAo+6bQHni/kV94oaD58nZ3OQgvBMh4jeZ854jjCbpJaCMs2u2CgezjlTZCY7+E38t+/tiFlAOakVBSC9oGEYCFxh5X/clKXi7Q2PZj8j/pmcc51wmVFEMB5Led7kj1R1YWCnalhIZO4hpz83yBGCYZQgm2AZy0r8k741L9ab0H/KhMSJHGN2ym2Dgdpg1a0QdlMGVidIQGNjeSEx7TPkkDStuM588qKcR8C6M=
|
10
|
+
gem: data_structures_101
|
11
|
+
on:
|
12
|
+
tags: true
|
13
|
+
repo: renehernandez/data_structures_101
|
14
|
+
branch: master
|
data/_config.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
theme: jekyll-theme-slate
|
data/lib/data_structures_101.rb
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
require "data_structures_101/version"
|
2
2
|
require "data_structures_101/linked_list"
|
3
|
+
require "data_structures_101/hash/base_hash_table"
|
4
|
+
require "data_structures_101/hash/bucket"
|
5
|
+
require "data_structures_101/chained_hash_table"
|
6
|
+
require "data_structures_101/probe_hash_table"
|
3
7
|
|
4
8
|
module DataStructures101
|
5
9
|
# Your code goes here...
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module DataStructures101
|
2
|
+
|
3
|
+
class ChainedHashTable < Hash::BaseHashTable
|
4
|
+
|
5
|
+
def initialize(capacity = 31, prime = 109345121, hash_lambda = nil)
|
6
|
+
super
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def bucket_find(hash_code, key)
|
12
|
+
bucket = @table[hash_code]
|
13
|
+
return nil if bucket.nil?
|
14
|
+
|
15
|
+
bucket.find(key)
|
16
|
+
end
|
17
|
+
|
18
|
+
def bucket_insert(hash_code, key, value)
|
19
|
+
bucket = @table[hash_code]
|
20
|
+
bucket = @table[hash_code] = Hash::Bucket.new if bucket.nil?
|
21
|
+
|
22
|
+
old_size = bucket.size()
|
23
|
+
old_value = bucket.insert(key, value)
|
24
|
+
@size += (bucket.size - old_size)
|
25
|
+
|
26
|
+
old_value
|
27
|
+
end
|
28
|
+
|
29
|
+
def bucket_delete(hash_code, key)
|
30
|
+
bucket = @table[hash_code]
|
31
|
+
return nil if bucket.nil?
|
32
|
+
|
33
|
+
old_size = bucket.size
|
34
|
+
value = bucket.delete(key)
|
35
|
+
@size -= (old_size - bucket.size)
|
36
|
+
|
37
|
+
value
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module DataStructures101
|
2
|
+
module Hash
|
3
|
+
class BaseHashTable
|
4
|
+
|
5
|
+
attr_reader :size, :hash_lambda
|
6
|
+
|
7
|
+
def initialize(capacity, prime, hash_lambda = nil)
|
8
|
+
@capacity = capacity
|
9
|
+
@size = 0
|
10
|
+
@table = Array.new(@capacity)
|
11
|
+
|
12
|
+
random = Random.new
|
13
|
+
scale = random.rand(prime - 1) + 1
|
14
|
+
shift = random.rand(prime)
|
15
|
+
|
16
|
+
@hash_lambda = if hash_lambda.nil?
|
17
|
+
->(key) { return (((key.hash * scale + shift) % prime) % @capacity).abs }
|
18
|
+
else
|
19
|
+
hash_lambda
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def []=(key, value)
|
24
|
+
insert(key, value)
|
25
|
+
end
|
26
|
+
|
27
|
+
def insert(key, value)
|
28
|
+
old_value = bucket_insert(hash_lambda.call(key), key, value)
|
29
|
+
|
30
|
+
# keep load factor <= 0.5
|
31
|
+
resize(new_capacity) if @size > @capacity / 2
|
32
|
+
|
33
|
+
old_value
|
34
|
+
end
|
35
|
+
|
36
|
+
def [](key)
|
37
|
+
bucket_find(hash_lambda.call(key), key)
|
38
|
+
end
|
39
|
+
|
40
|
+
def delete(key)
|
41
|
+
bucket_delete(hash_lambda.call(key), key)
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def new_capacity()
|
47
|
+
2 * capacity - 1
|
48
|
+
end
|
49
|
+
|
50
|
+
def resize(new_capacity)
|
51
|
+
@capacity = new_capacity
|
52
|
+
|
53
|
+
buffer = self.map { |key, value| [key, value] }
|
54
|
+
|
55
|
+
create_table
|
56
|
+
@size = 0
|
57
|
+
|
58
|
+
buffer.each { |key, value| self[key] = value }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module DataStructures101
|
2
|
+
module Hash
|
3
|
+
class Bucket
|
4
|
+
|
5
|
+
attr_reader :table
|
6
|
+
|
7
|
+
def initialize()
|
8
|
+
@table = []
|
9
|
+
end
|
10
|
+
|
11
|
+
def [](key)
|
12
|
+
find(key)
|
13
|
+
end
|
14
|
+
|
15
|
+
def []=(key, value)
|
16
|
+
insert(key, value)
|
17
|
+
end
|
18
|
+
|
19
|
+
def insert(key, value)
|
20
|
+
idx = @table.find_index {|_key, _| _key == key}
|
21
|
+
|
22
|
+
if idx.nil?
|
23
|
+
@table << [key, value]
|
24
|
+
return nil
|
25
|
+
else
|
26
|
+
value, @table[idx][1] = @table[idx][1], value
|
27
|
+
return value
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def size()
|
32
|
+
@table.size
|
33
|
+
end
|
34
|
+
|
35
|
+
def find(key)
|
36
|
+
pair = @table.find {|_key, _| _key == key}
|
37
|
+
pair.nil? ? nil : pair.last
|
38
|
+
end
|
39
|
+
|
40
|
+
def delete(key)
|
41
|
+
idx = @table.find_index {|_key, _| _key == key}
|
42
|
+
return nil if idx.nil?
|
43
|
+
|
44
|
+
value = @table[idx].last
|
45
|
+
@table[idx] = @table.last if idx != @table.size - 1
|
46
|
+
@table.pop
|
47
|
+
value
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -69,36 +69,20 @@ module DataStructures101
|
|
69
69
|
self
|
70
70
|
end
|
71
71
|
|
72
|
-
def first(
|
73
|
-
|
74
|
-
return @head.next.value
|
75
|
-
end
|
72
|
+
def first(n = nil)
|
73
|
+
return @head.next.value if n.nil?
|
76
74
|
|
77
|
-
|
78
|
-
raise ArgumentError, "wrong number of arguments (given #{args.size}, expected 1)"
|
79
|
-
end
|
75
|
+
raise ArgumentError, "negative array size" if n < 0
|
80
76
|
|
81
|
-
|
82
|
-
raise ArgumentError, "negative array size"
|
83
|
-
end
|
84
|
-
|
85
|
-
return new_list_from_range(0, args.first - 1)
|
77
|
+
return new_list_from_range(0, n - 1)
|
86
78
|
end
|
87
79
|
|
88
|
-
def last(
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
if args.size > 1
|
94
|
-
raise ArgumentError, "wrong number of arguments (given #{args.size}, expected 1)"
|
95
|
-
end
|
96
|
-
|
97
|
-
if args.first < 0
|
98
|
-
raise ArgumentError, "negative array size"
|
99
|
-
end
|
80
|
+
def last(n = nil)
|
81
|
+
return @tail.prev.value if n.nil?
|
82
|
+
|
83
|
+
raise ArgumentError, "negative array size" if n < 0
|
100
84
|
|
101
|
-
return new_list_from_range(size -
|
85
|
+
return new_list_from_range(size - n, size - 1)
|
102
86
|
end
|
103
87
|
|
104
88
|
def push(*values)
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
|
3
|
+
module DataStructures101
|
4
|
+
class ProbeHashTable < Hash::BaseHashTable
|
5
|
+
|
6
|
+
attr_reader :probe_lambda
|
7
|
+
|
8
|
+
def initialize(capacity = 31, prime = 109345121,
|
9
|
+
hash_lambda = nil, probe_lambda = nil)
|
10
|
+
super(capacity, prime, hash_lambda)
|
11
|
+
|
12
|
+
@probe_lambda = if probe_lambda.nil?
|
13
|
+
->(h, i) { return (h + i) % @capacity }
|
14
|
+
else
|
15
|
+
probe_lambda
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
Sentinel = Class.new do
|
22
|
+
include Singleton
|
23
|
+
end
|
24
|
+
|
25
|
+
def bucket_find(hash_code, key)
|
26
|
+
idx = find_slot(hash_code, key)
|
27
|
+
|
28
|
+
slot_available?(idx) ? nil : @table[idx].last
|
29
|
+
end
|
30
|
+
|
31
|
+
def bucket_insert(hash_code, key, value)
|
32
|
+
idx = find_slot(hash_code, key)
|
33
|
+
|
34
|
+
if !slot_available?(idx)
|
35
|
+
old_value = @table[idx].last
|
36
|
+
@table[idx] = [key, value]
|
37
|
+
return old_value
|
38
|
+
end
|
39
|
+
|
40
|
+
@table[idx] = [key, value]
|
41
|
+
@size += 1
|
42
|
+
|
43
|
+
nil
|
44
|
+
end
|
45
|
+
|
46
|
+
def bucket_delete(hash_code, key)
|
47
|
+
idx = find_slot(hash_code, key)
|
48
|
+
return nil if slot_available?(idx)
|
49
|
+
|
50
|
+
value = @table[idx].last
|
51
|
+
@table[idx] = Sentinel.instance
|
52
|
+
@size -= 1
|
53
|
+
|
54
|
+
value
|
55
|
+
end
|
56
|
+
|
57
|
+
def find_slot(h, key)
|
58
|
+
idx = -1
|
59
|
+
|
60
|
+
j = 0
|
61
|
+
loop do
|
62
|
+
i = @probe_lambda.call(h, j)
|
63
|
+
if slot_available?(i)
|
64
|
+
idx = i if idx == -1
|
65
|
+
break if @table[i].nil?
|
66
|
+
elsif @table[i].first == key
|
67
|
+
return i
|
68
|
+
end
|
69
|
+
j += 1
|
70
|
+
end
|
71
|
+
|
72
|
+
idx
|
73
|
+
end
|
74
|
+
|
75
|
+
def slot_available?(i)
|
76
|
+
@table[i].nil? || @table[i] == Sentinel.instance
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: data_structures_101
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- aegis
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-08-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -66,11 +66,16 @@ files:
|
|
66
66
|
- LICENSE.txt
|
67
67
|
- README.md
|
68
68
|
- Rakefile
|
69
|
+
- _config.yml
|
69
70
|
- bin/console
|
70
71
|
- bin/setup
|
71
72
|
- data_structures_101.gemspec
|
72
73
|
- lib/data_structures_101.rb
|
74
|
+
- lib/data_structures_101/chained_hash_table.rb
|
75
|
+
- lib/data_structures_101/hash/base_hash_table.rb
|
76
|
+
- lib/data_structures_101/hash/bucket.rb
|
73
77
|
- lib/data_structures_101/linked_list.rb
|
78
|
+
- lib/data_structures_101/probe_hash_table.rb
|
74
79
|
- lib/data_structures_101/version.rb
|
75
80
|
homepage: https://github.com/renehernandez/bok-data_structures_101
|
76
81
|
licenses:
|
@@ -92,7 +97,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
92
97
|
version: '0'
|
93
98
|
requirements: []
|
94
99
|
rubyforge_project:
|
95
|
-
rubygems_version: 2.6.
|
100
|
+
rubygems_version: 2.6.11
|
96
101
|
signing_key:
|
97
102
|
specification_version: 4
|
98
103
|
summary: DataStructures101 is a simple gem that groups several implementations of
|