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; +}