data-struct 0.0.9 → 0.0.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e5e32796574806001e31a7808fffbd22a9e6be13
4
- data.tar.gz: 6ec9af9dcbfaac5fee5dd717c3d4bc401d1cf5b1
3
+ metadata.gz: 9afef8d83b99609e9b5b7198f2c74d6f8f60df31
4
+ data.tar.gz: 7e8812d7bf78a9678feb71371149ba352f197f35
5
5
  SHA512:
6
- metadata.gz: b33ec6a761467cb0d51b06cc68fc7ec39446b7d2bf70db09e0a75967c120823dee2931d209285a474cdf287111bf762b1fb8e76abe62607c36a96f11bf55e445
7
- data.tar.gz: a2334b34c6d5c5efb35eba7750932c38f6b1a3da3aa5ae43f21ccc2f3895376bc7f41b0965511bed415dc9a2b93974df0ece3b440ee68acfb2795a8c9d6984c2
6
+ metadata.gz: dd8f19a9af0523dfe9176108d549882aedf4610cde4bcaeadf730254392a2bbabae73c4da7c123a8f5f041fb723d02aaef87935c79ec0121c36d833ac9328e7e
7
+ data.tar.gz: 7100ff534e0f5dd748c03ed0d8a865c6fc15754f5b0e5141a24a3aea47875c93adc3abd0e3ef09d6202c39744d280d35faac1db874126e258a0d67efd68cb7db
data/lib/bin_heap.rb ADDED
@@ -0,0 +1,93 @@
1
+ class BinHeap
2
+ attr_reader :store
3
+
4
+ def initialize(&prc)
5
+ @store = Array.new
6
+ @prc = prc || Proc.new { |el1, el2| el1 <=> el2 }
7
+ end
8
+
9
+ def insert(value)
10
+ @store << value
11
+ self.class.heapify_up(@store, @store.length - 1, &@prc)
12
+ end
13
+
14
+ def extract
15
+ raise "Heap is empty" if @store.empty?
16
+
17
+ top_priority = @store[0]
18
+
19
+ if @store.length > 1
20
+ @store[0] = @store.pop
21
+ self.class.heapify_down(@store, 0, &@prc)
22
+ else
23
+ @store.pop
24
+ end
25
+
26
+ top_priority
27
+ end
28
+
29
+ protected
30
+ attr_writer :prc, :store
31
+
32
+ public
33
+ def self.heapify_up(store, child_idx, &prc)
34
+ prc = prc || Proc.new { |el1, el2| el1 <=> el2 }
35
+ return store if child_idx == 0
36
+
37
+ parent_idx = find_parent(child_idx)
38
+
39
+ if prc.call(store[child_idx], store[parent_idx]) == -1
40
+ store[child_idx], store[parent_idx] = store[parent_idx], store[child_idx]
41
+ heapify_up(store, parent_idx, &prc)
42
+ else
43
+ return store
44
+ end
45
+ end
46
+
47
+ def self.heapify_down(store, parent_idx, &prc)
48
+ prc = prc || Proc.new { |el1, el2| el1 <=> el2 }
49
+
50
+ children_idx = find_children(store.length - 1, parent_idx)
51
+
52
+ c0_idx = children_idx[0]
53
+ c1_idx = children_idx[1]
54
+
55
+ children = []
56
+ children << store[c0_idx] if c0_idx
57
+ children << store[c1_idx] if c1_idx
58
+
59
+ parent = store[parent_idx]
60
+
61
+ #When the parent index is where it's supposed to be
62
+ if children.all? { |child| prc.call(child, parent) >= 0}
63
+ return store
64
+ end
65
+
66
+ if store.length == 1
67
+ swap_idx = c0_idx
68
+ else
69
+ swap_idx = prc.call(children[0], children[1]) == 1 ? c1_idx : c0_idx
70
+ end
71
+
72
+ store[swap_idx], store[parent_idx] = parent, store[swap_idx]
73
+
74
+ heapify_down(store, swap_idx, &prc)
75
+ end
76
+
77
+ def self.find_children(last_idx, parent_idx)
78
+ child1 = (parent_idx * 2) + 1
79
+ child2 = (parent_idx * 2) + 2
80
+
81
+
82
+ return [child1, child2].select{ |idx| idx <= last_idx }
83
+ end
84
+
85
+ def self.find_parent(child_idx)
86
+ if child_idx == 0
87
+ raise "Out of bounds"
88
+ else
89
+ return (child_idx - 1) / 2
90
+ end
91
+ end
92
+ end
93
+
@@ -0,0 +1,174 @@
1
+ class BinarySearchTree
2
+ attr_accessor :value, :parent, :left, :right, :depth, :balance
3
+
4
+ def initialize(value)
5
+ @value = value
6
+ @parent = EmptyNode.new
7
+ @left = EmptyNode.new
8
+ @right = EmptyNode.new
9
+ @depth = 0
10
+ @balance = 0
11
+ end
12
+
13
+ def self.from_array(array)
14
+ BinarySearchTree.new(array.first).tap do |tree|
15
+ array.each { |val| tree.insert(val) }
16
+ end
17
+ end
18
+
19
+ def children
20
+ count = 0
21
+ count += 1 if left.class == BinarySearchTree
22
+ count += 1 if right.class == BinarySearchTree
23
+
24
+ count
25
+ end
26
+
27
+ def left_rotate
28
+ # A B
29
+ # / \ / \
30
+ # D B <=> A' C
31
+ # / \ / \
32
+ # E C D E
33
+ #
34
+
35
+ # KW: still need to refactor this, unnecessary creation of new node
36
+ # reassign parent
37
+ new_left = BinarySearchTree.new(value) # A'
38
+
39
+ new_left.left = left # A' -> D
40
+ left.parent = new_left # D <- A'
41
+ new_left.right = right.left # A' -> E
42
+ right.left.parent = new_left # E <- A'
43
+ new_left.parent = self # A' <- A
44
+
45
+ new_right = right.right # C
46
+ new_right.parent = self # C <- A
47
+
48
+ @value, @left, @right = right.value, new_left, new_right
49
+ end
50
+
51
+ def right_rotate
52
+ new_right = BinarySearchTree.new(value)
53
+
54
+ new_right.right = right
55
+ right.parent = new_right
56
+ new_right.left = left.right
57
+ left.right.parent = new_right
58
+ new_right.parent = self
59
+
60
+ new_left = left.left
61
+ new_left.parent = self
62
+
63
+ @value, @left, @right = left.value, new_left, new_right
64
+ end
65
+
66
+ def insert(val)
67
+ case val <=> value
68
+ when -1 then insert_left(val)
69
+ when 1 then insert_right(val)
70
+ when 0 then false
71
+ end
72
+
73
+ self
74
+ end
75
+
76
+ def inspect
77
+ " { #{value} : #{left.inspect} | #{right.inspect} } "
78
+ end
79
+
80
+ def include?(val)
81
+ case val <=> value
82
+ when -1 then left.include?(val)
83
+ when 1 then right.include?(val)
84
+ when 0 then true
85
+ end
86
+ end
87
+
88
+ def to_a
89
+ left.to_a + [value] + right.to_a
90
+ end
91
+
92
+ def recalculate_depth_and_balance
93
+ @depth = ([left.depth, right.depth].max + 1)
94
+ @balance = right.depth - left.depth
95
+ # p "RECALULATED DEPTH = #{depth}: BALANCE = #{balance}"
96
+ end
97
+
98
+ def update_depth_and_balance
99
+ # recursively update depth and balance, rebalances if needed and crawls up the tree
100
+ recalculate_depth_and_balance
101
+ rebalance if ([-2, 2].include?(@balance))
102
+ # p "RECALULATED #{self.inspect} DEPTH = #{depth}: BALANCE = #{balance}"
103
+ parent.update_depth_and_balance
104
+ end
105
+
106
+ private
107
+
108
+ def insert_left(val)
109
+ if (left.class != EmptyNode)
110
+ left.insert(val)
111
+ else
112
+ new_node = BinarySearchTree.new(val)
113
+ self.left, new_node.parent = new_node, self
114
+ new_node.update_depth_and_balance
115
+ end
116
+ end
117
+
118
+ def insert_right(val)
119
+ if (right.class != EmptyNode)
120
+ right.insert(val)
121
+ else
122
+ new_node = BinarySearchTree.new(val)
123
+ self.right, new_node.parent = new_node, self
124
+ new_node.update_depth_and_balance
125
+ end
126
+ end
127
+
128
+ def rebalance
129
+ if @balance == -2
130
+ left.left_rotate if left.balance == 1
131
+ right_rotate
132
+ elsif @balance == 2
133
+ right.right_rotate if right.balance == -1
134
+ left_rotate
135
+ end
136
+ right.recalculate_depth_and_balance
137
+ left.recalculate_depth_and_balance
138
+ recalculate_depth_and_balance
139
+ end
140
+ end
141
+
142
+ class EmptyNode
143
+ attr_reader :depth
144
+ attr_accessor :parent
145
+
146
+ def initialize
147
+ @depth = 0
148
+ @parent = nil
149
+ end
150
+
151
+ def include?(*)
152
+ false
153
+ end
154
+
155
+ def insert(*)
156
+ false
157
+ end
158
+
159
+ def inspect
160
+ "{}"
161
+ end
162
+
163
+ def recalculate_depth_and_balance
164
+ true
165
+ end
166
+
167
+ def to_a
168
+ []
169
+ end
170
+
171
+ def update_depth_and_balance
172
+ true
173
+ end
174
+ end
data/lib/data-struct.rb CHANGED
@@ -1,22 +1,17 @@
1
-
2
- # require_relative "doubly_linked_list"
1
+ require_relative "binary_search_tree"
3
2
  require_relative "dynamic_array"
3
+ # require_relative "doubly_linked_list"
4
4
  require_relative "max_stack"
5
5
  require_relative "min_max_stack"
6
6
  # require_relative "min_max_queue"
7
- require_relative "single_linked_list"
7
+
8
+ require_relative "singly_linked_list"
8
9
  # require_relative "stack_queue"
9
10
 
10
11
  module DataStruct
11
- class DynamicArray < DynamicArray
12
- end
13
-
14
- class MaxStack < MaxStack
15
- end
16
-
17
- class MinMaxStack < MinMaxStack
18
- end
19
-
20
- class SingleLinkedList < SingleLinkedList
21
- end
22
- end
12
+ class BinarySearchTree < BinarySearchTree; end
13
+ class DynamicArray < DynamicArray; end
14
+ class MaxStack < MaxStack; end
15
+ class MinMaxStack < MinMaxStack; end
16
+ class SinglyLinkedList < SinglyLinkedList; end
17
+ end
@@ -1,9 +1,9 @@
1
1
  # singly linked list
2
- class SingleLinkedList
2
+ class SinglyLinkedList
3
3
  attr_reader :sentinel
4
4
 
5
5
  def initialize
6
- @sentinel = SingleLink.new(nil)
6
+ @sentinel = SinglyLink.new(nil)
7
7
  end
