Skip to content
Snippets Groups Projects
Commit 1b3e4265 authored by florian.burgener's avatar florian.burgener
Browse files

Update deletion

parent 06ef8907
No related branches found
No related tags found
No related merge requests found
......@@ -58,6 +58,12 @@ def array_insert_sorted(array, value):
return index
def sorted_array_delete(array, value):
index = find_value_index_in_array(array, value)
array.pop(index)
return index
# B+ Tree : START
......@@ -226,34 +232,35 @@ def bptree_delete_internal(root, parents, node, key):
parent = parents.pop()
if len(node.keys) < node.order and node != root:
children_index = None
for i, child in enumerate(parent.children):
if node == child:
children_index = i
if children_index == 0:
sibling = parent.children[children_index + 1]
parent_key = parent.keys[children_index]
parent.keys.pop(find_value_index_in_array(parent.keys, parent_key))
array_insert_sorted(sibling.keys, parent_key)
array_insert_sorted(sibling.keys, node.keys[0])
sibling.children = node.children + sibling.children
else:
sibling = parent.children[children_index - 1]
parent_key = parent.keys[children_index - 1]
parent.keys.pop(find_value_index_in_array(parent.keys, parent_key))
array_insert_sorted(node.keys, parent_key)
for key in sibling.keys:
array_insert_sorted(node.keys, key)
node.children = sibling.children + node.children
if parent == root and len(parent.keys) == 0:
bptree_shrink(root)
if is_value_in_array(node.keys, key):
print("Merge 2")
# children_index = None
# for i, child in enumerate(parent.children):
# if node == child:
# children_index = i
# if children_index == 0:
# sibling = parent.children[children_index + 1]
# parent_key = parent.keys[children_index]
# parent.keys.pop(find_value_index_in_array(parent.keys, parent_key))
# array_insert_sorted(sibling.keys, parent_key)
# array_insert_sorted(sibling.keys, node.keys[0])
# sibling.children = node.children + sibling.children
# else:
# sibling = parent.children[children_index - 1]
# parent_key = parent.keys[children_index - 1]
# parent.keys.pop(find_value_index_in_array(parent.keys, parent_key))
# array_insert_sorted(node.keys, parent_key)
# for key in sibling.keys:
# array_insert_sorted(node.keys, key)
# node.children = sibling.children + node.children
# if parent == root and len(parent.keys) == 0:
# bptree_shrink(root)
if is_value_in_array(node.keys, key) and len(node.children) > 0:
index = find_value_index_in_array(node.keys, key)
node.keys[index] = bptree_find_smallest_key(node.children[index + 1])
......@@ -261,37 +268,22 @@ def bptree_delete_internal(root, parents, node, key):
bptree_delete_internal(root, parents, parent, key)
def bptree_delete_leaf(root, parents, leaf, key):
if len(leaf.keys) > leaf.order or leaf == root:
deletion_index = find_value_index_in_array(leaf.keys, key)
leaf.keys.pop(deletion_index)
bptree_delete_internal(root, parents, parents.pop(), key)
else:
deletion_index = find_value_index_in_array(leaf.keys, key)
leaf.keys.pop(deletion_index)
parent = parents.pop()
children_index = None
for i, child in enumerate(parent.children):
if leaf == child:
children_index = i
def bptree_find_sibling(parent, children_index):
if children_index == 0:
# Must take the sibling on the right.
sibling = parent.children[1]
sibling_position = "r"
elif children_index == 2 * leaf.order - 1:
elif children_index == 2 * parent.order - 1:
# Must take the sibling on the left.
sibling = parent.children[children_index - 1]
sibling = parent.children[2 * parent.order - 2]
sibling_position = "l"
else:
# Can take the sibling from left or right.
if len(parent.children[children_index - 1].keys) > leaf.order:
if len(parent.children[children_index - 1].keys) > parent.order:
# The left sibling has enough keys to borrow one.
sibling = parent.children[children_index - 1]
sibling_position = "l"
elif len(parent.children[children_index + 1].keys) > leaf.order:
elif len(parent.children[children_index + 1].keys) > parent.order:
# The right sibling has enough keys to borrow one.
sibling = parent.children[children_index + 1]
sibling_position = "r"
......@@ -299,31 +291,50 @@ def bptree_delete_leaf(root, parents, leaf, key):
# A merge between the node and the left sibling is required.
sibling = parent.children[children_index - 1]
if len(sibling.keys) == sibling.order:
if children_index == 0:
# Sibling not on the left.
array_insert_sorted(sibling.keys, leaf.keys[0])
parent.children.pop(children_index)
parent.keys.pop(children_index)
return sibling, sibling_position
def bptree_delete_leaf(root, parents, leaf, key):
if leaf != root:
parent = parents.pop()
if len(leaf.keys) > leaf.order or leaf == root:
sorted_array_delete(leaf.keys, key)
else:
for key in sibling.keys:
array_insert_sorted(leaf.keys, key)
deletion_index = find_value_index_in_array(leaf.keys, key)
leaf.keys.pop(deletion_index)
parent.children.pop(children_index - 1)
parent.keys.pop(children_index - 1)
children_index = None
bptree_delete_internal(root, parents, parent, key)
for i, child in enumerate(parent.children):
if leaf == child:
children_index = i
sibling, sibling_position = bptree_find_sibling(parent, children_index)
if len(sibling.keys) == sibling.order:
print("Merge 1")
pass
# if children_index == 0:
# # Sibling not on the left.
# array_insert_sorted(sibling.keys, leaf.keys[0])
# parent.children.pop(children_index)
# parent.keys.pop(children_index)
# else:
# for key in sibling.keys:
# array_insert_sorted(leaf.keys, key)
# parent.children.pop(children_index - 1)
# parent.keys.pop(children_index - 1)
else:
if sibling_position == "l":
sibling_key = sibling.keys[len(sibling.keys) - 1]
deletion_index = find_value_index_in_array(sibling.keys, sibling_key)
sibling.keys.pop(deletion_index)
sorted_array_delete(sibling.keys, sibling_key)
array_insert_sorted(leaf.keys, sibling_key)
parent.keys[children_index - 1] = sibling_key
else:
sibling_key = sibling.keys[0]
deletion_index = find_value_index_in_array(sibling.keys, sibling_key)
sibling.keys.pop(deletion_index)
sorted_array_delete(sibling.keys, sibling_key)
array_insert_sorted(leaf.keys, sibling_key)
parent.keys[children_index] = sibling.keys[0]
......@@ -420,48 +431,44 @@ def main():
random.seed(a)
order = 2
root = Node(order)
keys = generate_random_keys(40, 1, 99)
print(keys)
# root = Node(order)
# keys = generate_random_keys(40, 1, 99)
# print(keys)
for key in keys:
bptree_insert(root, key)
# for key in keys:
# bptree_insert(root, key)
bptree_print(root)
extracted_keys = bptree_extract_all_keys(root)
assert extracted_keys == sorted(keys)
# bptree_print(root)
# extracted_keys = bptree_extract_all_keys(root)
# assert extracted_keys == sorted(keys)
for key in keys:
assert bptree_search(root, key)
# for key in keys:
# assert bptree_search(root, key)
for _ in range(5):
while True:
random_key = random.randint(1, 99)
# for _ in range(5):
# while True:
# random_key = random.randint(1, 99)
if random_key not in keys:
break
# if random_key not in keys:
# break
assert not bptree_search(root, random_key)
# assert not bptree_search(root, random_key)
# root = Node(order)
# keys = generate_random_keys(18, 1, 99)
# print(keys)
# print("=====")
root = Node(order)
keys = generate_random_keys(18, 1, 99)
print(keys)
print("=====")
# for key in keys:
# bptree_insert(root, key)
for key in keys:
bptree_insert(root, key)
# bptree_delete(root, 56)
# bptree_delete(root, 82)
# bptree_delete(root, 75)
# bptree_insert(root, 80)
# bptree_delete(root, 47)
# # bptree_delete(root, 80)
# bptree_delete(root, 21)
# bptree_delete(root, 22)
# bptree_delete(root, 12)
# bptree_delete(root, 8)
# bptree_print(root)
bptree_delete(root, 56)
bptree_delete(root, 12)
bptree_delete(root, 21)
bptree_delete(root, 47)
bptree_delete(root, 11)
bptree_delete(root, 86)
bptree_print(root)
if __name__ == "__main__":
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment