@@ -17,7 +17,7 @@ class Crystal::PointerPairingHeap(T)
17
17
abstract def heap_compare (other : Pointer (self )) : Bool
18
18
end
19
19
20
- @head : T * | Nil
20
+ @head : Pointer ( T )?
21
21
22
22
private def head= (head )
23
23
@head = head
@@ -29,44 +29,26 @@ class Crystal::PointerPairingHeap(T)
29
29
@head .nil?
30
30
end
31
31
32
- def first ? : T * | Nil
32
+ def first ? : Pointer ( T )?
33
33
@head
34
34
end
35
35
36
- def shift ? : T * | Nil
36
+ def shift ? : Pointer ( T )?
37
37
if node = @head
38
38
self .head = merge_pairs(node.value.heap_child?)
39
39
node.value.heap_child = nil
40
40
node
41
41
end
42
42
end
43
43
44
- def add (node : T * ) : Bool
44
+ def add (node : Pointer ( T )) : Nil
45
45
if node.value.heap_previous? || node.value.heap_next? || node.value.heap_child?
46
46
raise ArgumentError .new(" The node is already in a Pairing Heap tree" )
47
47
end
48
48
self .head = meld(@head , node)
49
- node == @head
50
49
end
51
50
52
- def delete (node : T * ) : {Bool , Bool }
53
- if node == @head
54
- self .head = merge_pairs(node.value.heap_child?)
55
- node.value.heap_child = nil
56
- return {true , true }
57
- end
58
-
59
- if remove?(node)
60
- subtree = merge_pairs(node.value.heap_child?)
61
- self .head = meld(@head , subtree)
62
- unlink(node)
63
- return {true , false }
64
- end
65
-
66
- {false , false }
67
- end
68
-
69
- private def remove? (node )
51
+ def delete (node : Pointer (T )) : Nil
70
52
if previous_node = node.value.heap_previous?
71
53
next_sibling = node.value.heap_next?
72
54
@@ -80,9 +62,13 @@ class Crystal::PointerPairingHeap(T)
80
62
next_sibling.value.heap_previous = previous_node
81
63
end
82
64
83
- true
65
+ subtree = merge_pairs(node.value.heap_child?)
66
+ clear(node)
67
+ self .head = meld(@head , subtree)
84
68
else
85
- false
69
+ # removing head
70
+ self .head = merge_pairs(node.value.heap_child?)
71
+ node.value.heap_child = nil
86
72
end
87
73
end
88
74
@@ -99,29 +85,29 @@ class Crystal::PointerPairingHeap(T)
99
85
clear_recursive(child)
100
86
child = child.value.heap_next?
101
87
end
102
- unlink (node)
88
+ clear (node)
103
89
end
104
90
105
- private def meld (a : T * , b : T * ) : T *
91
+ private def meld (a : Pointer ( T ) , b : Pointer ( T )) : Pointer ( T )
106
92
if a.value.heap_compare(b)
107
93
add_child(a, b)
108
94
else
109
95
add_child(b, a)
110
96
end
111
97
end
112
98
113
- private def meld (a : T * , b : Nil ) : T *
99
+ private def meld (a : Pointer ( T ) , b : Nil ) : Pointer ( T )
114
100
a
115
101
end
116
102
117
- private def meld (a : Nil , b : T * ) : T *
103
+ private def meld (a : Nil , b : Pointer ( T )) : Pointer ( T )
118
104
b
119
105
end
120
106
121
107
private def meld (a : Nil , b : Nil ) : Nil
122
108
end
123
109
124
- private def add_child (parent : T * , node : T * ) : T *
110
+ private def add_child (parent : Pointer ( T ) , node : Pointer ( T )) : Pointer ( T )
125
111
first_child = parent.value.heap_child?
126
112
parent.value.heap_child = node
127
113
@@ -132,28 +118,39 @@ class Crystal::PointerPairingHeap(T)
132
118
parent
133
119
end
134
120
135
- # Twopass merge of the children of *node* into pairs of two.
136
- private def merge_pairs (a : T * ) : T * | Nil
137
- a.value.heap_previous = nil
121
+ private def merge_pairs (node : Pointer (T )?) : Pointer (T )?
122
+ return unless node
138
123
139
- if b = a.value.heap_next?
140
- a.value.heap_next = nil
141
- b.value.heap_previous = nil
142
- else
143
- return a
124
+ # 1st pass: meld children into pairs (left to right)
125
+ tail = nil
126
+
127
+ while a = node
128
+ if b = a.value.heap_next?
129
+ node = b.value.heap_next?
130
+ root = meld(a, b)
131
+ root.value.heap_previous = tail
132
+ tail = root
133
+ else
134
+ a.value.heap_previous = tail
135
+ tail = a
136
+ break
137
+ end
144
138
end
145
139
146
- rest = merge_pairs(b.value.heap_next? )
147
- b.value.heap_next = nil
140
+ # 2nd pass: meld the pairs back into a single tree (right to left )
141
+ root = nil
148
142
149
- pair = meld(a, b)
150
- meld(pair, rest)
151
- end
143
+ while tail
144
+ node = tail.value.heap_previous?
145
+ root = meld(root, tail)
146
+ tail = node
147
+ end
152
148
153
- private def merge_pairs (node : Nil ) : Nil
149
+ root.value.heap_next = nil if root
150
+ root
154
151
end
155
152
156
- private def unlink (node ) : Nil
153
+ private def clear (node ) : Nil
157
154
node.value.heap_previous = nil
158
155
node.value.heap_next = nil
159
156
node.value.heap_child = nil
0 commit comments