-
Notifications
You must be signed in to change notification settings - Fork 70
/
example_027_BPlusTree.py
133 lines (106 loc) · 4.18 KB
/
example_027_BPlusTree.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
class BPlusTree:
def __init__(self, order):
"""
Initializes a B+Tree with a specified order.
Args:
order (int): The maximum number of children for internal nodes.
"""
self.root = BPlusNode(order) # Initialize the root node of the B+Tree.
def search(self, key):
"""
Searches for a key in the B+Tree.
Args:
key: The key to search for in the tree.
Returns:
Value associated with the key if found, else None.
"""
return self.root.search(key) # Initiates the search from the root node.
def insert(self, key, value):
"""
Inserts a key-value pair into the B+Tree.
Args:
key: The key to insert.
value: The value associated with the key.
"""
self.root.insert(key, value) # Initiates the insertion from the root node.
class BPlusNode:
def __init__(self, order):
"""
Initializes a B+Tree node with a specified order.
Args:
order (int): The maximum number of children for internal nodes.
"""
self.order = order # Maximum number of children for this node.
self.keys = list() # List to hold keys.
self.values = list() # List to hold values.
self.children = list() # List to hold child nodes.
def search(self, key):
"""
Searches for a key in the current node or its children.
Args:
key: The key to search for in the node or its children.
Returns:
Value associated with the key if found, else None.
"""
if self.is_leaf(): # If it's a leaf node, search directly in this node.
for i in range(len(self.keys)):
if key == self.keys[i]:
return self.values[i]
return None
else: # If it's an internal node, find the appropriate child to continue the search.
child_index = self.get_child_index(key)
return self.children[child_index].search(key)
def insert(self, key, value):
"""
Inserts a key-value pair into the current node or its children.
Args:
key: The key to insert.
value: The value associated with the key.
"""
if not self.is_leaf(): # If it's an internal node, find the appropriate child to insert the key-value pair.
child_index = self.get_child_index(key)
self.children[child_index].insert(key, value)
else: # If it's a leaf node, directly insert the key-value pair.
self.keys.append(key)
self.values.append(value)
self.sort_node() # Sort the node after insertion.
def is_leaf(self):
"""
Checks if the node is a leaf node.
Returns:
True if the node is a leaf, False otherwise.
"""
return len(self.children) == 0
def get_child_index(self, key):
"""
Determines the appropriate child index for the given key.
Args:
key: The key to find the child index for.
Returns:
The index of the child node for the given key.
"""
for i in range(len(self.keys)):
if key < self.keys[i]:
return i
return len(self.keys) # If key is greater than all keys, return the last child index.
def sort_node(self):
"""
Sorts the keys and values in the node.
"""
combined = list(zip(self.keys, self.values)) # Convert to a list to maintain lists for keys and values
combined.sort(key=lambda x: x[0]) # Sort based on keys
self.keys, self.values = zip(*combined) # Unzip the sorted keys and values
self.keys = list(self.keys)
self.values = list(self.values)
def main():
b_plus_tree = BPlusTree(order=3) # Create a B+Tree with order 3.
# Insert some key-value pairs
b_plus_tree.insert(10, "A")
b_plus_tree.insert(5, "B")
b_plus_tree.insert(20, "C")
b_plus_tree.insert(30, "D")
# # Search for a key
result = b_plus_tree.search(5)
print("Value for key 5:", result) # Output: Value for key 5: B
if __name__ == "__main__":
main()