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
6de38c99
Commit
6de38c99
authored
3 years ago
by
Alec
Browse files
Options
Downloads
Patches
Plain Diff
library commented
parent
44365830
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
bp_tree.c
+91
-43
91 additions, 43 deletions
bp_tree.c
bp_tree.h
+18
-10
18 additions, 10 deletions
bp_tree.h
with
109 additions
and
53 deletions
bp_tree.c
+
91
−
43
View file @
6de38c99
...
@@ -4,6 +4,12 @@
...
@@ -4,6 +4,12 @@
#include
<stdbool.h>
#include
<stdbool.h>
#include
<math.h>
#include
<math.h>
typedef
struct
control
{
int
value
;
node
*
lhs
;
node
*
rhs
;
}
control
;
const
control
CONST_CONTR
=
{
const
control
CONST_CONTR
=
{
.
value
=
0
,
.
value
=
0
,
.
lhs
=
NULL
,
.
lhs
=
NULL
,
...
@@ -35,7 +41,9 @@ bool bp_is_leaf(node *nd) {return nd->childs[0] == NULL;}
...
@@ -35,7 +41,9 @@ 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 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
];
...
@@ -46,28 +54,50 @@ void bp_node_shift(node *nd, int index)
...
@@ -46,28 +54,50 @@ void bp_node_shift(node *nd, int index)
node
*
bp_split
(
node
*
nd
)
node
*
bp_split
(
node
*
nd
)
{
{
node
*
new
=
bp_create_node
();
node
*
new
=
bp_create_node
();
for
(
int
i
=
0
;
i
<
M
/
2
;
i
++
)
/*
this weird thing is for the for loop
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
*/
int
upto
=
(
int
)
floor
(
M
/
2
);
int
index
=
upto
;
// update the new counts
nd
->
count
=
(
int
)
floor
(
nd
->
count
/
2
);
new
->
count
=
upto
;
// as explained, do shit if the order is odd
if
(
M
%
2
==
1
)
{
upto
++
;
new
->
count
++
;
}
for
(
int
i
=
0
;
i
<
upto
;
i
++
)
{
{
new
->
data
[
i
]
=
nd
->
data
[
M
/
2
+
i
];
new
->
data
[
i
]
=
nd
->
data
[
index
+
i
];
nd
->
data
[
M
/
2
+
i
]
=
0
;
nd
->
data
[
index
+
i
]
=
0
;
new
->
childs
[
i
]
=
nd
->
childs
[
M
/
2
+
i
];
new
->
childs
[
i
]
=
nd
->
childs
[
index
+
i
];
nd
->
childs
[
M
/
2
+
i
]
=
NULL
;
nd
->
childs
[
index
+
i
]
=
NULL
;
}
}
nd
->
count
/=
2
;
new
->
count
=
M
/
2
;
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 the algorithm)
for
(
int
i
=
0
;
i
<
M
;
i
++
)
for
(
int
i
=
0
;
i
<
M
;
i
++
)
{
{
// 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
(
nd
->
data
[
i
]
>
val
.
value
)
if
(
nd
->
data
[
i
]
>
val
.
value
)
{
{
bp_node_shift
(
nd
,
i
);
bp_node_shift
(
nd
,
i
);
...
@@ -78,7 +108,7 @@ control bp_insert_into(node *nd, control val)
...
@@ -78,7 +108,7 @@ control bp_insert_into(node *nd, control val)
}
}
nd
->
count
++
;
nd
->
count
++
;
// if the node is now full, we split
if
(
nd
->
count
==
M
)
if
(
nd
->
count
==
M
)
{
{
control
v
;
control
v
;
...
@@ -86,20 +116,23 @@ control bp_insert_into(node *nd, control val)
...
@@ -86,20 +116,23 @@ control bp_insert_into(node *nd, control val)
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
(
bp_is_leaf
(
new
))
if
(
bp_is_leaf
(
new
))
nd
->
next
=
new
;
nd
->
next
=
new
;
return
v
;
return
v
;
}
}
return
CONST_CONTR
;
return
CONST_CONTR
;
}
}
control
bp_insert
(
node
*
nd
,
control
val
){
control
bp_insert
(
node
*
nd
,
control
val
){
control
c
;
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
(
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
{
{
for
(
int
i
=
0
;
i
<
M
;
i
++
)
for
(
int
i
=
0
;
i
<
M
;
i
++
)
{
{
...
@@ -109,9 +142,8 @@ control bp_insert(node *nd, control val){
...
@@ -109,9 +142,8 @@ control bp_insert(node *nd, control val){
break
;
break
;
}
}
}
}
//c = bp_insert_into(nd, c);
}
}
//
Si il y a eu un split
//
if a split happened
if
(
c
.
value
!=
0
)
if
(
c
.
value
!=
0
)
{
{
return
c
;
return
c
;
...
@@ -121,6 +153,7 @@ control bp_insert(node *nd, control val){
...
@@ -121,6 +153,7 @@ control bp_insert(node *nd, control val){
node
*
bp_split_root
(
node
*
root
)
node
*
bp_split_root
(
node
*
root
)
{
{
// 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
();
...
@@ -147,12 +180,21 @@ node* bp_split_root(node *root)
...
@@ -147,12 +180,21 @@ node* bp_split_root(node *root)
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
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
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
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
++
)
...
@@ -166,16 +208,17 @@ node* bp_insert_val(node* tree, int val)
...
@@ -166,16 +208,17 @@ node* bp_insert_val(node* tree, int val)
}
}
}
}
/* GROS ICI SI LA RACINE N'EST PAS UNE FEUILLE ET QU'APRES AVOIR REMONTE UNE VALEUR LA RACINE EST PLEINE, IL FAUT SPLIT LA RACINE */
// If the root is full, we must split it
printf
(
"%d
\n
"
,
tree
->
count
);
if
(
tree
->
count
==
M
)
if
(
tree
->
count
==
M
)
{
{
return
bp_split_root
(
tree
);
return
bp_split_root
(
tree
);
}
}
//if not, we can simply return the root
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
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
;
...
@@ -185,58 +228,64 @@ node* bp_insert_val(node* tree, int val)
...
@@ -185,58 +228,64 @@ node* bp_insert_val(node* tree, int val)
return
tree
;
return
tree
;
}
}
void
bp_destroy
(
node
*
nd
)
void
bp_destroy
(
node
*
root
)
{
{
if
(
nd
==
NULL
)
if
(
root
==
NULL
)
return
;
return
;
if
(
!
bp_is_leaf
(
nd
))
// free the childs first
if
(
!
bp_is_leaf
(
root
))
{
{
for
(
int
i
=
0
;
i
<
M
;
i
++
)
for
(
int
i
=
0
;
i
<
M
;
i
++
)
{
{
bp_destroy
(
nd
->
childs
[
i
]);
bp_destroy
(
root
->
childs
[
i
]);
}
}
}
}
//free(nd->childs);
free
(
nd
);
}
// then free the root
free
(
root
);
}
void
bp_print_as_ll
(
node
*
nd
)
void
bp_print_as_ll
(
node
*
root
)
{
{
if
(
nd
==
NULL
)
// if we reached the end of the list
if
(
root
==
NULL
)
{
{
printf
(
"NULL
\n
"
);
printf
(
"NULL
\n
"
);
return
;
return
;
}
}
if
(
!
bp_is_leaf
(
nd
))
// search for the first leaf on the tree
if
(
!
bp_is_leaf
(
root
))
{
{
return
bp_print_as_ll
(
nd
->
childs
[
0
]);
return
bp_print_as_ll
(
root
->
childs
[
0
]);
}
}
// print every values in the node until hitting 0, then we can get on the next node
for
(
int
i
=
0
;
i
<
M
;
i
++
)
for
(
int
i
=
0
;
i
<
M
;
i
++
)
{
{
printf
(
" %d |"
,
nd
->
data
[
i
]);
printf
(
" %d |"
,
root
->
data
[
i
]);
if
(
nd
->
data
[
i
+
1
]
==
0
)
if
(
root
->
data
[
i
+
1
]
==
0
)
{
{
printf
(
"->"
);
printf
(
"->"
);
return
bp_print_as_ll
(
nd
->
next
);
return
bp_print_as_ll
(
root
->
next
);
}
}
}
}
}
}
void
bp_print
(
node
*
nd
,
int
depth
)
void
bp_print
(
node
*
root
,
int
depth
)
{
{
if
(
bp_is_leaf
(
nd
))
// if we are on a leaf, we can print the values directly next to each other
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 |"
,
nd
->
data
[
i
]);
printf
(
" %d |"
,
root
->
data
[
i
]);
if
(
nd
->
data
[
i
+
1
]
==
0
)
// if we reach a 0, we have seen every values in the node
if
(
root
->
data
[
i
+
1
]
==
0
)
break
;
break
;
}
}
printf
(
"
\n
"
);
printf
(
"
\n
"
);
...
@@ -244,19 +293,18 @@ void bp_print(node *nd, int depth)
...
@@ -244,19 +293,18 @@ void bp_print(node *nd, int depth)
}
}
for
(
int
i
=
0
;
i
<
M
;
i
++
)
for
(
int
i
=
0
;
i
<
M
;
i
++
)
{
{
printf
(
"
\n
"
);
printf
(
"
\n
"
);
bp_print
(
nd
->
childs
[
i
],
depth
+
1
);
bp_print
(
root
->
childs
[
i
],
depth
+
1
);
for
(
int
i
=
0
;
i
<
depth
;
i
++
)
for
(
int
i
=
0
;
i
<
depth
;
i
++
)
printf
(
" "
);
printf
(
" "
);
printf
(
" %d |"
,
nd
->
data
[
i
]);
printf
(
" %d |"
,
root
->
data
[
i
]);
if
(
nd
->
data
[
i
+
1
]
==
0
)
if
(
root
->
data
[
i
+
1
]
==
0
)
{
{
printf
(
"
\n
"
);
printf
(
"
\n
"
);
return
bp_print
(
nd
->
childs
[
i
+
1
],
depth
+
1
);
return
bp_print
(
root
->
childs
[
i
+
1
],
depth
+
1
);
}
}
}
}
}
}
\ No newline at end of file
This diff is collapsed.
Click to expand it.
bp_tree.h
+
18
−
10
View file @
6de38c99
#ifndef _BP_TREE_C_
#ifndef _BP_TREE_C_
#define _BP_TREE_C_
#define _BP_TREE_C_
#define M
4
#define M
5
#include
<stdlib.h>
#include
<stdlib.h>
typedef
struct
node
{
typedef
struct
node
{
...
@@ -11,17 +11,25 @@ typedef struct node{
...
@@ -11,17 +11,25 @@ typedef struct node{
struct
node
*
next
;
struct
node
*
next
;
}
node
;
}
node
;
typedef
struct
control
{
/// @short Print in CLI a B+ Tree
int
value
;
/// @param *root Root of the tree to print
node
*
lhs
;
/// @param depth Always set as 0
node
*
rhs
;
void
bp_print
(
node
*
root
,
int
depth
);
}
control
;
extern
const
control
CONST_CONTR
;
/// @short Free an entire B+ Tree
/// @param *root pointer to the root of the tree to free
void
bp_destroy
(
node
*
root
);
void
bp_print
(
node
*
nd
,
int
depth
);
/// @short Creates a new node of a tree with every values set in a known way
void
bp_destroy
(
node
*
nd
);
/// @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
/// @param val Value to insert
node
*
bp_insert_val
(
node
*
tree
,
int
val
);
node
*
bp_insert_val
(
node
*
tree
,
int
val
);
void
bp_print_as_ll
(
node
*
nd
);
/// @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
void
bp_print_as_ll
(
node
*
root
);
#endif
#endif
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