@@ -5,20 +5,13 @@ def initialize(values = [])
55 @arr = values . dup
66
77 ( arr . size / 2 - 1 ) . downto ( 0 ) . each do |i |
8- heapify! ( i )
8+ heapify_down ( i )
99 end
1010 end
1111
1212 def push ( value )
13- i = arr . size
1413 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
14+ heapify_up ( arr . size - 1 )
2215 end
2316
2417 def max
@@ -30,7 +23,7 @@ def pop
3023 last = arr . pop
3124 unless arr . empty?
3225 arr [ 0 ] = last
33- heapify! ( 0 )
26+ heapify_down ( 0 )
3427 end
3528 value
3629 end
@@ -45,63 +38,88 @@ def sample
4538
4639 # logarithmic time
4740 def delRandom
48- i = rand ( arr . size )
49- x = arr [ i ]
41+ index = rand ( arr . size )
42+ x = arr [ index ]
5043
51- swap ( i , arr . size - 1 )
44+ swap ( index , arr . size - 1 )
5245 arr . pop
5346
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 )
47+ unless index == arr . size
48+ if index == 0 || arr [ index ] <= arr [ parent_index ( index ) ]
49+ heapify_down ( index )
50+ else
51+ heapify_up ( index )
52+ end
6253 end
6354
6455 x
6556 end
6657
6758 def valid_heap?
6859 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 ]
60+ ( 0 ..( arr . size / 2 - 1 ) ) . each do |parent_i |
61+ left_i = left_index ( parent_i )
62+ right_i = right_index ( parent_i )
63+ return false if left_i < arr . size && arr [ left_i ] > arr [ parent_i ]
64+ return false if right_i < arr . size && arr [ right_i ] > arr [ parent_i ]
7465 end
7566 true
7667 end
7768
78- private def heapify! ( i )
79- loop do
80- left_child = 2 * i + 1
81- right_child = 2 * i + 2
82- largest_child = i
69+ private def heapify_up ( index )
70+ parent_i = parent_index ( index )
8371
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 ]
72+ return if index == 0 || @arr [ index ] <= @arr [ parent_i ]
8673
87- break if largest_child == i
74+ swap ( index , parent_i )
75+ heapify_up ( parent_i )
76+ end
8877
89- swap ( i , largest_child )
90- i = largest_child
91- end
78+ private def heapify_down ( index )
79+ left_i = left_index ( index )
80+ right_i = right_index ( index )
81+ largest_child = index
82+
83+ largest_child = left_i if left_i < arr . size && arr [ left_i ] > arr [ largest_child ]
84+ largest_child = right_i if right_i < arr . size && arr [ right_i ] > arr [ largest_child ]
85+
86+ return if largest_child == index
87+
88+ swap ( index , largest_child )
89+ heapify_down ( largest_child )
90+ end
91+
92+ private def parent_index ( index )
93+ ( index - 1 ) / 2
94+ end
95+
96+ def left_index ( index )
97+ 2 * index + 1
98+ end
99+
100+ def right_index ( index )
101+ 2 * index + 2
92102 end
93103
94104 private def swap ( i , j )
105+ return if i == j
95106 arr [ i ] , arr [ j ] = arr [ j ] , arr [ i ]
96107 end
97108end
98109
99- n = rand ( 3 ..9 )
100- a = Array . new ( n ) { rand ( 1 ..99 ) } . uniq
110+ 100 . times do
111+ n = rand ( 3 ..9 )
112+ a = Array . new ( n ) { rand ( 1 ..99 ) } . uniq
113+
114+ h1 = Heap . new ( a )
115+ x = h1 . delRandom
116+ b = a - [ x ]
117+ h2 = Heap . new ( b )
101118
102- h1 = Heap . new ( a )
103- x = h1 . delRandom
104- b = a - [ x ]
105- h2 = Heap . new ( b )
119+ unless h1 . arr . sort == h2 . arr . sort && h1 . valid_heap? && h2 . valid_heap?
120+ puts "ERROR: h1 = #{ h1 . arr } , h2 = #{ h2 . arr } | #{ h1 . valid_heap? } #{ h2 . valid_heap? } "
121+ exit
122+ end
123+ end
106124
107- p h1 . arr . sort == h2 . arr . sort && h1 . valid_heap? && h2 . valid_heap?
125+ puts "OK"
0 commit comments