@@ -133,7 +133,7 @@ pub fn RedBlackTreeSet(
133133 /// Returns `error.OutOfMemory` if node allocation fails.
134134 pub fn put (self : * Self , data : T ) ! void {
135135 // Check if key already exists first to avoid unnecessary allocation
136- if (self .get (data )) | existing | {
136+ if (self .getNode (data )) | existing | {
137137 existing .data = data ;
138138 return ;
139139 }
@@ -241,7 +241,7 @@ pub fn RedBlackTreeSet(
241241 ///
242242 /// Time complexity: O(log n)
243243 pub fn remove (self : * Self , data : T ) ? T {
244- const node = self .get (data ) orelse return null ;
244+ const node = self .getNode (data ) orelse return null ;
245245 const value = node .data ;
246246 self .removeNode (node );
247247 self .size -= 1 ;
@@ -432,13 +432,24 @@ pub fn RedBlackTreeSet(
432432 node .parent = left ;
433433 }
434434
435- /// Returns a pointer to the node containing the data.
435+ /// Returns an immutable pointer to the stored value that compares equal
436+ /// to `data`, or `null` if no such value exists.
436437 ///
437- /// Returns `null` if the data is not found. The returned node pointer can be used
438- /// to access or modify the data directly.
438+ /// Time complexity: O(log n)
439+ pub fn get (self : * const Self , data : T ) ? * const T {
440+ const node = self .getNode (data ) orelse return null ;
441+ return & node .data ;
442+ }
443+
444+ /// Checks whether the tree contains the given value.
439445 ///
440446 /// Time complexity: O(log n)
441- pub fn get (self : * const Self , data : T ) ? * Node {
447+ pub fn contains (self : * const Self , data : T ) bool {
448+ return self .getNode (data ) != null ;
449+ }
450+
451+ /// Internal: returns the node pointer for mutation by `put` and `remove`.
452+ fn getNode (self : * const Self , data : T ) ? * Node {
442453 var current = self .root ;
443454
444455 while (current ) | node | {
@@ -452,13 +463,6 @@ pub fn RedBlackTreeSet(
452463 return null ;
453464 }
454465
455- /// Checks whether the tree contains the given value.
456- ///
457- /// Time complexity: O(log n)
458- pub fn contains (self : * const Self , data : T ) bool {
459- return self .get (data ) != null ;
460- }
461-
462466 fn findMinimum (self : * const Self , node : * Node ) * Node {
463467 _ = self ; // Mark as intentionally unused
464468 var current = node ;
@@ -468,19 +472,25 @@ pub fn RedBlackTreeSet(
468472 return current ;
469473 }
470474
471- pub fn minimum (self : Self , node : ? * Node ) ? * Node {
472- const start = node orelse self .root orelse return null ;
473- return self .findMinimum (start );
475+ /// Returns the smallest value in the tree, or `null` if the tree is empty.
476+ ///
477+ /// Time complexity: O(log n)
478+ pub fn minimum (self : * const Self ) ? T {
479+ const start = self .root orelse return null ;
480+ return self .findMinimum (start ).data ;
474481 }
475482
476- pub fn maximum (self : Self , node : ? * Node ) ? * Node {
477- var current = node orelse self .root orelse return null ;
483+ /// Returns the largest value in the tree, or `null` if the tree is empty.
484+ ///
485+ /// Time complexity: O(log n)
486+ pub fn maximum (self : * const Self ) ? T {
487+ var current = self .root orelse return null ;
478488
479489 while (current .right ) | right | {
480490 current = right ;
481491 }
482492
483- return current ;
493+ return current . data ;
484494 }
485495
486496 /// Iterator for in-order traversal
@@ -512,7 +522,7 @@ pub fn RedBlackTreeSet(
512522 self .stack .deinit (self .allocator );
513523 }
514524
515- pub fn next (self : * Iterator ) ! ? * Node {
525+ pub fn next (self : * Iterator ) ! ? T {
516526 if (self .stack .items .len == 0 ) return null ;
517527
518528 const node : * Node = self .stack .pop ().? ;
@@ -524,7 +534,7 @@ pub fn RedBlackTreeSet(
524534 current = n .left ;
525535 }
526536
527- return node ;
537+ return node . data ;
528538 }
529539 };
530540
@@ -670,13 +680,13 @@ test "RedBlackTreeSet: minimum and maximum" {
670680 try tree .put (3 );
671681 try tree .put (20 );
672682
673- const min = tree .minimum (null );
674- const max = tree .maximum (null );
683+ const min = tree .minimum ();
684+ const max = tree .maximum ();
675685
676686 try std .testing .expect (min != null );
677687 try std .testing .expect (max != null );
678- try std .testing .expectEqual (@as (i32 , 3 ), min .? . data );
679- try std .testing .expectEqual (@as (i32 , 20 ), max .? . data );
688+ try std .testing .expectEqual (@as (i32 , 3 ), min .? );
689+ try std .testing .expectEqual (@as (i32 , 20 ), max .? );
680690}
681691
682692test "RedBlackTreeSet: iterator empty tree" {
@@ -720,15 +730,17 @@ test "RedBlackTreeSet: negative numbers" {
720730 try std .testing .expect (tree .contains (0 ));
721731}
722732
723- test "RedBlackTreeSet: get returns correct node " {
733+ test "RedBlackTreeSet: get returns correct value " {
724734 const allocator = std .testing .allocator ;
725735 var tree = RedBlackTreeSet (i32 , i32Compare ).init (allocator );
726736 defer tree .deinit ();
727737
728738 try tree .put (10 );
729739 try tree .put (20 );
730740
731- const node = tree .get (10 );
732- try std .testing .expect (node != null );
733- try std .testing .expectEqual (@as (i32 , 10 ), node .? .data );
741+ const ptr = tree .get (10 );
742+ try std .testing .expect (ptr != null );
743+ try std .testing .expectEqual (@as (i32 , 10 ), ptr .?.* );
744+
745+ try std .testing .expect (tree .get (99 ) == null );
734746}
0 commit comments