8
8
 
9
9
  def pop
@@ -15,7 +15,7 @@ class SingleLinkedList
15
15
  end
16
16
 
17
17
  def push(val)
18
- link = SingleLink.new(val)
18
+ link = SinglyLink.new(val)
19
19
  _, last_link = walkthrough
20
20
  last_link.next = link
21
21
 
@@ -32,7 +32,7 @@ class SingleLinkedList
32
32
  end
33
33
 
34
34
  def unshift(val)
35
- link = SingleLink.new(val)
35
+ link = SinglyLink.new(val)
36
36
  @sentinel.next, link.next = link, @sentinel.next
37
37
 
38
38
  self
@@ -52,7 +52,7 @@ class SingleLinkedList
52
52
  end
53
53
  end
54
54
 
55
- class SingleLink
55
+ class SinglyLink
56
56
  attr_accessor :next, :val
57
57
 
58
58
  def initialize(val)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: data-struct
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.0.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin Wang
@@ -13,18 +13,21 @@ bindir: bin
13
13
  cert_chain: []
14
14
  date: 2015-07-16 00:00:00.000000000 Z
15
15
  dependencies: []
16
- description: A simple gem that provides several useful implementations of data structures
16
+ description: A simple gem that provides several useful implementations of data structures.
17
+ Contribute at github.com/kswang2400/data-struct
17
18
  email: kevinwang2400@gmail.com
18
19
  executables: []
19
20
  extensions: []
20
21
  extra_rdoc_files: []
21
22
  files:
23
+ - lib/bin_heap.rb
24
+ - lib/binary_search_tree.rb
22
25
  - lib/data-struct.rb
23
26
  - lib/doubly_linked_list.rb
24
27
  - lib/dynamic_array.rb
25
28
  - lib/max_stack.rb
26
29
  - lib/min_max_stack.rb
27
- - lib/single_linked_list.rb
30
+ - lib/singly_linked_list.rb
28
31
  - lib/stack_queue.rb
29
32
  homepage: http://rubygems.org/gems/data-struct
30
33
  licenses: