Skip to content
Snippets Groups Projects
Commit 36a363de authored by david's avatar david
Browse files

suppresion de dossier appartenant aux sujets suivants

parent 2f15768d
No related branches found
No related tags found
No related merge requests found
Pipeline #652 failed
Showing
with 0 additions and 854 deletions
#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
#ifndef __BOUNDED_MIN_HEAP_HPP
#define __BOUNDED_MIN_HEAP_HPP
#include"bounded_heap.hpp"
#include"arraylist.hpp"
namespace structures {
template <typename T>
class BoundedMinHeap: public BoundedHeap<T> {
public:
BoundedMinHeap(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
#ifndef __DYNAMIC_HEAP_HPP
#define __DYNAMIC_HEAP_HPP
#include"binary_heap.hpp"
#include"arraylist.hpp"
namespace structures {
template <typename T>
class DynamicHeap : public BinaryHeap<T> {
public:
/**
Throws an axception if pos is out of bound.
*/
T pop() {
int size = tree.get_size();
if( size == 0 )
throw new std::runtime_error("Cannot pop an empty heap");
T result = tree.get(0);
swap(0, size-1);
tree.pop_back();
this->down_heap();
return result;
}
void push(const T & val) {
tree.append(val);
this->up_heap();
}
size_t get_size() {
return tree.get_size();
}
protected:
ArrayList<T> tree;
private:
void swap(const int pos1,const int pos2){
tree.swap(pos1, pos2);
}
/**
Throws an axception if pos is out of bound.
*/
inline T get(const int pos){
return tree.get(pos);
}
};
}//namespace structures
#endif
#ifndef __DYNAMIC_MAX_HEAP_HPP
#define __DYNAMIC_MAX_HEAP_HPP
#include"dynamic_heap.hpp"
#include"arraylist.hpp"
namespace structures {
template <typename T>
class DynamicMaxHeap: public DynamicHeap<T> {
private:
bool compare_elements(int pos1, int pos2){
return this->tree.get(pos1) > this->tree.get(pos2);
}
};
}//namespace structures
#endif
#ifndef __DYNAMIC_MIN_HEAP_HPP
#define __DYNAMIC_MIN_HEAP_HPP
#include"heap.hpp"
#include"arraylist.hpp"
namespace structures {
/**
Cette classe est un proxy pour les vecteurs, c'est à dire les tableaux dynamiques en C++.
On utilise cette classe afin d'avoir le contrôle sur la gestion de la mémoire.
*/
template <typename T>
class DynamicMinHeap: public DynamicHeap{
private:
bool compare_elements(int pos1, int pos2){
return this->tree.get(pos1) < this->tree.get(pos2);
}
};
}
#endif
#ifndef __HEAP_HPP
#define __HEAP_HPP
namespace structures {
template <typename T>
class Heap{
public:
virtual T pop() = 0;
virtual void push(const T & val) = 0;
virtual size_t get_size() = 0;
};
}//namespace structures
#endif
#ifndef __STACK_HPP
#define __STACK_HPP
#include"arraylist.hpp"
namespace structures {
/**
Cette classe est un proxy pour les vecteurs, c'est à dire les tableaux dynamiques en C++.
On utilise cette classe afin d'avoir le contrôle sur la gestion de la mémoire.
*/
template <typename P>
class Queue : public ArrayList<P> {
public:
Queue(){
top = 0;
}
inline void push(const P & x){
if( this->do_we_need_to_enlarge_capacity() )
this->enlarge_capacity();
this->data[( this->size + top ) % this->capacity] = x;
this->size++;
}
inline P pop(){
if( this->size == 0 )
throw std::runtime_error("Cannot pop an empty queue");
P res = this->data[top];
top = (top + 1) % this->capacity;
this->size--;
if( this->do_we_need_to_reduce_capacity() )
this->reduce_capacity();
return res;
}
private:
int top;
inline void realloc(int new_capacity){
P * tmp = new P[new_capacity];
if( (this->size + top) > this->capacity ){
std::memcpy( tmp, &this->data[top], sizeof(P) * (this->capacity - top) );
std::memcpy( &tmp[this->capacity - top], &this->data[0],
sizeof(P) * (this->size-(this->capacity - top)) );
}
else{
std::memcpy( tmp, &this->data[top], sizeof(P) * this->size );
}
delete [] this->data;
this->data = tmp;
top = 0;
}
};
}// namespace structures
#endif
#ifndef __STACK_HPP
#define __STACK_HPP
#include"arraylist.hpp"
namespace structures {
/**
Cette classe est un proxy pour les vecteurs, c'est à dire les tableaux dynamiques en C++.
On utilise cette classe afin d'avoir le contrôle sur la gestion de la mémoire.
*/
template <typename P>
class Stack : public ArrayList<P> {
public:
inline void push(const P & x){
this->append(x);
}
inline P pop(){
this->pop_back();
return this->data[this->size];
}
};
}// namespace structures
#endif
#include<iostream>
#include <chrono>
#include<cstdlib>
#include "structures/RedBlackTree.hpp"
#include "analysis/analyzer.hpp"
using namespace structures;
using namespace analysis;
using namespace std::chrono;
int main(int argc, char ** argv){
int i;
int max = 3;
// Tas Binaire borné.
RedBlackTree<int> dh;
// Analyse du temps pris par les opérations.
Analyzer time_analysis;
high_resolution_clock::time_point before, after;
for(i = 0; i < max ; i++){
//double rand_value = rand() / (double) RAND_MAX;
double rand_value = 0;
if( dh.get_size() == 0 || rand_value < 0.49 ){
int key = rand()%200;
// Ajout d'un élément et mesure du temps pris par l'opération.
before = high_resolution_clock::now();
dh.insert(key);
after = high_resolution_clock::now();
dh.print();
std::cerr<<"---------------------------"<<std::endl;
}
/*else{
before = high_resolution_clock::now();
dh.pop();
after = high_resolution_clock::now();
}*/
// Enregistrement du temps pris par l'opération
auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(after - before);
time_analysis.append(static_cast<double>(duration.count()));
// Enregistrement du nombre de copies efféctuées par l'opération.
// S'il y a eu réallocation de mémoire, il a fallu recopier tout le tableau.
//swap_analysis.append( dh.get_swap_counter() );
}
// Affichage de quelques statistiques sur l'expérience.
/*std::cerr<<"Total cost :"<<time_analysis.get_total_cost()<<std::endl;
std::cerr<<"Average cost :"<<time_analysis.get_average_cost()<<std::endl;
std::cerr<<"Variance :"<<time_analysis.get_variance()<<std::endl;
std::cerr<<"Standard deviation :"<<time_analysis.get_standard_deviation()<<std::endl;
*/
// Sauvegarde les données de l'expérience.
//time_analysis.save_values("../plots/red_black_tree_rand_time_cpp.plot");
dh.print();
return 0;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment