Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Nadi Tomeh
SDA
Commits
49cdb06f
Commit
49cdb06f
authored
Sep 09, 2020
by
david
Browse files
premier test CI
parent
f2518138
Changes
36
Hide whitespace changes
Inline
Side-by-side
.gitlab-ci.yml
0 → 100644
View file @
49cdb06f
image
:
alpine
stages
:
-
test
sda:test
script
:
-
file AUTHORS.md
CPP/include/structures/BTree.hpp
0 → 100644
View file @
49cdb06f
#ifndef __BTREE__
#define __BTREE__
/**
@ensures capacity of nodes >= order * size
*/
template
<
typename
T
>
class
BTree
{
public:
BTree
(
int
order
){
}
private:
int
order
;
std
::
vector
<
T
>
nodes
;
};
#endif
CPP/include/structures/RedBlackTree.hpp
0 → 100644
View file @
49cdb06f
#ifndef __RED_BLACK_TREE_H__
#define __RED_BLACK_TREE_H__
#include
<queue>
#include
<assert.h>
namespace
structures
{
#define __BLACK__ true
#define __RED__ false
#define __RED_BLACK_LEAF__ nullptr
template
<
typename
T
>
class
RedBlackTree
{
private:
struct
RedBlackNode
{
RedBlackNode
*
parent_n
;
RedBlackNode
*
left_n
;
RedBlackNode
*
right_n
;
bool
color
;
T
key
;
inline
RedBlackNode
*
parent
(){
return
parent_n
;
}
inline
RedBlackNode
*
grand_parent
(){
RedBlackNode
*
p
=
parent
();
return
(
p
==
nullptr
)
?
nullptr
:
p
->
parent
();
}
inline
RedBlackNode
*
sibling
(){
RedBlackNode
*
p
=
parent
();
if
(
p
==
nullptr
)
return
nullptr
;
if
(
p
->
left_n
==
this
)
return
p
->
right_n
;
return
p
->
left_n
;
}
inline
RedBlackNode
*
uncle
(){
RedBlackNode
*
p
=
parent
();
if
(
p
==
nullptr
)
return
nullptr
;
return
(
p
->
parent
()
==
nullptr
)
?
nullptr
:
p
->
sibling
();
}
friend
bool
operator
<
(
const
RedBlackNode
&
rbn1
,
const
RedBlackNode
&
rbn2
)
{
return
rbn1
.
key
<
rbn2
.
key
;
// keep the same order
}
RedBlackNode
(
const
T
&
key_p
,
const
bool
color_p
=
__RED__
)
:
parent_n
(
nullptr
),
left_n
(
nullptr
),
right_n
(
nullptr
),
color
(
color_p
),
key
(
key_p
){}
};
int
size
;
RedBlackNode
*
root
;
RedBlackNode
*
brt_insert
(
const
T
&
value
){
RedBlackNode
**
tmp
=
&
root
;
RedBlackNode
*
parent_node
=
nullptr
;
RedBlackNode
*
new_node
=
new
RedBlackNode
(
value
);
while
(
*
tmp
!=
nullptr
){
parent_node
=
*
tmp
;
if
(
*
new_node
<
**
tmp
)
tmp
=
&
((
*
tmp
)
->
left_n
);
else
tmp
=
&
((
*
tmp
)
->
right_n
);
}
*
tmp
=
new_node
;
new_node
->
parent_n
=
parent_node
;
size
++
;
return
new_node
;
}
void
rotate_left
(
RedBlackNode
*
n
,
RedBlackNode
*
p
){
RedBlackNode
*
right_node
=
n
->
right_n
;
std
::
cerr
<<
"--------Rotate Left -------"
<<
std
::
endl
;
print
();
if
(
right_node
!=
__RED_BLACK_LEAF__
){
n
->
right_n
=
right_node
->
left_n
;
right_node
->
left_n
=
n
;
n
->
parent_n
=
right_node
;
if
(
n
->
right_n
!=
__RED_BLACK_LEAF__
)
n
->
right_n
->
parent_n
=
n
;
if
(
p
!=
nullptr
)
{
if
(
n
==
p
->
left_n
)
{
p
->
left_n
=
right_node
;
}
else
if
(
n
==
p
->
right_n
)
{
p
->
right_n
=
right_node
;
}
}
right_node
->
parent_n
=
p
;
}
}
void
rotate_right
(
RedBlackNode
*
n
,
RedBlackNode
*
p
){
RedBlackNode
*
nnew
=
n
->
left_n
;
assert
(
nnew
!=
nullptr
);
// Since the leaves of a red-black tree are empty,
// they cannot become internal nodes.
n
->
left_n
=
nnew
->
right_n
;
nnew
->
right_n
=
n
;
n
->
parent_n
=
nnew
;
// Handle other child/parent pointers.
if
(
n
->
left_n
!=
nullptr
)
{
n
->
left_n
->
parent_n
=
n
;
}
// Initially n could be the root.
if
(
p
!=
nullptr
)
{
if
(
n
==
p
->
left_n
)
{
p
->
left_n
=
nnew
;
}
else
if
(
n
==
p
->
right_n
)
{
p
->
right_n
=
nnew
;
}
}
nnew
->
parent_n
=
p
;
}
inline
void
repair_upward
(
RedBlackNode
*
p
,
RedBlackNode
*
u
,
RedBlackNode
*
g
){
p
->
color
=
__BLACK__
;
u
->
color
=
__BLACK__
;
g
->
color
=
__RED__
;
repair_tree
(
g
);
}
inline
void
repair_downward
(
RedBlackNode
*
n
,
RedBlackNode
*
p
,
RedBlackNode
*
g
){
//Step One
if
(
g
->
left_n
!=
nullptr
&&
n
==
g
->
left_n
->
right_n
){
rotate_left
(
p
,
g
);
n
=
n
->
left_n
;
}
else
if
(
g
->
right_n
!=
nullptr
&&
n
==
g
->
right_n
->
left_n
){
rotate_right
(
p
,
g
);
n
=
n
->
right_n
;
}
//Step Two
p
=
n
->
parent
();
g
=
n
->
grand_parent
();
if
(
n
==
p
->
left_n
)
rotate_right
(
g
,
g
->
parent
());
else
rotate_left
(
g
,
g
->
parent
());
p
->
color
=
__BLACK__
;
g
->
color
=
__RED__
;
}
void
repair_tree
(
RedBlackNode
*
new_node
){
RedBlackNode
*
p
=
new_node
->
parent
();
if
(
p
==
nullptr
)
new_node
->
color
=
__BLACK__
;
else
if
(
p
->
color
==
__RED__
){
RedBlackNode
*
u
=
new_node
->
uncle
();
RedBlackNode
*
g
=
new_node
->
grand_parent
();
if
(
u
!=
nullptr
&&
u
->
color
==
__RED__
)
repair_upward
(
p
,
u
,
g
);
else
repair_downward
(
new_node
,
p
,
g
);
}
}
void
node_label
(
int
node
,
RedBlackNode
*
current
){
std
::
cout
<<
node
<<
" [label =
\"
"
<<
current
->
key
<<
"
\"
"
;
if
(
current
->
color
==
__RED__
)
std
::
cout
<<
", color=
\"
white
\"
, color =
\"
red
\"
];"
<<
std
::
endl
;
else
std
::
cout
<<
", color=
\"
white
\"
, color =
\"
grey
\"
];"
<<
std
::
endl
;
}
public:
RedBlackTree
()
:
size
(
0
),
root
(
nullptr
){}
inline
size_t
get_size
(){
return
size
;
}
void
insert
(
const
T
&
value
){
RedBlackNode
*
new_node
=
brt_insert
(
value
);
print
();
std
::
cerr
<<
"-----------Repair----------"
<<
std
::
endl
;
repair_tree
(
new_node
);
}
void
print
(){
std
::
queue
<
RedBlackNode
*>
nodes
;
RedBlackNode
*
current
;
int
node
=
0
;
int
current_node
=
1
;
nodes
.
push
(
root
);
std
::
cout
<<
"digraph {"
<<
std
::
endl
;
std
::
cout
<<
"node [ style =
\"
filled
\"
];"
<<
std
::
endl
;
node_label
(
node
,
root
);
while
(
!
nodes
.
empty
()){
current
=
nodes
.
front
();
nodes
.
pop
();
if
(
current
->
left_n
!=
nullptr
){
node_label
(
current_node
,
current
->
left_n
);
std
::
cout
<<
node
<<
" -> "
<<
current_node
++<<
"; left"
<<
std
::
endl
;
nodes
.
push
(
current
->
left_n
);
}
if
(
current
->
right_n
!=
nullptr
){
node_label
(
current_node
,
current
->
right_n
);
std
::
cout
<<
node
<<
" -> "
<<
current_node
++<<
"; right"
<<
std
::
endl
;
nodes
.
push
(
current
->
right_n
);
}
node
++
;
}
std
::
cout
<<
"}"
<<
std
::
endl
;
}
};
}
#endif
CPP/include/structures/binary_heap.hpp
0 → 100644
View file @
49cdb06f
#ifndef __BINARY_HEAP_HPP
#define __BINARY_HEAP_HPP
#include
"heap.hpp"
namespace
structures
{
template
<
typename
T
>
class
BinaryHeap
:
public
Heap
<
T
>
{
protected:
virtual
bool
compare_elements
(
int
pos1
,
int
pos2
)
=
0
;
virtual
void
swap
(
int
pos1
,
int
pos2
)
=
0
;
virtual
T
get
(
int
pos
)
=
0
;
void
up_heap
(){
int
pos
=
this
->
get_size
()
-
1
;
int
pos_parent
=
(
pos
-
1
)
/
2
;
while
(
pos
>
0
&&
compare_elements
(
pos
,
pos_parent
)
){
swap
(
pos
,
pos_parent
);
pos
=
pos_parent
;
pos_parent
=
(
pos
-
1
)
/
2
;
}
}
void
down_heap
(){
size_t
pos
=
0
;
size_t
child_pos
=
min_max_child
(
pos
);
while
(
child_pos
>=
0
&&
compare_elements
(
child_pos
,
pos
)
){
swap
(
pos
,
child_pos
);
pos
=
child_pos
;
child_pos
=
min_max_child
(
pos
);
}
}
inline
int
min_max_child
(
size_t
pos
){
if
(
2
*
pos
+
1
>=
this
->
get_size
()
)
return
-
1
;
if
(
2
*
pos
+
2
>=
this
->
get_size
()
)
return
2
*
pos
+
1
;
return
(
compare_elements
(
2
*
pos
+
1
,
2
*
pos
+
2
)
)
?
2
*
pos
+
1
:
2
*
pos
+
2
;
}
};
}
//namespace structures
#endif
CPP/include/structures/binomial_heap.hpp
0 → 100644
View file @
49cdb06f
#ifndef __BINOMIAL_HEAP_HPP
#define __BINOMIAL_HEAP_HPP
#include
<list>
#include
"binomial_tree.hpp"
#include
"heap.hpp"
namespace
structures
{
template
<
typename
T
>
class
BinomialHeap
:
public
Heap
<
T
>
{
public:
BinomialHeap
()
:
size
(
0
){}
BinomialHeap
(
const
T
&
val
)
:
size
(
0
){
push
(
val
);
}
BinomialHeap
(
std
::
list
<
BinomialTree
<
T
>
>
subTrees
,
size_t
size_p
)
:
trees
(
subTrees
),
size
(
size_p
){}
T
pop
()
{
auto
it
=
trees
.
begin
();
auto
it_min
=
it
;
for
(
it
++
;
it
!=
trees
.
end
();
it
++
){
if
(
it
->
get_value
()
<
it_min
->
get_value
())
it_min
=
it
;
}
T
res
=
it_min
->
get_value
();
int
pop_size
=
(
1
<<
it_min
->
get_rank
())
-
1
;
if
(
pop_size
>
0
){
BinomialHeap
subTrees
(
it_min
->
pop
(),
pop_size
);
trees
.
erase
(
it_min
);
if
(
pop_size
>
0
)
merge
(
subTrees
);
}
else
trees
.
erase
(
it_min
);
size
--
;
return
res
;
}
void
push
(
const
T
&
val
){
if
(
trees
.
empty
())
trees
.
push_front
(
BinomialTree
<
T
>
(
val
));
else
{
BinomialHeap
bh
(
val
);
merge
(
bh
);
}
size
++
;
}
size_t
get_size
(){
return
size
;}
void
merge
(
BinomialHeap
&
bh
){
auto
local_it
=
trees
.
begin
();
auto
retenue
=
trees
.
end
();
size
+=
bh
.
size
;
while
(
local_it
!=
trees
.
end
()
&&
!
bh
.
empty
()){
//Both current trees have the same rank r -> merge into a tree of rank r+1
if
(
bh
.
front
().
get_rank
()
==
local_it
->
get_rank
()
){
if
(
bh
.
front
().
get_value
()
<
local_it
->
get_value
()
)
std
::
iter_swap
(
local_it
,
bh
.
trees
.
begin
());
local_it
->
addSubtree
(
bh
.
front
());
bh
.
trees
.
pop_front
();
retenue
=
local_it
;
local_it
++
;
}
else
{
//Other tree has a lesser rank
if
(
bh
.
front
().
get_rank
()
<
local_it
->
get_rank
()){
if
(
retenue
!=
trees
.
end
()
&&
bh
.
front
().
get_rank
()
==
retenue
->
get_rank
()){
if
(
bh
.
front
().
get_value
()
<
retenue
->
get_value
()
)
std
::
iter_swap
(
retenue
,
bh
.
trees
.
begin
());
retenue
->
addSubtree
(
bh
.
front
());
//Merge it with the retenue
}
else
{
trees
.
emplace
(
local_it
,
bh
.
front
());
//Add it to the list
}
bh
.
trees
.
pop_front
();
}
//Tries to merge tree and retenue
if
(
retenue
!=
trees
.
end
()
&&
retenue
->
get_rank
()
==
local_it
->
get_rank
()){
if
(
retenue
->
get_value
()
<
local_it
->
get_value
()
)
std
::
iter_swap
(
local_it
,
retenue
);
local_it
->
addSubtree
(
*
retenue
);
trees
.
erase
(
retenue
);
retenue
=
trees
.
end
();
local_it
++
;
}
}
}
//Check last merge.
if
(
local_it
!=
trees
.
end
()
&&
retenue
!=
trees
.
end
()){
while
(
local_it
->
get_rank
()
==
retenue
->
get_rank
()){
if
(
retenue
->
get_value
()
<
local_it
->
get_value
()
)
std
::
iter_swap
(
local_it
,
retenue
);
local_it
->
addSubtree
(
*
retenue
);
trees
.
erase
(
retenue
);
retenue
=
local_it
;
local_it
++
;
}
}
if
(
!
bh
.
empty
()){
while
(
retenue
!=
trees
.
end
()
){
if
(
bh
.
front
().
get_value
()
<
retenue
->
get_value
()
)
std
::
iter_swap
(
retenue
,
bh
.
trees
.
begin
());
retenue
->
addSubtree
(
bh
.
front
());
bh
.
trees
.
pop_front
();
}
trees
.
splice
(
trees
.
end
(),
bh
.
trees
);
}
}
friend
std
::
ostream
&
operator
<<
(
std
::
ostream
&
o
,
const
BinomialHeap
<
T
>
&
bh
){
o
<<
"digraph{ "
;
for
(
BinomialTree
<
T
>
tree
:
bh
.
trees
){
o
<<
tree
;
}
o
<<
"}"
;
return
o
;
}
private:
std
::
list
<
BinomialTree
<
T
>
>
trees
;
size_t
size
;
inline
BinomialTree
<
T
>&
front
()
{
return
trees
.
front
();
};
inline
bool
empty
(){
return
trees
.
empty
();
}
};
}
//namespace structures
#endif
CPP/include/structures/binomial_tree.hpp
0 → 100644
View file @
49cdb06f
#ifndef __BINOMIAL_TREE_HPP
#define __BINOMIAL_TREE_HPP
#include
<list>
#include
<queue>
#include
<iostream>
namespace
structures
{
template
<
typename
T
>
class
BinomialTree
{
public:
BinomialTree
(
const
T
&
value_p
){
value
=
value_p
;
}
const
size_t
get_rank
(){
return
subTrees
.
size
();
}
inline
T
get_value
(){
return
value
;
}
std
::
list
<
BinomialTree
<
T
>
>
&
pop
(){
return
subTrees
;
}
void
addSubtree
(
BinomialTree
bt
){
if
(
bt
.
get_rank
()
!=
get_rank
())
throw
new
std
::
runtime_error
(
"Cannot add a binomial tree with a different rank"
);
subTrees
.
push_back
(
bt
);
}
friend
std
::
ostream
&
operator
<<
(
std
::
ostream
&
o
,
const
BinomialTree
<
T
>
&
a
){
std
::
queue
<
BinomialTree
<
T
>
>
nodes
;
BinomialTree
<
T
>
current
=
a
;
int
node
=
(
1
<<
(
a
.
subTrees
.
size
()))
-
1
;
int
node_child
=
node
+
1
;
nodes
.
push
(
a
);
o
<<
node
<<
" [label =
\"
"
<<
current
.
value
<<
"
\"
];"
<<
std
::
endl
;
while
(
!
nodes
.
empty
()){
current
=
nodes
.
front
();
nodes
.
pop
();
for
(
BinomialTree
<
T
>
subTree
:
current
.
subTrees
){
//o<<current.value<<" -> "<<subTree.value<<"; ";
o
<<
node_child
<<
" [label =
\"
"
<<
subTree
.
value
<<
"
\"
];"
;
o
<<
node
<<
" -> "
<<
node_child
++<<
"; "
<<
std
::
endl
;
nodes
.
push
(
subTree
);
}
node
++
;
}
return
o
;
}
private:
std
::
list
<
BinomialTree
<
T
>
>
subTrees
;
T
value
;
};
}
//namespace structures
#endif
CPP/include/structures/bounded_heap.hpp
0 → 100644
View file @
49cdb06f
#ifndef __BOUNDED_HEAP_HPP
#define __BOUNDED_HEAP_HPP
#include
"binary_heap.hpp"
#include
"arraylist.hpp"
namespace
structures
{
template
<
typename
T
>
class
BoundedHeap
:
public
BinaryHeap
<
T
>
{
public:
BoundedHeap
(
const
int
capacity_p
){
capacity
=
capacity_p
;
tree
=
new
T
[
capacity
];
size
=
0
;
swap_counter
=
0
;
}
/**
Throws an axception if pos is out of bound.
*/
T
pop
()
{
swap_counter
=
0
;
if
(
size
==
0
)
throw
new
std
::
runtime_error
(
"Cannot pop an empty heap"
);
T
result
=
tree
[
0
];
swap
(
0
,
size
-
1
);
size
--
;
this
->
down_heap
();
return
result
;
}
void
push
(
const
T
&
val
)
{
swap_counter
=
0
;
if
(
size
==
capacity
)
throw
new
std
::
runtime_error
(
"Cannot push value: heap is full"
);
tree
[
size
++
]
=
val
;
this
->
up_heap
();
}
size_t
get_size
()
{
return
size
;
}
size_t
get_swap_counter
(){
return
swap_counter
;
}
protected:
T
*
tree
;
private:
int
size
;
int
capacity
;
size_t
swap_counter
;
void
swap
(
const
int
pos1
,
const
int
pos2
){
if
(
pos1
<
0
||
pos1
>
size
)
throw
std
::
runtime_error
(
pos1
+
" is out of bound (Heap swap)"
);
if
(
pos2
<
0
||
pos2
>
size
)
throw
std
::
runtime_error
(
pos2
+
" is out of bound (Heap swap)"
);
T
tmp
=
tree
[
pos1
];
tree
[
pos1
]
=
tree
[
pos2
];
tree
[
pos2
]
=
tmp
;
swap_counter
++
;
}
/**
Throws an axception if pos is out of bound.
*/
inline
T
get
(
const
int
pos
){
if
(
pos
<
0
||
pos
>
size
)
throw
std
::
runtime_error
(
pos
+
" is out of bound (Bounded Heap)"
);
return
tree
[
pos
];
}
};
}
//namespace structures
#endif
CPP/include/structures/bounded_max_heap.hpp
0 → 100644
View file @
49cdb06f
#ifndef __BOUNDED_MAX_HEAP_HPP
#define __BOUNDED_MAX_HEAP_HPP
#include
"bounded_heap.hpp"
#include
"arraylist.hpp"
namespace
structures
{
template
<
typename
T
>
class
BoundedMaxHeap
:
public
BoundedHeap
<
T
>
{
public:
BoundedMaxHeap
(
const
int
capacity_p
)
:
BoundedHeap
<
T
>
(
capacity_p
)
{}
private:
bool
compare_elements
(
int
pos1
,
int
pos2
){
return
this
->
tree
[
pos1
]
>
this
->
tree
[
pos2
];
}
};
}
//namespace structures