| ... | ... | @@ -49,7 +49,12 @@ pub fn PriorityQueue(comptime T: type) type { |
| 49 | 49 | |
| 50 | 50 | fn addUnchecked(self: *Self, elem: T) void { |
| 51 | 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 | 58 | while (child_index > 0) { |
| 54 | 59 | var parent_index = ((child_index - 1) >> 1); |
| 55 | 60 | const child = self.items[child_index]; |
| ... | ... | @@ -61,7 +66,6 @@ pub fn PriorityQueue(comptime T: type) type { |
| 61 | 66 | self.items[child_index] = parent; |
| 62 | 67 | child_index = parent_index; |
| 63 | 68 | } |
| 64 | | self.len += 1; |
| 65 | 69 | } |
| 66 | 70 | |
| 67 | 71 | /// Add each element in `items` to the queue. |
| ... | ... | @@ -190,6 +194,17 @@ pub fn PriorityQueue(comptime T: type) type { |
| 190 | 194 | self.len = new_len; |
| 191 | 195 | } |
| 192 | 196 | |
| 197 | pub fn update(self: *Self, elem: T, new_elem: T) !void { |
| 198 | var update_index: usize = std.mem.indexOfScalar(T, self.items, elem) orelse return error.ElementNotFound; |
| 199 | const old_elem: T = self.items[update_index]; |
| 200 | self.items[update_index] = new_elem; |
| 201 | if (self.compareFn(new_elem, old_elem)) { |
| 202 | siftUp(self, update_index); |
| 203 | } else { |
| 204 | siftDown(self, update_index); |
| 205 | } |
| 206 | } |
| 207 | |
| 193 | 208 | pub const Iterator = struct { |
| 194 | 209 | queue: *PriorityQueue(T), |
| 195 | 210 | count: usize, |
| ... | ... | @@ -437,3 +452,66 @@ test "std.PriorityQueue: iterator while empty" { |
| 437 | 452 | |
| 438 | 453 | expectEqual(it.next(), null); |
| 439 | 454 | } |
| 455 | |
| 456 | test "std.PriorityQueue: update min heap" { |
| 457 | var queue = PQ.init(testing.allocator, lessThan); |
| 458 | defer queue.deinit(); |
| 459 | |
| 460 | try queue.add(55); |
| 461 | try queue.add(44); |
| 462 | try queue.add(11); |
| 463 | try queue.update(55, 5); |
| 464 | try queue.update(44, 4); |
| 465 | try queue.update(11, 1); |
| 466 | expectEqual(@as(u32, 1), queue.remove()); |
| 467 | expectEqual(@as(u32, 4), queue.remove()); |
| 468 | expectEqual(@as(u32, 5), queue.remove()); |
| 469 | } |
| 470 | |
| 471 | |
| 472 | test "std.PriorityQueue: update same min heap" { |
| 473 | var queue = PQ.init(testing.allocator, lessThan); |
| 474 | defer queue.deinit(); |
| 475 | |
| 476 | try queue.add(1); |
| 477 | try queue.add(1); |
| 478 | try queue.add(2); |
| 479 | try queue.add(2); |
| 480 | try queue.update(1, 5); |
| 481 | try queue.update(2, 4); |
| 482 | expectEqual(@as(u32, 1), queue.remove()); |
| 483 | expectEqual(@as(u32, 2), queue.remove()); |
| 484 | expectEqual(@as(u32, 4), queue.remove()); |
| 485 | expectEqual(@as(u32, 5), queue.remove()); |
| 486 | } |
| 487 | |
| 488 | test "std.PriorityQueue: update max heap" { |
| 489 | var queue = PQ.init(testing.allocator, greaterThan); |
| 490 | defer queue.deinit(); |
| 491 | |
| 492 | try queue.add(55); |
| 493 | try queue.add(44); |
| 494 | try queue.add(11); |
| 495 | try queue.update(55, 5); |
| 496 | try queue.update(44, 1); |
| 497 | try queue.update(11, 4); |
| 498 | expectEqual(@as(u32, 5), queue.remove()); |
| 499 | expectEqual(@as(u32, 4), queue.remove()); |
| 500 | expectEqual(@as(u32, 1), queue.remove()); |
| 501 | } |
| 502 | |
| 503 | test "std.PriorityQueue: update same max heap" { |
| 504 | var queue = PQ.init(testing.allocator, greaterThan); |
| 505 | defer queue.deinit(); |
| 506 | |
| 507 | try queue.add(1); |
| 508 | try queue.add(1); |
| 509 | try queue.add(2); |
| 510 | try queue.add(2); |
| 511 | try queue.update(1, 5); |
| 512 | try queue.update(2, 4); |
| 513 | expectEqual(@as(u32, 5), queue.remove()); |
| 514 | expectEqual(@as(u32, 4), queue.remove()); |
| 515 | expectEqual(@as(u32, 2), queue.remove()); |
| 516 | expectEqual(@as(u32, 1), queue.remove()); |
| 517 | } |
| | \ No newline at end of file |