Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
T
TP_Bplus_Tree
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
Show more breadcrumbs
Hepia_2021-2022
Prog_Seq
TP_Bplus_Tree
Commits
d7a28fbb
Commit
d7a28fbb
authored
3 years ago
by
Alec
Browse files
Options
Downloads
Patches
Plain Diff
split root now soft
parent
3fc3d0df
Branches
Branches containing commit
No related tags found
No related merge requests found
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
bp_tree.c
+106
-124
106 additions, 124 deletions
bp_tree.c
bp_tree.h
+33
-17
33 additions, 17 deletions
bp_tree.h
main.c
+44
-37
44 additions, 37 deletions
main.c
with
183 additions
and
178 deletions
bp_tree.c
+
106
−
124
View file @
d7a28fbb
#include
"bp_tree.h"
#include
"bp_tree.h"
#include
<math.h>
#include
<stdbool.h>
#include
<stdio.h>
#include
<stdio.h>
#include
<stdlib.h>
#include
<stdlib.h>
#include
<stdbool.h>
#include
<math.h>
typedef
struct
control
{
typedef
struct
control
{
int
value
;
int
value
;
...
@@ -10,14 +10,9 @@ typedef struct control{
...
@@ -10,14 +10,9 @@ typedef struct control{
node
*
rhs
;
node
*
rhs
;
}
control
;
}
control
;
const
control
CONST_CONTR
=
{
const
control
CONST_CONTR
=
{.
value
=
0
,
.
lhs
=
NULL
,
.
rhs
=
NULL
};
.
value
=
0
,
.
lhs
=
NULL
,
.
rhs
=
NULL
};
node
*
bp_create_node
()
node
*
bp_create_node
()
{
{
node
*
nd
=
malloc
(
sizeof
(
node
));
node
*
nd
=
malloc
(
sizeof
(
node
));
for
(
int
i
=
0
;
i
<
M
+
1
;
i
++
)
for
(
int
i
=
0
;
i
<
M
+
1
;
i
++
)
...
@@ -29,8 +24,7 @@ node* bp_create_node()
...
@@ -29,8 +24,7 @@ node* bp_create_node()
return
nd
;
return
nd
;
}
}
control
value_to_insert
(
int
val
)
control
value_to_insert
(
int
val
)
{
{
control
c
;
control
c
;
c
.
value
=
val
;
c
.
value
=
val
;
c
.
lhs
=
c
.
rhs
=
NULL
;
c
.
lhs
=
c
.
rhs
=
NULL
;
...
@@ -39,25 +33,24 @@ control value_to_insert(int val)
...
@@ -39,25 +33,24 @@ control value_to_insert(int val)
bool
bp_is_leaf
(
node
*
nd
)
{
return
nd
->
childs
[
0
]
==
NULL
;
}
bool
bp_is_leaf
(
node
*
nd
)
{
return
nd
->
childs
[
0
]
==
NULL
;
}
void
bp_node_shift
(
node
*
nd
,
int
index
)
void
bp_node_shift
(
node
*
nd
,
int
index
)
{
{
// as there is one more child than values, we must do one more iteration
//
as there is one more child than values, we must do one more iteration
outside of the for
// outside of the for
nd
->
childs
[
M
]
=
nd
->
childs
[
M
-
1
];
nd
->
childs
[
M
]
=
nd
->
childs
[
M
-
1
];
for
(
int
i
=
M
-
1
;
i
>
index
;
i
--
)
for
(
int
i
=
M
-
1
;
i
>
index
;
i
--
)
{
{
nd
->
data
[
i
]
=
nd
->
data
[
i
-
1
];
nd
->
data
[
i
]
=
nd
->
data
[
i
-
1
];
nd
->
childs
[
i
+
1
]
=
nd
->
childs
[
i
];
nd
->
childs
[
i
+
1
]
=
nd
->
childs
[
i
];
}
}
}
}
node
*
bp_split
(
node
*
nd
)
node
*
bp_split
(
node
*
nd
)
{
{
node
*
new
=
bp_create_node
();
node
*
new
=
bp_create_node
();
/*
/*
this weird thing is for the for loop
this weird thing is for the for loop
up to how many loop do we want to do
up to how many loop do we want to do
we need it outside because if the order of the tree is odd, we must do one more loop
we need it outside because if the order of the tree is odd, we must do
one more loop
*/
*/
int
upto
=
(
int
)
floor
(
M
/
2
);
int
upto
=
(
int
)
floor
(
M
/
2
);
int
index
=
upto
;
int
index
=
upto
;
...
@@ -67,14 +60,12 @@ node* bp_split(node *nd)
...
@@ -67,14 +60,12 @@ node* bp_split(node *nd)
new
->
count
=
upto
;
new
->
count
=
upto
;
// as explained, do shit if the order is odd
// as explained, do shit if the order is odd
if
(
M
%
2
==
1
)
if
(
M
%
2
==
1
)
{
{
upto
++
;
upto
++
;
new
->
count
++
;
new
->
count
++
;
}
}
for
(
int
i
=
0
;
i
<
upto
;
i
++
)
for
(
int
i
=
0
;
i
<
upto
;
i
++
)
{
{
new
->
data
[
i
]
=
nd
->
data
[
index
+
i
];
new
->
data
[
i
]
=
nd
->
data
[
index
+
i
];
nd
->
data
[
index
+
i
]
=
0
;
nd
->
data
[
index
+
i
]
=
0
;
new
->
childs
[
i
]
=
nd
->
childs
[
index
+
i
];
new
->
childs
[
i
]
=
nd
->
childs
[
index
+
i
];
...
@@ -84,22 +75,20 @@ node* bp_split(node *nd)
...
@@ -84,22 +75,20 @@ node* bp_split(node *nd)
return
new
;
return
new
;
}
}
control
bp_insert_into
(
node
*
nd
,
control
val
)
control
bp_insert_into
(
node
*
nd
,
control
val
)
{
{
// look for a 0 in the node (it is guarenteed to exist in this version of
// look for a 0 in the node (it is guarenteed to exist in this version of the algorithm)
// the algorithm)
for
(
int
i
=
0
;
i
<
M
;
i
++
)
for
(
int
i
=
0
;
i
<
M
;
i
++
)
{
{
// if we plainly find a 0
// if we plainly find a 0
if
(
nd
->
data
[
i
]
==
0
)
if
(
nd
->
data
[
i
]
==
0
)
{
{
nd
->
data
[
i
]
=
val
.
value
;
nd
->
data
[
i
]
=
val
.
value
;
nd
->
childs
[
i
]
=
val
.
lhs
;
nd
->
childs
[
i
]
=
val
.
lhs
;
break
;
break
;
}
}
// if we need to insert the value between two values, we need to
shifter everything greater than our value one case further
// if we need to insert the value between two values, we need to
if
(
nd
->
data
[
i
]
>
val
.
value
)
// shifter everything greater than our value one case further
{
if
(
nd
->
data
[
i
]
>
val
.
value
)
{
bp_node_shift
(
nd
,
i
);
bp_node_shift
(
nd
,
i
);
nd
->
data
[
i
]
=
val
.
value
;
nd
->
data
[
i
]
=
val
.
value
;
nd
->
childs
[
i
]
=
val
.
rhs
;
nd
->
childs
[
i
]
=
val
.
rhs
;
...
@@ -109,15 +98,15 @@ control bp_insert_into(node *nd, control val)
...
@@ -109,15 +98,15 @@ control bp_insert_into(node *nd, control val)
nd
->
count
++
;
nd
->
count
++
;
// if the node is now full, we split
// if the node is now full, we split
if
(
nd
->
count
==
M
)
if
(
nd
->
count
==
M
)
{
{
control
v
;
control
v
;
node
*
new
=
bp_split
(
nd
);
node
*
new
=
bp_split
(
nd
);
v
.
lhs
=
nd
;
v
.
lhs
=
nd
;
v
.
rhs
=
new
;
v
.
rhs
=
new
;
v
.
value
=
new
->
data
[
0
];
v
.
value
=
new
->
data
[
0
];
// if the new node we created is a leaf, we must add it to the linked list
// if the new node we created is a leaf, we must add it to the
// linked list
if
(
bp_is_leaf
(
new
))
if
(
bp_is_leaf
(
new
))
nd
->
next
=
new
;
nd
->
next
=
new
;
...
@@ -127,80 +116,85 @@ control bp_insert_into(node *nd, control val)
...
@@ -127,80 +116,85 @@ control bp_insert_into(node *nd, control val)
}
}
control
bp_insert
(
node
*
nd
,
control
val
)
{
control
bp_insert
(
node
*
nd
,
control
val
)
{
control
c
;
// will help us to return the pivot, and the two pointers of the childs-to-be
control
c
;
// will help us to return the pivot, and the two pointers of the
// childs-to-be
// if we are in a leaf, we found where to insert the value, so let's do it
// if we are in a leaf, we found where to insert the value, so let's do it
if
(
bp_is_leaf
(
nd
))
if
(
bp_is_leaf
(
nd
))
c
=
bp_insert_into
(
nd
,
val
);
c
=
bp_insert_into
(
nd
,
val
);
else
// otherwise let's keep looking
else
// otherwise let's keep looking
{
{
for
(
int
i
=
0
;
i
<
M
;
i
++
)
for
(
int
i
=
0
;
i
<
M
;
i
++
)
{
{
if
(
nd
->
data
[
i
]
>
val
.
value
||
nd
->
data
[
i
]
==
0
)
{
if
(
nd
->
data
[
i
]
>
val
.
value
||
nd
->
data
[
i
]
==
0
)
{
c
=
bp_insert
(
nd
->
childs
[
i
],
val
);
c
=
bp_insert
(
nd
->
childs
[
i
],
val
);
break
;
break
;
}
}
}
}
}
}
// if a split happened
// if a split happened
if
(
c
.
value
!=
0
)
if
(
c
.
value
!=
0
)
{
{
return
c
;
return
c
;
}
}
return
CONST_CONTR
;
return
CONST_CONTR
;
}
}
node
*
bp_split_root
(
node
*
root
)
node
*
bp_split_root
(
node
*
root
)
{
{
// TEMPORARY FUNC (COPYRIGHT), HARD WRITTEN NEEDS TO BE SOFT
// TEMPORARY FUNC (COPYRIGHT), HARD WRITTEN NEEDS TO BE SOFT
node
*
new
=
bp_create_node
();
node
*
new
=
bp_create_node
();
node
*
rhs
=
bp_create_node
();
node
*
rhs
=
bp_create_node
();
rhs
->
childs
[
0
]
=
root
->
childs
[
3
];
int
index
=
(
int
)
floor
(
M
/
2
);
rhs
->
childs
[
1
]
=
root
->
childs
[
4
];
int
looper
=
index
;
if
(
M
%
2
==
0
)
{
looper
--
;
}
root
->
childs
[
3
]
=
NULL
;
for
(
int
i
=
0
;
i
<=
looper
;
i
++
)
{
root
->
childs
[
4
]
=
NULL
;
rhs
->
childs
[
i
]
=
root
->
childs
[
index
+
i
+
1
];
root
->
childs
[
index
+
i
+
1
]
=
NULL
;
}
rhs
->
data
[
0
]
=
root
->
data
[
3
];
for
(
int
i
=
0
;
i
<
looper
;
i
++
)
{
root
->
data
[
3
]
=
0
;
rhs
->
data
[
i
]
=
root
->
data
[
index
+
i
+
1
];
root
->
data
[
index
+
i
+
1
]
=
0
;
}
new
->
childs
[
0
]
=
root
;
new
->
childs
[
0
]
=
root
;
new
->
childs
[
1
]
=
rhs
;
new
->
childs
[
1
]
=
rhs
;
new
->
data
[
0
]
=
root
->
data
[
2
];
new
->
data
[
0
]
=
root
->
data
[
index
];
root
->
data
[
2
]
=
0
;
root
->
data
[
index
]
=
0
;
new
->
count
=
1
;
new
->
count
=
1
;
root
->
count
=
M
/
2
;
root
->
count
=
index
;
rhs
->
count
=
M
/
2
;
rhs
->
count
=
index
;
if
(
M
%
2
==
0
)
{
rhs
->
count
--
;
}
return
new
;
return
new
;
}
}
node
*
bp_insert_val
(
node
*
tree
,
int
val
)
node
*
bp_insert_val
(
node
*
tree
,
int
val
)
{
{
// Parse the val into a control struct then insert it in the tree
// Parse the val into a control struct then insert it in the tree
control
test
=
bp_insert
(
tree
,
value_to_insert
(
val
));
control
test
=
bp_insert
(
tree
,
value_to_insert
(
val
));
/*
/*
depending on the control item, we act differently
depending on the control item, we act differently
if the control has pointers to node, then we had a split in the direct childs of the root. We must add the values upringed to the root
if the control has pointers to node, then we had a split in the direct
childs of the root. We must add the values upringed to the root
*/
*/
if
(
test
.
rhs
!=
NULL
)
if
(
test
.
rhs
!=
NULL
)
{
{
/*
/*
if the root isn't a leaf, first we add the value into the node
if the root isn't a leaf, first we add the value into the node
we can't use bp_insert_into() as if we need a split, the way we do it is slightly different
we can't use bp_insert_into() as if we need a split, the way we
do it is slightly different
*/
*/
if
(
!
bp_is_leaf
(
tree
))
if
(
!
bp_is_leaf
(
tree
))
{
{
for
(
int
i
=
0
;
i
<
M
;
i
++
)
{
for
(
int
i
=
0
;
i
<
M
;
i
++
)
if
(
tree
->
data
[
i
]
==
0
)
{
{
if
(
tree
->
data
[
i
]
==
0
)
{
tree
->
childs
[
i
+
1
]
=
test
.
rhs
;
tree
->
childs
[
i
+
1
]
=
test
.
rhs
;
tree
->
data
[
i
]
=
test
.
value
;
tree
->
data
[
i
]
=
test
.
value
;
tree
->
count
++
;
tree
->
count
++
;
...
@@ -209,8 +203,7 @@ node* bp_insert_val(node* tree, int val)
...
@@ -209,8 +203,7 @@ node* bp_insert_val(node* tree, int val)
}
}
// If the root is full, we must split it
// If the root is full, we must split it
if
(
tree
->
count
==
M
)
if
(
tree
->
count
==
M
)
{
{
return
bp_split_root
(
tree
);
return
bp_split_root
(
tree
);
}
}
...
@@ -218,7 +211,8 @@ node* bp_insert_val(node* tree, int val)
...
@@ -218,7 +211,8 @@ node* bp_insert_val(node* tree, int val)
return
tree
;
return
tree
;
}
}
// if, after a split, the root was a leaf, we must create a new node which will contain the values from the control
// if, after a split, the root was a leaf, we must create a new
// node which will contain the values from the control
tree
=
bp_create_node
();
tree
=
bp_create_node
();
tree
->
childs
[
0
]
=
test
.
lhs
;
tree
->
childs
[
0
]
=
test
.
lhs
;
tree
->
childs
[
1
]
=
test
.
rhs
;
tree
->
childs
[
1
]
=
test
.
rhs
;
...
@@ -228,16 +222,13 @@ node* bp_insert_val(node* tree, int val)
...
@@ -228,16 +222,13 @@ node* bp_insert_val(node* tree, int val)
return
tree
;
return
tree
;
}
}
void
bp_destroy
(
node
*
root
)
void
bp_destroy
(
node
*
root
)
{
{
if
(
root
==
NULL
)
if
(
root
==
NULL
)
return
;
return
;
// free the childs first
// free the childs first
if
(
!
bp_is_leaf
(
root
))
if
(
!
bp_is_leaf
(
root
))
{
{
for
(
int
i
=
0
;
i
<
M
;
i
++
)
{
for
(
int
i
=
0
;
i
<
M
;
i
++
)
{
bp_destroy
(
root
->
childs
[
i
]);
bp_destroy
(
root
->
childs
[
i
]);
}
}
}
}
...
@@ -246,44 +237,36 @@ void bp_destroy(node *root)
...
@@ -246,44 +237,36 @@ void bp_destroy(node *root)
free
(
root
);
free
(
root
);
}
}
void
bp_print_as_ll
(
node
*
root
)
void
bp_print_as_ll
(
node
*
root
)
{
{
// if we reached the end of the list
// if we reached the end of the list
if
(
root
==
NULL
)
if
(
root
==
NULL
)
{
{
printf
(
"NULL
\n
"
);
printf
(
"NULL
\n
"
);
return
;
return
;
}
}
// search for the first leaf on the tree
// search for the first leaf on the tree
if
(
!
bp_is_leaf
(
root
))
if
(
!
bp_is_leaf
(
root
))
{
{
return
bp_print_as_ll
(
root
->
childs
[
0
]);
return
bp_print_as_ll
(
root
->
childs
[
0
]);
}
}
printf
(
"|"
);
printf
(
"|"
);
// print every values in the node until hitting 0, then we can get on the
next node
// print every values in the node until hitting 0, then we can get on the
for
(
int
i
=
0
;
i
<
M
;
i
++
)
// next node
{
for
(
int
i
=
0
;
i
<
M
;
i
++
)
{
printf
(
" %d |"
,
root
->
data
[
i
]);
printf
(
" %d |"
,
root
->
data
[
i
]);
if
(
root
->
data
[
i
+
1
]
==
0
)
if
(
root
->
data
[
i
+
1
]
==
0
)
{
{
printf
(
" -> "
);
printf
(
" -> "
);
return
bp_print_as_ll
(
root
->
next
);
return
bp_print_as_ll
(
root
->
next
);
}
}
}
}
}
}
void
bp_print
(
node
*
root
,
int
depth
)
void
bp_print
(
node
*
root
,
int
depth
)
{
{
// if we are on a leaf, we can print the values directly next to each other
// if we are on a leaf, we can print the values directly next to each other
if
(
bp_is_leaf
(
root
))
if
(
bp_is_leaf
(
root
))
{
{
for
(
int
i
=
0
;
i
<
depth
;
i
++
)
for
(
int
i
=
0
;
i
<
depth
;
i
++
)
printf
(
" "
);
printf
(
" "
);
for
(
int
i
=
0
;
i
<
M
;
i
++
)
for
(
int
i
=
0
;
i
<
M
;
i
++
)
{
{
printf
(
" %d |"
,
root
->
data
[
i
]);
printf
(
" %d |"
,
root
->
data
[
i
]);
// if we reach a 0, we have seen every values in the node
// if we reach a 0, we have seen every values in the node
if
(
root
->
data
[
i
+
1
]
==
0
)
if
(
root
->
data
[
i
+
1
]
==
0
)
...
@@ -292,8 +275,7 @@ void bp_print(node *root, int depth)
...
@@ -292,8 +275,7 @@ void bp_print(node *root, int depth)
return
;
return
;
}
}
for
(
int
i
=
0
;
i
<
M
;
i
++
)
for
(
int
i
=
0
;
i
<
M
;
i
++
)
{
{
bp_print
(
root
->
childs
[
i
],
depth
+
1
);
bp_print
(
root
->
childs
[
i
],
depth
+
1
);
printf
(
"
\n
"
);
printf
(
"
\n
"
);
...
...
This diff is collapsed.
Click to expand it.
bp_tree.h
+
33
−
17
View file @
d7a28fbb
...
@@ -11,25 +11,41 @@ typedef struct node{
...
@@ -11,25 +11,41 @@ typedef struct node{
struct
node
*
next
;
struct
node
*
next
;
}
node
;
}
node
;
/// @short Print in CLI a B+ Tree
/**
/// @param *root Root of the tree to print
* @brief Print in CLI a B+ Tree
/// @param depth Always set as 0
*
* @param root Root of the tree to print
* @param depth Always set as 0
*/
void
bp_print
(
node
*
root
,
int
depth
);
void
bp_print
(
node
*
root
,
int
depth
);
/// @short Free an entire B+ Tree
/**
/// @param *root pointer to the root of the tree to free
* @brief Free an entire B+ Tree
*
* @param root pointer to the root of the tree to free
*/
void
bp_destroy
(
node
*
root
);
void
bp_destroy
(
node
*
root
);
/// @short Creates a new node of a tree with every values set in a known way
/**
/// @return Pointer to new node created
* @brief Creates a new node of a tree with every values set in a known way
*
* @return Pointer to new node created
*/
node
*
bp_create_node
();
node
*
bp_create_node
();
/// @short Insert a new int (key) into a B+ Tree
/**
/// @param *tree Pointer of the root of the tree
* @brief Insert a new int (key) into a B+ Tree
/// @param val Value to insert
*
* @param tree Pointer of the root of the tree
* @param val Value to insert
* @return New root of the tree
*/
node
*
bp_insert_val
(
node
*
tree
,
int
val
);
node
*
bp_insert_val
(
node
*
tree
,
int
val
);
/// @short Print in CLI the leaves of the B+ Tree as a linked list
/**
/// @param *root Pointer to the root of the tree to print
* @brief Print in CLI the leaves of the B+ Tree as a linked list
*
* @param root Pointer to the root of the tree to print
*/
void
bp_print_as_ll
(
node
*
root
);
void
bp_print_as_ll
(
node
*
root
);
#endif
#endif
This diff is collapsed.
Click to expand it.
main.c
+
44
−
37
View file @
d7a28fbb
...
@@ -2,9 +2,7 @@
...
@@ -2,9 +2,7 @@
#include
<stdio.h>
#include
<stdio.h>
#include
<stdlib.h>
#include
<stdlib.h>
int
int
main
()
{
main
()
{
node
*
tree
=
bp_create_node
();
node
*
tree
=
bp_create_node
();
tree
=
bp_insert_val
(
tree
,
3
);
tree
=
bp_insert_val
(
tree
,
3
);
...
@@ -37,6 +35,15 @@ main ()
...
@@ -37,6 +35,15 @@ main ()
tree
=
bp_insert_val
(
tree
,
12
);
tree
=
bp_insert_val
(
tree
,
12
);
bp_print
(
tree
,
0
);
bp_print
(
tree
,
0
);
printf
(
"
\n
|||||||||
\n
"
);
printf
(
"
\n
|||||||||
\n
"
);
tree
=
bp_insert_val
(
tree
,
13
);
bp_print
(
tree
,
0
);
printf
(
"
\n
|||||||||
\n
"
);
tree
=
bp_insert_val
(
tree
,
14
);
bp_print
(
tree
,
0
);
printf
(
"
\n
|||||||||
\n
"
);
tree
=
bp_insert_val
(
tree
,
15
);
bp_print
(
tree
,
0
);
printf
(
"
\n
|||||||||
\n
"
);
bp_print_as_ll
(
tree
);
bp_print_as_ll
(
tree
);
bp_destroy
(
tree
);
bp_destroy
(
tree
);
return
0
;
return
0
;
...
...
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