| ... | @@ -257,6 +257,48 @@ pub fn Treap(comptime Key: type, comptime compareFn: anytype) type { | ... | @@ -257,6 +257,48 @@ pub fn Treap(comptime Key: type, comptime compareFn: anytype) type { |
| 257 | assert(link.* == node); | 257 | assert(link.* == node); |
| 258 | link.* = target; | 258 | link.* = target; |
| 259 | } | 259 | } |
| | 260 | |
| | 261 | pub const InorderIterator = struct { |
| | 262 | current: ?*Node, |
| | 263 | previous: ?*Node = null, |
| | 264 | |
| | 265 | pub fn next(it: *InorderIterator) ?*Node { |
| | 266 | while (true) { |
| | 267 | if (it.current) |current| { |
| | 268 | const previous = it.previous; |
| | 269 | it.previous = current; |
| | 270 | if (previous == current.parent) { |
| | 271 | if (current.children[0]) |left_child| { |
| | 272 | it.current = left_child; |
| | 273 | } else { |
| | 274 | if (current.children[1]) |right_child| { |
| | 275 | it.current = right_child; |
| | 276 | } else { |
| | 277 | it.current = current.parent; |
| | 278 | } |
| | 279 | return current; |
| | 280 | } |
| | 281 | } else if (previous == current.children[0]) { |
| | 282 | if (current.children[1]) |right_child| { |
| | 283 | it.current = right_child; |
| | 284 | } else { |
| | 285 | it.current = current.parent; |
| | 286 | } |
| | 287 | return current; |
| | 288 | } else { |
| | 289 | std.debug.assert(previous == current.children[1]); |
| | 290 | it.current = current.parent; |
| | 291 | } |
| | 292 | } else { |
| | 293 | return null; |
| | 294 | } |
| | 295 | } |
| | 296 | } |
| | 297 | }; |
| | 298 | |
| | 299 | pub fn inorderIterator(self: *Self) InorderIterator { |
| | 300 | return .{ .current = self.root }; |
| | 301 | } |
| 260 | }; | 302 | }; |
| 261 | } | 303 | } |
| 262 | | 304 | |
| ... | @@ -344,6 +386,16 @@ test "std.Treap: insert, find, replace, remove" { | ... | @@ -344,6 +386,16 @@ test "std.Treap: insert, find, replace, remove" { |
| 344 | try testing.expectEqual(entry.node, treap.getEntryForExisting(node).node); | 386 | try testing.expectEqual(entry.node, treap.getEntryForExisting(node).node); |
| 345 | } | 387 | } |
| 346 | | 388 | |
| | 389 | // in-order iterator check |
| | 390 | { |
| | 391 | var it = treap.inorderIterator(); |
| | 392 | var last_key: u64 = 0; |
| | 393 | while (it.next()) |node| { |
| | 394 | try std.testing.expect(node.key >= last_key); |
| | 395 | last_key = node.key; |
| | 396 | } |
| | 397 | } |
| | 398 | |
| 347 | // replace check | 399 | // replace check |
| 348 | iter.reset(); | 400 | iter.reset(); |
| 349 | while (iter.next()) |node| { | 401 | while (iter.next()) |node| { |