| ... | @@ -49,7 +49,12 @@ pub fn PriorityQueue(comptime T: type) type { | ... | @@ -49,7 +49,12 @@ pub fn PriorityQueue(comptime T: type) type { |
| 49 | | 49 | |
| 50 | fn addUnchecked(self: *Self, elem: T) void { | 50 | fn addUnchecked(self: *Self, elem: T) void { |
| 51 | self.items[self.len] = elem; | 51 | self.items[self.len] = elem; |
| 52 | var child_index = self.len; | 52 | siftUp(self, self.len); |
| | 53 | self.len += 1; |
| | 54 | } |
| | 55 | |
| | 56 | fn siftUp(self: *Self, start_index: usize) void { |
| | 57 | var child_index = start_index; |
| 53 | while (child_index > 0) { | 58 | while (child_index > 0) { |
| 54 | var parent_index = ((child_index - 1) >> 1); | 59 | var parent_index = ((child_index - 1) >> 1); |
| 55 | const child = self.items[child_index]; | 60 | const child = self.items[child_index]; |
| ... | @@ -61,7 +66,6 @@ pub fn PriorityQueue(comptime T: type) type { | ... | @@ -61,7 +66,6 @@ pub fn PriorityQueue(comptime T: type) type { |
| 61 | self.items[child_index] = parent; | 66 | self.items[child_index] = parent; |
| 62 | child_index = parent_index; | 67 | child_index = parent_index; |
| 63 | } | 68 | } |
| 64 | self.len += 1; | | |
| 65 | } | 69 | } |
| 66 | | 70 | |
| 67 | /// Add each element in `items` to the queue. | 71 | /// Add each element in `items` to the queue. |
| ... | @@ -190,27 +194,16 @@ pub fn PriorityQueue(comptime T: type) type { | ... | @@ -190,27 +194,16 @@ pub fn PriorityQueue(comptime T: type) type { |
| 190 | self.len = new_len; | 194 | self.len = new_len; |
| 191 | } | 195 | } |
| 192 | | 196 | |
| 193 | fn linearSearch(elem: T, items: []const T) usize { | | |
| 194 | var found: usize = 0; | | |
| 195 | for (items) |item, i| { | | |
| 196 | if (item == elem) { | | |
| 197 | found = i; | | |
| 198 | break; | | |
| 199 | } | | |
| 200 | } | | |
| 201 | return found; | | |
| 202 | } | | |
| 203 | | | |
| 204 | pub fn update(self: *Self, elem: T, new_elem: T) !void { | 197 | pub fn update(self: *Self, elem: T, new_elem: T) !void { |
| 205 | var update_index: usize = linearSearch(elem, self.items); | 198 | var update_index: usize = std.mem.indexOfScalar(T, self.items, elem) catch |error| return error.ElementNotFound; |
| 206 | assert (update_index >= 0 and update_index < self.items.len); | 199 | assert (update_index >= 0 and update_index < self.items.len); |
| 207 | // Heapreplace: | 200 | const old_elem: T = self.items[update_index]; |
| 208 | // replace the item: self.items[update_index]= new_elem; | | |
| 209 | // swap the new item to the top of the heap: std.mem.swap(heap[0], heap[update_index]); | | |
| 210 | // sift up or down: which has been generically implemented as sift down: siftDown(self, 0) | | |
| 211 | self.items[update_index] = new_elem; | 201 | self.items[update_index] = new_elem; |
| 212 | std.mem.swap(T, &self.items[0], &self.items[update_index]); | 202 | if (self.compareFn(new_elem, old_elem)) { |
| 213 | siftDown(self, 0); | 203 | siftUp(self, update_index); |
| | 204 | } else { |
| | 205 | siftDown(self, update_index); |
| | 206 | } |
| 214 | } | 207 | } |
| 215 | | 208 | |
| 216 | pub const Iterator = struct { | 209 | pub const Iterator = struct { |