Skip to content

Commit 6d68e9b

Browse files
committed
Refactor shared ordered-binary key accessors
Extract common key/min/max helpers into Tree::Utils::BinarySearchNodeAccessors and use it across BinarySearchTreeNode, AvlTreeNode, RedBlackTreeNode, SplayTreeNode, and TreapNode without changing public behavior.
1 parent fbdeb4f commit 6d68e9b

7 files changed

Lines changed: 90 additions & 130 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ Changes section to scan for breaking or behavioral changes.
2020
* Refactor shared array-backed tree API helpers into
2121
`Tree::Utils::ArrayTreeApiMethods` and use it in `Tree::FenwickTree` and
2222
`Tree::SegmentTree` without changing public behavior.
23+
* Refactor shared ordered-binary node accessors into
24+
`Tree::Utils::BinarySearchNodeAccessors` and use it in
25+
`BinarySearchTreeNode`, `AvlTreeNode`, `RedBlackTreeNode`,
26+
`SplayTreeNode`, and `TreapNode` without changing public behavior.
2327
* Make `Tree::TrieNode#<<` use trie word-insert semantics (`insert(word)`)
2428
instead of generic child-node attachment semantics.
2529
* Add `<<` insertion shorthand to `Tree::AATree` and `Tree::BTree` for

lib/tree/avltree.rb

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
# frozen_string_literal: true
3939

4040
require_relative 'binarytree'
41+
require_relative 'utils/binary_search_node_accessors'
4142

4243
module Tree
4344
# Provides an AVL Tree implementation. This node allows only two child nodes
@@ -54,6 +55,8 @@ module Tree
5455
# This inherits from the {Tree::BinaryTreeNode} class.
5556
#
5657
class AvlTreeNode < BinaryTreeNode
58+
include Tree::Utils::BinarySearchNodeAccessors
59+
5760
# @!group Core Attributes
5861

5962
# @!attribute [r] height
@@ -148,32 +151,6 @@ def delete(key)
148151
removed
149152
end
150153

151-
# Returns the minimum node in the subtree rooted at this node.
152-
#
153-
# @return [Tree::AvlTreeNode] The minimum node in the subtree.
154-
def min_node
155-
current = self
156-
current = current.left_child while current.left_child
157-
current
158-
end
159-
160-
# Returns the maximum node in the subtree rooted at this node.
161-
#
162-
# @return [Tree::AvlTreeNode] The maximum node in the subtree.
163-
def max_node
164-
current = self
165-
current = current.right_child while current.right_child
166-
current
167-
end
168-
169-
# Returns the AVL key for this node (the content).
170-
#
171-
# @return [Object] The node content used as the AVL key.
172-
def key
173-
validate_key!(@content)
174-
@content
175-
end
176-
177154
private
178155

179156
# Coerce a name or node into an AVL node instance.

lib/tree/binarysearchtree.rb

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
# frozen_string_literal: true
3939

4040
require_relative 'binarytree'
41+
require_relative 'utils/binary_search_node_accessors'
4142

4243
module Tree
4344
# Provides a Binary Search Tree (BST) implementation. This node allows only
@@ -50,6 +51,8 @@ module Tree
5051
# This inherits from the {Tree::BinaryTreeNode} class.
5152
#
5253
class BinarySearchTreeNode < BinaryTreeNode
54+
include Tree::Utils::BinarySearchNodeAccessors
55+
5356
# Inserts the specified node into the BST, based on the node content.
5457
#
5558
# @param [Tree::BinarySearchTreeNode, String, Symbol] node_or_name The node
@@ -131,32 +134,6 @@ def delete(key)
131134
removed
132135
end
133136

134-
# Returns the minimum node in the subtree rooted at this node.
135-
#
136-
# @return [Tree::BinarySearchTreeNode] The minimum node in the subtree.
137-
def min_node
138-
current = self
139-
current = current.left_child while current.left_child
140-
current
141-
end
142-
143-
# Returns the maximum node in the subtree rooted at this node.
144-
#
145-
# @return [Tree::BinarySearchTreeNode] The maximum node in the subtree.
146-
def max_node
147-
current = self
148-
current = current.right_child while current.right_child
149-
current
150-
end
151-
152-
# Returns the BST key for this node (the content).
153-
#
154-
# @return [Object] The node content used as the BST key.
155-
def key
156-
validate_key!(@content)
157-
@content
158-
end
159-
160137
private
161138

162139
# Coerce a name or node into a BST node instance.

lib/tree/redblacktree.rb

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
# frozen_string_literal: true
3939

4040
require_relative 'binarytree'
41+
require_relative 'utils/binary_search_node_accessors'
4142

4243
module Tree
4344
# Provides a Red-Black Tree implementation. This node allows only two child
@@ -55,6 +56,8 @@ module Tree
5556
# root after modifications.
5657
#
5758
class RedBlackTreeNode < BinaryTreeNode
59+
include Tree::Utils::BinarySearchNodeAccessors
60+
5861
# @!group Core Attributes
5962

6063
# @!attribute [r] color
@@ -154,32 +157,6 @@ def delete(key)
154157
removed
155158
end
156159

157-
# Returns the minimum node in the subtree rooted at this node.
158-
#
159-
# @return [Tree::RedBlackTreeNode] The minimum node in the subtree.
160-
def min_node
161-
current = self
162-
current = current.left_child while current.left_child
163-
current
164-
end
165-
166-
# Returns the maximum node in the subtree rooted at this node.
167-
#
168-
# @return [Tree::RedBlackTreeNode] The maximum node in the subtree.
169-
def max_node
170-
current = self
171-
current = current.right_child while current.right_child
172-
current
173-
end
174-
175-
# Returns the RB tree key for this node (the content).
176-
#
177-
# @return [Object] The node content used as the RB tree key.
178-
def key
179-
validate_key!(@content)
180-
@content
181-
end
182-
183160
protected
184161

185162
# Sets the node color.

lib/tree/splaytree.rb

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
# frozen_string_literal: true
3939

4040
require_relative 'binarytree'
41+
require_relative 'utils/binary_search_node_accessors'
4142

4243
module Tree
4344
# Provides a Splay Tree implementation. This node allows only two child nodes
@@ -55,6 +56,8 @@ module Tree
5556
# This inherits from the {Tree::BinaryTreeNode} class.
5657
#
5758
class SplayTreeNode < BinaryTreeNode
59+
include Tree::Utils::BinarySearchNodeAccessors
60+
5861
# Inserts the specified node into the splay tree, based on the node content.
5962
#
6063
# @param [Tree::SplayTreeNode, String, Symbol] node_or_name The node
@@ -137,32 +140,6 @@ def delete(key)
137140
removed
138141
end
139142

140-
# Returns the minimum node in the subtree rooted at this node.
141-
#
142-
# @return [Tree::SplayTreeNode] The minimum node in the subtree.
143-
def min_node
144-
current = self
145-
current = current.left_child while current.left_child
146-
current
147-
end
148-
149-
# Returns the maximum node in the subtree rooted at this node.
150-
#
151-
# @return [Tree::SplayTreeNode] The maximum node in the subtree.
152-
def max_node
153-
current = self
154-
current = current.right_child while current.right_child
155-
current
156-
end
157-
158-
# Returns the splay key for this node (the content).
159-
#
160-
# @return [Object] The node content used as the splay key.
161-
def key
162-
validate_key!(@content)
163-
@content
164-
end
165-
166143
private
167144

168145
# Coerce a name or node into a splay node instance.

lib/tree/treap.rb

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
# frozen_string_literal: true
3939

4040
require_relative 'binarytree'
41+
require_relative 'utils/binary_search_node_accessors'
4142

4243
module Tree
4344
# Provides a Treap implementation. This node allows only two child nodes
@@ -58,6 +59,8 @@ module Tree
5859
# This inherits from the {Tree::BinaryTreeNode} class.
5960
#
6061
class TreapNode < BinaryTreeNode
62+
include Tree::Utils::BinarySearchNodeAccessors
63+
6164
# @!group Core Attributes
6265

6366
# @!attribute [r] priority
@@ -163,32 +166,6 @@ def delete(key)
163166
removed
164167
end
165168

166-
# Returns the minimum node in the subtree rooted at this node.
167-
#
168-
# @return [Tree::TreapNode] The minimum node in the subtree.
169-
def min_node
170-
current = self
171-
current = current.left_child while current.left_child
172-
current
173-
end
174-
175-
# Returns the maximum node in the subtree rooted at this node.
176-
#
177-
# @return [Tree::TreapNode] The maximum node in the subtree.
178-
def max_node
179-
current = self
180-
current = current.right_child while current.right_child
181-
current
182-
end
183-
184-
# Returns the treap key for this node (the content).
185-
#
186-
# @return [Object] The node content used as the treap key.
187-
def key
188-
validate_key!(@content)
189-
@content
190-
end
191-
192169
private
193170

194171
# Generate a random priority value.
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# binary_search_node_accessors.rb - This file is part of the RubyTree package.
2+
#
3+
# = binary_search_node_accessors.rb - Shared accessors for ordered binary nodes.
4+
#
5+
# Provides shared key/min/max helpers for ordered binary node types that use
6+
# +content+ as the sortable key.
7+
#
8+
# Author:: Anupam Sengupta (anupamsg@gmail.com)
9+
#
10+
11+
# Copyright (c) 2026 Anupam Sengupta. All rights reserved.
12+
#
13+
# Redistribution and use in source and binary forms, with or without
14+
# modification, are permitted provided that the following conditions are met:
15+
#
16+
# - Redistributions of source code must retain the above copyright notice, this
17+
# list of conditions and the following disclaimer.
18+
#
19+
# - Redistributions in binary form must reproduce the above copyright notice,
20+
# this list of conditions and the following disclaimer in the documentation
21+
# and/or other materials provided with the distribution.
22+
#
23+
# - Neither the name of the organization nor the names of its contributors may
24+
# be used to endorse or promote products derived from this software without
25+
# specific prior written permission.
26+
#
27+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
30+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
31+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
33+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
34+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
35+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37+
#
38+
# frozen_string_literal: true
39+
40+
module Tree
41+
module Utils
42+
# Shared key/min/max helpers for ordered binary node variants.
43+
module BinarySearchNodeAccessors
44+
# Returns the minimum node in the subtree rooted at this node.
45+
#
46+
# @return [Tree::BinaryTreeNode] The minimum node in the subtree.
47+
def min_node
48+
current = self
49+
current = current.left_child while current.left_child
50+
current
51+
end
52+
53+
# Returns the maximum node in the subtree rooted at this node.
54+
#
55+
# @return [Tree::BinaryTreeNode] The maximum node in the subtree.
56+
def max_node
57+
current = self
58+
current = current.right_child while current.right_child
59+
current
60+
end
61+
62+
# Returns the ordered key for this node (the content).
63+
#
64+
# @return [Object] The node content used as the key.
65+
def key
66+
validate_key!(@content)
67+
@content
68+
end
69+
end
70+
end
71+
end

0 commit comments

Comments
 (0)