diff --git a/src/binary_heap.hpp b/src/binary_heap.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..e62e974517e1d129ab1a05c1cf82b01453c67684
--- /dev/null
+++ b/src/binary_heap.hpp
@@ -0,0 +1,114 @@
+#ifndef __BINARY_HEAP_HPP__
+#define __BINARY_HEAP_HPP__
+#include<iostream>
+#include <exception>
+
+class FullBinaryHeapException: public std::exception{
+  virtual const char* what() const throw()
+  {
+    return "Cannot add value in a full Heap";
+  }
+};
+
+
+
+template <typename T>
+class BinaryHeap{
+private:
+  T * data;
+  size_t size;
+  size_t max;
+  size_t counter_swap_up;
+  size_t counter_swap_down;
+
+protected:
+  virtual bool heap_cmp(T & value1, T & value2) = 0;
+  
+public:
+  BinaryHeap(size_t max){
+    this->max = max;
+    this->size = 0;
+    this->data = new T[max];
+    counter_swap_up = 0;
+    counter_swap_down = 0;
+  }
+
+  ~BinaryHeap(){
+    delete this->data;
+  }
+
+  bool isEmpty(){
+    return size == 0;
+  }
+
+  size_t getSize(){
+    return this->size;
+  }
+
+  void resetCounters(){
+    counter_swap_up = 0;
+    counter_swap_down = 0;
+  }
+
+  size_t getSwapsCounters(){
+    return counter_swap_down + counter_swap_up;
+  }
+
+  inline int parent(int position){
+    return (position-1)/2;
+  }
+
+  inline int left_child(int position){
+    return position*2+1;
+  }
+
+  inline int right_child(int position){
+    return position*2+2;
+  }
+  
+  void heapify_up(int position){
+    while(position > 0 && heap_cmp(data[position], data[parent(position)])){
+      std::swap(data[parent(position)], data[position]);
+      counter_swap_up++;
+      position = parent(position);
+    }
+  }
+
+  void heapify_down(int position){
+    int min_child;
+    min_child = heap_cmp(data[left_child(position)], data[right_child(position)])? left_child(position): right_child(position);
+    while(min_child < (size-1) && heap_cmp(data[min_child], data[position])){
+      std::swap(data[min_child], data[position]);
+      position = min_child;
+      min_child = heap_cmp(data[left_child(position)],data[right_child(position)])? left_child(position): right_child(position);
+      counter_swap_down++;
+    }
+  }
+  
+  void insert(T value) {
+    if(size == max)
+      throw new FullBinaryHeapException();
+    data[size++] = value;
+    heapify_up(size-1);
+  }
+
+  T extract(){
+    std::swap(data[0], data[size-1]);
+    heapify_down(0);
+    return data[--size];
+  }
+
+  friend std::ostream& operator<<(std::ostream& os, const BinaryHeap<int>& heap);
+  
+};
+
+std::ostream& operator<<(std::ostream& os, const BinaryHeap<int>& heap)
+{
+  for( int i = 0; i < heap.size; i++)
+    os<<heap.data[i]<<" ";
+  os<<std::endl;
+  return os;
+}
+
+
+#endif
diff --git a/src/max_binary_heap.hpp b/src/max_binary_heap.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..e8852a9919460e30dad3243d2443093e04167e6d
--- /dev/null
+++ b/src/max_binary_heap.hpp
@@ -0,0 +1,20 @@
+#ifndef __MAX_BINARY_HEAP_HPP__
+#define __MAX_BINARY_HEAP_HPP__
+#include<iostream>
+
+#include"binary_heap.hpp"
+
+template <typename T>
+class MaxBinaryHeap: public BinaryHeap<T>{
+protected:
+  bool heap_cmp(T & value1, T & value2){
+    return value1 > value2;
+  }
+
+public:
+  MaxBinaryHeap(size_t max): BinaryHeap<T>(max){}
+  
+};
+
+
+#endif
diff --git a/src/min_binary_heap.hpp b/src/min_binary_heap.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..db3a3661903568cc3c8c40f8d06b5a9892693d62
--- /dev/null
+++ b/src/min_binary_heap.hpp
@@ -0,0 +1,20 @@
+#ifndef __MIN_BINARY_HEAP_HPP__
+#define __MIN_BINARY_HEAP_HPP__
+#include<iostream>
+
+#include"binary_heap.hpp"
+
+template <typename T>
+class MinBinaryHeap: public BinaryHeap<T>{
+protected:
+  bool heap_cmp(T & value1, T & value2){
+    return value1 < value2;
+  }
+
+public:
+  MinBinaryHeap(size_t max): BinaryHeap<T>(max){}
+  
+};
+
+
+#endif
diff --git a/src/test b/src/test
new file mode 100755
index 0000000000000000000000000000000000000000..0d6511c33bfabebdbfdafdf8862923c4b02c4de6
Binary files /dev/null and b/src/test differ
diff --git a/src/test.cpp b/src/test.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..374d02a83280a204b5df8c16c5c2ddec9ee6fe86
--- /dev/null
+++ b/src/test.cpp
@@ -0,0 +1,52 @@
+#include<iostream>
+#include"min_binary_heap.hpp"
+
+
+MinBinaryHeap<int> * initialize_heap(size_t size){
+  static MinBinaryHeap<int> * mbh = NULL;
+  if(mbh == NULL)
+    mbh = new MinBinaryHeap<int>(size);
+  else if(mbh->getSize() < size){
+    delete mbh;
+    mbh = new MinBinaryHeap<int>(size);
+  }    
+  return mbh;
+}
+
+size_t heap_sort(int * permutation, size_t size){
+  int i;
+  MinBinaryHeap<int> * mbh = initialize_heap(size);
+  mbh->resetCounters();
+  for(i = 0; i < size; i++)
+    mbh->insert(permutation[i]);
+  for(i = 0; i < size; i++)
+    permutation[i] = mbh->extract();
+  return mbh->getSwapsCounters();
+}
+
+
+
+void random_permutation(int * permutation, size_t size){
+  int i;
+  for(i = 0; i < size; i++)
+    permutation[i] = i;
+  for(i = 0; i < size; i++)
+    std::swap(permutation[i], permutation[i+rand()%(size-i)]);  
+}
+
+int main(int argc, char ** argv){
+  int permutation[1024];
+  int size, xp;
+  int xp_num = 1000;
+  double mean;
+  
+  for(size = 4; size <= 1024; size = 2*size){
+    mean= 0;
+    for(xp = 0; xp < xp_num; xp++){
+      random_permutation(permutation, size);
+      mean +=heap_sort(permutation, size);
+    }
+    printf("%d %lf\n", size, mean/xp_num);
+  }
+  return EXIT_SUCCESS;
+}