Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
I
ISC_144 - B+ Tree Project
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
This is an archived project. Repository and other project resources are read-only.
Show more breadcrumbs
florian.burgener
ISC_144 - B+ Tree Project
Commits
c9ce881c
Commit
c9ce881c
authored
3 years ago
by
Florian Burgener
Browse files
Options
Downloads
Patches
Plain Diff
Refactoring
parent
4675e8d3
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
__main__.py
+120
-40
120 additions, 40 deletions
__main__.py
with
120 additions
and
40 deletions
__main__.py
+
120
−
40
View file @
c9ce881c
import
random
import
random
from
numpy
import
sort
class
Node
:
def
__init__
(
self
,
order
):
self
.
order
=
order
self
.
is_leaf
=
True
self
.
keys
=
[]
self
.
children
=
[]
def
lower_bound
(
array
,
value
):
def
lower_bound
(
array
,
value
):
low
=
0
low
=
0
...
@@ -45,12 +35,40 @@ def is_value_in_array(array, value):
...
@@ -45,12 +35,40 @@ def is_value_in_array(array, value):
return
False
return
False
def
find_value_index_in_array
(
array
,
value
):
low
=
0
high
=
len
(
array
)
-
1
while
low
<=
high
:
m
=
(
low
+
high
)
//
2
if
array
[
m
]
<
value
:
low
=
m
+
1
elif
array
[
m
]
>
value
:
high
=
m
-
1
else
:
return
m
return
None
def
array_insert_sorted
(
array
,
value
):
def
array_insert_sorted
(
array
,
value
):
index
=
lower_bound
(
array
,
value
)
index
=
lower_bound
(
array
,
value
)
array
.
insert
(
index
,
value
)
array
.
insert
(
index
,
value
)
return
index
return
index
# B+ Tree : START
class
Node
:
def
__init__
(
self
,
order
):
self
.
order
=
order
self
.
is_leaf
=
True
self
.
keys
=
[]
self
.
children
=
[]
def
find_leaf
(
root
,
key
):
def
find_leaf
(
root
,
key
):
parents
=
[]
parents
=
[]
current
=
root
current
=
root
...
@@ -67,13 +85,7 @@ def node_is_full(node):
...
@@ -67,13 +85,7 @@ def node_is_full(node):
return
len
(
node
.
keys
)
==
2
*
node
.
order
return
len
(
node
.
keys
)
==
2
*
node
.
order
def
insert
(
root
,
key
):
# INSERTION : START
parents
,
leaf
=
find_leaf
(
root
,
key
)
if
node_is_full
(
leaf
):
insert_full
(
root
,
parents
,
leaf
,
key
,
None
)
else
:
insert_non_full
(
leaf
,
key
,
None
)
def
redistribute_keys
(
left_node
,
right_node
,
left_index
,
right_index
):
def
redistribute_keys
(
left_node
,
right_node
,
left_index
,
right_index
):
...
@@ -145,7 +157,7 @@ def split_internal(node, key, right_child_node):
...
@@ -145,7 +157,7 @@ def split_internal(node, key, right_child_node):
return
median_value
,
right_node
return
median_value
,
right_node
def
tree_grow
(
root
,
median_value
,
split_right_node
):
def
bp
tree_grow
(
root
,
median_value
,
split_right_node
):
left_node
=
Node
(
root
.
order
)
left_node
=
Node
(
root
.
order
)
left_node
.
is_leaf
=
split_right_node
.
is_leaf
left_node
.
is_leaf
=
split_right_node
.
is_leaf
left_node
.
keys
=
root
.
keys
left_node
.
keys
=
root
.
keys
...
@@ -162,7 +174,7 @@ def insert_full(root, parents, node, key, previous_split_right_node):
...
@@ -162,7 +174,7 @@ def insert_full(root, parents, node, key, previous_split_right_node):
median_value
,
split_right_node
=
split_internal
(
node
,
key
,
previous_split_right_node
)
median_value
,
split_right_node
=
split_internal
(
node
,
key
,
previous_split_right_node
)
if
node
==
root
:
if
node
==
root
:
tree_grow
(
root
,
median_value
,
split_right_node
)
bp
tree_grow
(
root
,
median_value
,
split_right_node
)
else
:
else
:
parent
=
parents
.
pop
()
parent
=
parents
.
pop
()
...
@@ -179,7 +191,59 @@ def insert_non_full(node, key, previous_split_right_node):
...
@@ -179,7 +191,59 @@ def insert_non_full(node, key, previous_split_right_node):
node
.
children
.
insert
(
inserted_at_index
+
1
,
previous_split_right_node
)
node
.
children
.
insert
(
inserted_at_index
+
1
,
previous_split_right_node
)
def
tree_search
(
root
,
key
):
def
bptree_insert
(
root
,
key
):
parents
,
leaf
=
find_leaf
(
root
,
key
)
if
node_is_full
(
leaf
):
insert_full
(
root
,
parents
,
leaf
,
key
,
None
)
else
:
insert_non_full
(
leaf
,
key
,
None
)
# INSERTION : END
# DELETION : START
def
bptree_delete
(
root
,
key
):
parents
,
leaf
=
find_leaf
(
root
,
key
)
if
not
is_value_in_array
(
leaf
.
keys
,
key
):
return
if
len
(
leaf
.
keys
)
>
leaf
.
order
:
deletion_index
=
find_value_index_in_array
(
leaf
.
keys
,
key
)
leaf
.
keys
.
pop
(
deletion_index
)
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
:
sibling
=
parent
.
children
[
children_index
+
1
]
else
:
sibling
=
parent
.
children
[
children_index
-
1
]
if
len
(
sibling
.
keys
)
==
leaf
.
order
:
pass
else
:
# Works only if children_index = 0
borrowed_key
=
sibling
.
keys
[
0
]
sibling
.
keys
.
pop
(
0
)
leaf
.
keys
.
append
(
borrowed_key
)
parent
.
keys
[
0
]
=
sibling
.
keys
[
0
]
# DELETION : END
def
bptree_search
(
root
,
key
):
if
root
.
is_leaf
:
if
root
.
is_leaf
:
return
is_value_in_array
(
root
.
keys
,
key
)
return
is_value_in_array
(
root
.
keys
,
key
)
...
@@ -188,10 +252,10 @@ def tree_search(root, key):
...
@@ -188,10 +252,10 @@ def tree_search(root, key):
if
children_index
<
len
(
root
.
keys
)
and
root
.
keys
[
children_index
]
==
key
:
if
children_index
<
len
(
root
.
keys
)
and
root
.
keys
[
children_index
]
==
key
:
children_index
+=
1
children_index
+=
1
return
tree_search
(
root
.
children
[
children_index
],
key
)
return
bp
tree_search
(
root
.
children
[
children_index
],
key
)
def
tree_print
(
root
,
depth
=
0
):
def
bp
tree_print
(
root
,
depth
=
0
):
print
(
"
"
*
depth
,
end
=
""
)
print
(
"
"
*
depth
,
end
=
""
)
print
(
root
.
keys
)
print
(
root
.
keys
)
...
@@ -199,10 +263,10 @@ def tree_print(root, depth=0):
...
@@ -199,10 +263,10 @@ def tree_print(root, depth=0):
return
return
for
child
in
root
.
children
:
for
child
in
root
.
children
:
tree_print
(
child
,
depth
+
1
)
bp
tree_print
(
child
,
depth
+
1
)
def
extract_all_keys
(
root
):
def
bptree_
extract_all_keys
(
root
):
current
=
root
current
=
root
while
not
current
.
is_leaf
:
while
not
current
.
is_leaf
:
...
@@ -218,6 +282,9 @@ def extract_all_keys(root):
...
@@ -218,6 +282,9 @@ def extract_all_keys(root):
return
keys
return
keys
# B+ Tree : END
def
generate_random_keys
(
length
,
min_key
,
max_key
):
def
generate_random_keys
(
length
,
min_key
,
max_key
):
keys
=
[]
keys
=
[]
...
@@ -236,28 +303,41 @@ def main():
...
@@ -236,28 +303,41 @@ def main():
random
.
seed
(
0
)
random
.
seed
(
0
)
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:
insert
(
root
,
key
)
#
bptree_
insert(root, key)
tree_print
(
root
)
# bp
tree_print(root)
extracted_keys
=
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
tree_search
(
root
,
key
)
#
assert
bp
tree_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)
root
=
Node
(
order
)
keys
=
generate_random_keys
(
8
,
1
,
99
)
print
(
keys
)
print
(
"
=====
"
)
for
key
in
keys
:
bptree_insert
(
root
,
key
)
assert
not
tree_search
(
root
,
random_key
)
bptree_delete
(
root
,
51
)
# bptree_delete(root, 52)
bptree_delete
(
root
,
34
)
bptree_print
(
root
)
if
__name__
==
"
__main__
"
:
if
__name__
==
"
__main__
"
:
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment