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,108 +232,113 @@ def bptree_delete_internal(root, parents, node, key):
parent = parents.pop()
if len(node.keys) < node.order and node != root:
children_index = None
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])
for i, child in enumerate(parent.children):
if node == child:
children_index = i
if node != root:
bptree_delete_internal(root, parents, parent, key)
if children_index == 0:
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 * parent.order - 1:
# Must take the sibling on the left.
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) > 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) > parent.order:
# The right sibling has enough keys to borrow one.
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
sibling_position = "r"
else:
# A merge between the node and the left sibling is required.
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):
index = find_value_index_in_array(node.keys, key)
node.keys[index] = bptree_find_smallest_key(node.children[index + 1])
if node != root:
bptree_delete_internal(root, parents, parent, key)
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:
deletion_index = find_value_index_in_array(leaf.keys, key)
leaf.keys.pop(deletion_index)
bptree_delete_internal(root, parents, parents.pop(), key)
sorted_array_delete(leaf.keys, 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
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:
# Must take the sibling on the left.
sibling = parent.children[children_index - 1]
sibling_position = "l"
else:
# Can take the sibling from left or right.
if len(parent.children[children_index - 1].keys) > leaf.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:
# The right sibling has enough keys to borrow one.
sibling = parent.children[children_index + 1]
sibling_position = "r"
else:
# A merge between the node and the left sibling is required.
sibling = parent.children[children_index - 1]
sibling, sibling_position = bptree_find_sibling(parent, children_index)
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)
else:
for key in sibling.keys:
array_insert_sorted(leaf.keys, key)
parent.children.pop(children_index - 1)
parent.keys.pop(children_index - 1)
bptree_delete_internal(root, parents, parent, key)
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]
bptree_delete_internal(root, parents, parent, key)
bptree_delete_internal(root, parents, parent, key)
def deletion_find_leaf(root, key):
......@@ -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