Skip to content
Snippets Groups Projects
Commit 98acc8e4 authored by Florian Burgener's avatar Florian Burgener
Browse files

Insertion done (only work with unique keys)

parent a51e72da
No related branches found
No related tags found
No related merge requests found
import random
from numpy import sort
class Node:
def __init__(self, order):
......@@ -58,7 +60,7 @@ def insert(root, key):
insert_non_full(leaf, key, None)
def redistribute_items(left_node, right_node, left_index, right_index):
def redistribute_keys(left_node, right_node, left_index, right_index):
right_node.keys = left_node.keys[right_index:]
left_node.keys = left_node.keys[:left_index]
......@@ -66,68 +68,64 @@ def redistribute_items(left_node, right_node, left_index, right_index):
def split_leaf(node, key):
virtual_insertion_index = array_binary_search(node.keys, key)
median_index = len(node.keys) // 2
right_node = Node(node.order)
right_node.is_leaf = node.is_leaf
if virtual_insertion_index < median_index:
median_value = node.keys[median_index - 1]
redistribute_items(node, right_node, median_index - 1, median_index - 1)
redistribute_keys(node, right_node, median_index - 1, median_index - 1)
array_insert_sorted(node.keys, key)
else:
if virtual_insertion_index > median_index:
median_value = node.keys[median_index]
else:
median_value = key
redistribute_items(node, right_node, median_index, median_index)
redistribute_keys(node, right_node, median_index, median_index)
array_insert_sorted(right_node.keys, key)
# if key == node.keys[len(node.keys) // 2]:
# # I don't like it but without it the duplicates can't work.
# split_index = len(node.keys) // 2
if not node.children:
# The node has no link to the next node, so a link is created.
node.children.append(right_node)
else:
# The node already has a link to the next node, the right node is linked to it and the node is linked to the right node.
right_node.children.append(node.children[0])
node.children[0] = right_node
return median_value, right_node
def redistribute_children(left_node, right_node, left_index, right_index):
right_node.children = left_node.children[right_index:]
left_node.children = left_node.children[:left_index]
def split_internal(node, key, right_child_node):
virtual_insertion_index = array_binary_search(node.keys, key)
median_index = len(node.keys) // 2
left_index = median_index
right_index = median_index
right_node = Node(node.order)
right_node.is_leaf = False
if virtual_insertion_index < median_index:
abc = node.keys[median_index - 1]
left_index -= 1
elif virtual_insertion_index > median_index:
abc = node.keys[median_index]
right_index += 1
else:
abc = key
split_right = Node(node.order)
split_right.is_leaf = node.is_leaf
split_right.keys = node.keys[right_index:]
node.keys = node.keys[:left_index]
if key < abc:
# The key is virtually inserted to the left of the median index.
median_value = node.keys[median_index - 1]
redistribute_keys(node, right_node, median_index - 1, median_index)
redistribute_children(node, right_node, median_index, median_index)
inserted_at_index = array_insert_sorted(node.keys, key)
elif key > abc:
inserted_at_index = array_insert_sorted(split_right.keys, key)
if virtual_insertion_index < median_index:
split_right.children = node.children[median_index:]
node.children = node.children[:median_index]
node.children.insert(inserted_at_index + 1, right_child_node)
elif virtual_insertion_index > median_index:
split_right.children = node.children[median_index + 1 :]
node.children = node.children[: median_index + 1]
split_right.children.insert(inserted_at_index + 1, right_child_node)
# The key is virtually inserted to the right of the median index.
median_value = node.keys[median_index]
redistribute_keys(node, right_node, median_index, median_index + 1)
redistribute_children(node, right_node, median_index + 1, median_index + 1)
inserted_at_index = array_insert_sorted(right_node.keys, key)
right_node.children.insert(inserted_at_index + 1, right_child_node)
else:
split_right.children = node.children[median_index + 1 :]
node.children = node.children[: median_index + 1]
split_right.children.insert(0, right_child_node)
# The key is virtually inserted at the median index.
median_value = key
redistribute_keys(node, right_node, median_index, median_index)
redistribute_children(node, right_node, median_index + 1, median_index + 1)
right_node.children.insert(0, right_child_node)
return abc, split_right
return median_value, right_node
def tree_grow(root, median_value, split_right_node):
......@@ -168,10 +166,29 @@ def tree_print(root, depth=0):
print(" " * depth, end="")
print(root.keys)
if root.is_leaf:
return
for child in root.children:
tree_print(child, depth + 1)
def extract_all_keys(root):
current = root
while not current.is_leaf:
current = current.children[0]
keys = []
while current.children:
keys += current.keys
current = current.children[0]
keys += current.keys
return keys
def generate_random_keys(length, min_key, max_key):
keys = []
......@@ -191,13 +208,15 @@ def main():
order = 2
root = Node(order)
keys = generate_random_keys(30, 1, 99)
keys = generate_random_keys(40, 1, 99)
print(keys)
for key in keys:
insert(root, key)
tree_print(root)
extracted_keys = extract_all_keys(root)
assert extracted_keys == sorted(keys)
if __name__ == "__main__":
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment