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

Deletion step 2

parent 1b3e4265
No related branches found
No related tags found
No related merge requests found
......@@ -52,7 +52,7 @@ def find_value_index_in_array(array, value):
return None
def array_insert_sorted(array, value):
def sorted_array_insert(array, value):
index = lower_bound(array, value)
array.insert(index, value)
return index
......@@ -95,15 +95,15 @@ def split_leaf(node, key):
if virtual_insertion_index < median_index:
median_value = node.keys[median_index - 1]
redistribute_keys(node, right_node, median_index - 1, median_index - 1)
array_insert_sorted(node.keys, key)
sorted_array_insert(node.keys, key)
elif virtual_insertion_index > median_index:
median_value = node.keys[median_index]
redistribute_keys(node, right_node, median_index, median_index)
array_insert_sorted(right_node.keys, key)
sorted_array_insert(right_node.keys, key)
else:
median_value = key
redistribute_keys(node, right_node, median_index, median_index)
array_insert_sorted(right_node.keys, key)
sorted_array_insert(right_node.keys, key)
if not node.children:
# The node has no link to the next node, so a link is created.
......@@ -132,14 +132,14 @@ def split_internal(node, key, right_child_node):
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)
inserted_at_index = sorted_array_insert(node.keys, key)
node.children.insert(inserted_at_index + 1, right_child_node)
elif virtual_insertion_index > median_index:
# 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)
inserted_at_index = sorted_array_insert(right_node.keys, key)
right_node.children.insert(inserted_at_index + 1, right_child_node)
else:
# The key is virtually inserted at the median index.
......@@ -179,7 +179,7 @@ def insert_full(root, parents, node, key, previous_split_right_node):
def insert_non_full(node, key, previous_split_right_node):
inserted_at_index = array_insert_sorted(node.keys, key)
inserted_at_index = sorted_array_insert(node.keys, key)
if previous_split_right_node is not None:
node.children.insert(inserted_at_index + 1, previous_split_right_node)
......@@ -222,123 +222,134 @@ def bptree_find_smallest_key(root):
def bptree_shrink(root):
right_child = root.children[1]
root.keys = right_child.keys
root.children = right_child.children
child = root.children[0]
root.keys = child.keys.copy()
root.children = child.children.copy()
root.is_leaf = child.is_leaf
def bptree_delete_internal(root, parents, node, key):
if node != root:
parent = parents.pop()
def bptree_steal_internal():
# TODO
pass
def bptree_steal_leaf(parent, node, child_index, sibling, sibling_side):
if sibling_side == "l":
sibling_key = sibling.keys[len(sibling.keys) - 1]
sorted_array_delete(sibling.keys, sibling_key)
sorted_array_insert(node.keys, sibling_key)
parent.keys[child_index - 1] = sibling_key
elif sibling_side == "r":
sibling_key = sibling.keys[0]
sorted_array_delete(sibling.keys, sibling_key)
sorted_array_insert(node.keys, sibling_key)
parent.keys[child_index] = sibling.keys[0]
def _bptree_merge(parent, main_node, secondary_node, pivot_index):
if not main_node.is_leaf:
parent_key = parent.keys[pivot_index]
main_node.keys.insert(0, parent_key)
if len(node.keys) < node.order and node != root:
print("Merge 2")
# children_index = None
for i in reversed(range(len(secondary_node.keys))):
main_node.keys.insert(0, secondary_node.keys[i])
# for i, child in enumerate(parent.children):
# if node == child:
# children_index = i
if not main_node.is_leaf:
for i in reversed(range(len(secondary_node.children))):
main_node.children.insert(0, secondary_node.children[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)
parent.keys.pop(pivot_index)
parent.children.pop(pivot_index)
# for key in sibling.keys:
# array_insert_sorted(node.keys, key)
# node.children = sibling.children + node.children
def bptree_merge(parent, node, child_index, sibling, sibling_side):
if sibling_side == "l":
# The sibling is merged into the node.
_bptree_merge(parent, node, sibling, child_index - 1)
elif sibling_side == "r":
# The node is merged into the sibling.
_bptree_merge(parent, sibling, node, child_index)
# 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])
def find_child_index(parent, child):
for i in range(len(parent.children)):
if child == parent.children[i]:
return i
if node != root:
bptree_delete_internal(root, parents, parent, key)
return None
def bptree_find_sibling(parent, children_index):
if children_index == 0:
def bptree_find_sibling(parent, child_index):
if child_index == 0:
# Must take the sibling on the right.
sibling = parent.children[1]
sibling_position = "r"
elif children_index == 2 * parent.order - 1:
elif child_index == len(parent.children) - 1:
# Must take the sibling on the left.
sibling = parent.children[2 * parent.order - 2]
sibling = parent.children[len(parent.children) - 2]
sibling_position = "l"
else:
# Can take the sibling from left or right.
if len(parent.children[children_index - 1].keys) > parent.order:
if len(parent.children[child_index - 1].keys) > parent.order:
# The left sibling has enough keys to borrow one.
sibling = parent.children[children_index - 1]
sibling = parent.children[child_index - 1]
sibling_position = "l"
elif len(parent.children[children_index + 1].keys) > parent.order:
elif len(parent.children[child_index + 1].keys) > parent.order:
# The right sibling has enough keys to borrow one.
sibling = parent.children[children_index + 1]
sibling = parent.children[child_index + 1]
sibling_position = "r"
else:
# A merge between the node and the left sibling is required.
sibling = parent.children[children_index - 1]
sibling = parent.children[child_index - 1]
sibling_position = "l"
return sibling, sibling_position
def bptree_delete_leaf(root, parents, leaf, key):
if leaf != root:
def _bptree_delete(root, parents, node, key):
parent = None
if len(parents) > 0:
parent = parents.pop()
if len(leaf.keys) > leaf.order or leaf == root:
sorted_array_delete(leaf.keys, key)
if node.is_leaf:
keys_length = len(node.keys)
sorted_array_delete(node.keys, key)
if keys_length == node.order and node != root:
child_index = find_child_index(parent, node)
sibling, sibling_side = bptree_find_sibling(parent, child_index)
if len(sibling.keys) == sibling.order:
# There is not enough key in the left and right siblings.
bptree_merge(parent, node, child_index, sibling, sibling_side)
if parent == root and len(parent.keys) == 0:
bptree_shrink(root)
parent = None
else:
# There are enough keys in the sibling to steal one.
bptree_steal_leaf(parent, node, child_index, sibling, sibling_side)
else:
deletion_index = find_value_index_in_array(leaf.keys, key)
leaf.keys.pop(deletion_index)
children_index = None
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]
sorted_array_delete(sibling.keys, sibling_key)
array_insert_sorted(leaf.keys, sibling_key)
parent.keys[children_index - 1] = sibling_key
if node != root and len(node.keys) < node.order:
child_index = find_child_index(parent, node)
sibling, sibling_side = bptree_find_sibling(parent, child_index)
if len(sibling.keys) == sibling.order:
bptree_merge(parent, node, child_index, sibling, sibling_side)
if parent == root and len(parent.keys) == 0:
bptree_shrink(root)
parent = None
else:
sibling_key = sibling.keys[0]
sorted_array_delete(sibling.keys, sibling_key)
array_insert_sorted(leaf.keys, sibling_key)
parent.keys[children_index] = sibling.keys[0]
print("???????????")
if len(node.children) > 0 and 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])
bptree_delete_internal(root, parents, parent, key)
if parent is not None:
_bptree_delete(root, parents, parent, key)
def deletion_find_leaf(root, key):
......@@ -363,14 +374,13 @@ def bptree_delete(root, key):
if not is_value_in_array(leaf.keys, key):
return
bptree_delete_leaf(root, parents, leaf, key)
_bptree_delete(root, parents, leaf, key)
# DELETION : END
def bptree_search(root, key):
# BUG !!!
if root.is_leaf:
return is_value_in_array(root.keys, key)
......@@ -455,19 +465,19 @@ def main():
# assert not bptree_search(root, random_key)
root = Node(order)
keys = generate_random_keys(18, 1, 99)
keys = generate_random_keys(30, 1, 99)
print(keys)
print("=====")
for key in keys:
bptree_insert(root, key)
bptree_delete(root, 56)
bptree_delete(root, 12)
bptree_delete(root, 21)
bptree_delete(root, 65)
bptree_delete(root, 57)
bptree_delete(root, 47)
bptree_delete(root, 11)
bptree_delete(root, 86)
# bptree_delete(root, 65)
bptree_print(root)
......
rebu.py 0 → 100644
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:
deletion_index = find_value_index_in_array(leaf.keys, key)
leaf.keys.pop(deletion_index)
children_index = None
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]
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]
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)
def bptree_delete_internal(root, parents, node, key):
if node != root:
parent = parents.pop()
if len(node.keys) < node.order and node != root:
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])
if node != root:
bptree_delete_internal(root, parents, parent, key)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment