mirror of
https://github.com/ziglang/zig.git
synced 2026-02-18 23:39:17 +00:00
rb: add sort() that re-sorts tree with new compare function
You can also specify the same compare function, but after updating the context that the function will use (connected to the rb.Tree) before.
This commit is contained in:
parent
e190082922
commit
4ab9678b95
@ -134,6 +134,20 @@ pub const Tree = struct {
|
||||
root: ?*Node,
|
||||
compareFn: fn (*Node, *Node, *Tree) Order,
|
||||
|
||||
/// Re-sorts a tree with a new compare function
|
||||
pub fn sort(tree: *Tree, newCompareFn: fn (*Node, *Node, *Tree) Order) !void {
|
||||
var newTree = Tree.init(newCompareFn);
|
||||
var node: *Node = undefined;
|
||||
while (true) {
|
||||
node = tree.first() orelse break;
|
||||
tree.remove(node);
|
||||
if (newTree.insert(node) != null) {
|
||||
return error.NotUnique; // EEXISTS
|
||||
}
|
||||
}
|
||||
tree.* = newTree;
|
||||
}
|
||||
|
||||
/// If you have a need for a version that caches this, please file a bug.
|
||||
pub fn first(tree: *Tree) ?*Node {
|
||||
var node: *Node = tree.root orelse return null;
|
||||
@ -244,6 +258,7 @@ pub const Tree = struct {
|
||||
return doLookup(key, tree, &parent, &is_left);
|
||||
}
|
||||
|
||||
/// If node is not part of tree, behavior is undefined.
|
||||
pub fn remove(tree: *Tree, nodeconst: *Node) void {
|
||||
var node = nodeconst;
|
||||
// as this has the same value as node, it is unsafe to access node after newnode
|
||||
@ -514,6 +529,10 @@ fn testCompare(l: *Node, r: *Node, contextIgnored: *Tree) Order {
|
||||
unreachable;
|
||||
}
|
||||
|
||||
fn testCompareReverse(l: *Node, r: *Node, contextIgnored: *Tree) Order {
|
||||
return testCompare(r, l, contextIgnored);
|
||||
}
|
||||
|
||||
test "rb" {
|
||||
if (@import("builtin").arch == .aarch64) {
|
||||
// TODO https://github.com/ziglang/zig/issues/3288
|
||||
@ -600,4 +619,8 @@ test "multiple inserts, followed by calling first and last" {
|
||||
var lookupNode: testNumber = undefined;
|
||||
lookupNode.value = 3;
|
||||
assert(tree.lookup(&lookupNode.node) == &third.node);
|
||||
tree.sort(testCompareReverse) catch unreachable;
|
||||
assert(testGetNumber(tree.first().?).value == 3);
|
||||
assert(testGetNumber(tree.last().?).value == 0);
|
||||
assert(tree.lookup(&lookupNode.node) == &third.node);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user