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