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

Update deletion

parent 06ef8907
Branches
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