File tree Expand file tree Collapse file tree 2 files changed +113
-0
lines changed
week4/priority-queues/task2 Expand file tree Collapse file tree 2 files changed +113
-0
lines changed Original file line number Diff line number Diff line change 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.
Original file line number Diff line number Diff line change 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?
You can’t perform that action at this time.
0 commit comments