Commit 49cdb06f authored by david's avatar david
Browse files

premier test CI

parent f2518138
image: alpine
stages:
- test
sda:test
script:
- file AUTHORS.md
#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
#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
#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
#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
#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
#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
#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
#endif