Skip to content

Commit a3c64e1

Browse files
committed
week4 - task2 - baseline
1 parent 05cb2f0 commit a3c64e1

File tree

2 files changed

+113
-0
lines changed

2 files changed

+113
-0
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
### Randomized priority queue
2+
3+
Describe how to add the methods `sample()` and `delRandom()` to our binary heap implementation.
4+
The two methods return a key that is chosen uniformly at random among the remaining keys, with the latter method also removing that key.
5+
The `sample()` method should take constant time; the `delRandom()` method should take logarithmic time.
6+
Do not worry about resizing the underlying array.
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
class Heap
2+
attr_reader :arr
3+
4+
def initialize(values = [])
5+
@arr = values.dup
6+
7+
(arr.size / 2 - 1).downto(0).each do |i|
8+
heapify!(i)
9+
end
10+
end
11+
12+
def push(value)
13+
i = arr.size
14+
arr << value
15+
parent_i = (i - 1) / 2
16+
17+
while i > 0 && arr[parent_i] < arr[i]
18+
swap(i, parent_i)
19+
i = parent_i
20+
parent_i = (i - 1) / 2
21+
end
22+
end
23+
24+
def max
25+
arr.first
26+
end
27+
28+
def pop
29+
value = arr[0]
30+
last = arr.pop
31+
unless arr.empty?
32+
arr[0] = last
33+
heapify!(0)
34+
end
35+
value
36+
end
37+
38+
def length
39+
arr.size
40+
end
41+
42+
def sample
43+
arr.sample
44+
end
45+
46+
# logarithmic time
47+
def delRandom
48+
i = rand(arr.size)
49+
x = arr[i]
50+
51+
swap(i, arr.size - 1)
52+
arr.pop
53+
54+
(0...arr.size).each do |k|
55+
heapify!(k)
56+
end
57+
(0...arr.size).each do |k|
58+
heapify!(k)
59+
end
60+
(0...arr.size).each do |k|
61+
heapify!(k)
62+
end
63+
64+
x
65+
end
66+
67+
def valid_heap?
68+
return true if arr.empty?
69+
(0..(arr.size / 2 - 1)).each do |parent_idx|
70+
left_child_idx = 2 * parent_idx + 1
71+
right_child_idx = 2 * parent_idx + 2
72+
return false if left_child_idx < arr.size && arr[left_child_idx] > arr[parent_idx]
73+
return false if right_child_idx < arr.size && arr[right_child_idx] > arr[parent_idx]
74+
end
75+
true
76+
end
77+
78+
private def heapify!(i)
79+
loop do
80+
left_child = 2 * i + 1
81+
right_child = 2 * i + 2
82+
largest_child = i
83+
84+
largest_child = left_child if left_child < arr.size && arr[left_child] > arr[largest_child]
85+
largest_child = right_child if right_child < arr.size && arr[right_child] > arr[largest_child]
86+
87+
break if largest_child == i
88+
89+
swap(i, largest_child)
90+
i = largest_child
91+
end
92+
end
93+
94+
private def swap(i, j)
95+
arr[i], arr[j] = arr[j], arr[i]
96+
end
97+
end
98+
99+
n = rand(3..9)
100+
a = Array.new(n) { rand(1..99) }.uniq
101+
102+
h1 = Heap.new(a)
103+
x = h1.delRandom
104+
b = a - [x]
105+
h2 = Heap.new(b)
106+
107+
p h1.arr.sort == h2.arr.sort && h1.valid_heap? && h2.valid_heap?

0 commit comments

Comments
 (0)