Advertisement
Guest User

Untitled

a guest
May 18th, 2015
304
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.54 KB | None | 0 0
  1. /*
  2.  * Created by on 28.04.2015.
  3.  * ADS SoSe 2015
  4.  * Thema: LinearHashing mit Shell Sort
  5. */
  6.  
  7.  
  8. #ifndef LINEARHASHING_H
  9. #define LINEARHASHING_H
  10.  
  11. #include <iostream>
  12. #include "Container.h"
  13. #include <math.h>
  14. #include <cmath>
  15.  
  16. enum status { leer,besetzt };
  17.  
  18. class LinHashException : public ContainerException {
  19. public:
  20.     virtual const char * what() const noexcept override { return "LinearHashing: empty"; }
  21. };
  22. class LinHashNotImplemented: public ContainerException{
  23. public:
  24.     virtual const char * what() const noexcept override{
  25.         return "LinearHashing: Function not implemented\n";
  26.     }
  27. };
  28.  
  29. template <typename E, size_t N=7>
  30. class LinearHashing : public Container<E> {
  31.     size_t nmax;
  32.     size_t n;
  33.     size_t d;
  34.     size_t nts;
  35.  
  36.     void sort() const;
  37.     struct OverflowContainer{
  38.         E* overflowbucket = new E[N/2]();
  39.         status overflowstatus[N/2] = {leer};
  40.         OverflowContainer* nextOverflow = nullptr;
  41.         ~OverflowContainer(){
  42.             if(nextOverflow)
  43.                 delete nextOverflow;
  44.         }
  45.     };
  46.     struct Bucket{
  47.         E* bucketElem = new E[N]();
  48.         status bucketstatus[N] = {leer};
  49.         OverflowContainer* newoverflow = nullptr;
  50.     };
  51.     Bucket* table;
  52. public:
  53.     LinearHashing() : nmax{N}, n{1}, d{0}, nts{0} {
  54.         table = new Bucket[n];
  55.     }
  56.     LinearHashing(std::initializer_list<E> el) : LinearHashing() { for (auto e: el) add(e); }
  57.  
  58.     virtual ~LinearHashing() {
  59.         for(size_t i = 0; i < n; ++i){
  60.             if(table[i].newoverflow != nullptr)
  61.                 destructOverflow(i);
  62.         }
  63.         delete[] table;
  64.     }
  65.  
  66.     using Container<E>::add;
  67.     virtual void add(const E e[], size_t len) override;
  68.  
  69.     using Container<E>::remove;
  70.     virtual void remove(const E e[], size_t len) override;
  71.  
  72.     virtual bool member(const E& e) const override;
  73.     virtual size_t size() const override {
  74.         return n;
  75.     }
  76.  
  77.     virtual E min() const override;
  78.     virtual E max() const override;
  79.  
  80.     virtual std::ostream& print(std::ostream& o) const override;
  81.  
  82.     virtual size_t apply(std::function<void(const E&)> f, Order order = dontcare) const override;
  83.     virtual void destructOverflow(int);
  84.     virtual void split();
  85.     virtual inline size_t compIndex(E);
  86.     virtual inline size_t compReIndex(E);
  87.     virtual inline  void addToOverflow(E, OverflowContainer*);
  88.     virtual void reHash(size_t);
  89.     virtual void reHashOverflow(OverflowContainer*);
  90. };
  91.  
  92. template <typename E, size_t N>
  93. void LinearHashing<E,N>::add(const E e[], size_t len) {
  94.     for(size_t i=0; i < len; ++i){
  95.         size_t address = compIndex(e[i]);
  96.         for(size_t j=0; j < N; ++j){
  97.             if(table[address].bucketstatus[j] == leer){
  98.                 table[address].bucketElem[j] = e[i];
  99.                 table[address].bucketstatus[j] = besetzt;
  100.                 break;
  101.             }else if(j == (N-1) && table[address].newoverflow == nullptr){
  102.                 table[address].newoverflow = new OverflowContainer();
  103.                 addToOverflow(e[i],table[address].newoverflow);
  104.                 split();
  105.                 reHash(nts);
  106.                 if(nts+1 == (pow(2, d))){
  107.                     nts=0;
  108.                     ++d;
  109.                 }else{
  110.                     ++nts;
  111.                 }
  112.             }else if(j == (N-1) && table[address].newoverflow != nullptr){
  113.                 addToOverflow(e[i],table[address].newoverflow);
  114.             }
  115.         }
  116.     }
  117. }
  118.  
  119. template <typename E, size_t N>
  120. void LinearHashing<E,N>::split(){
  121.     Bucket* tmp = new Bucket[size()+1];
  122.     std::copy(table,table+size(),tmp);
  123.     delete[] table;
  124.     table = tmp;
  125.     ++n;
  126. }
  127.  
  128. template <typename E, size_t N>
  129. void LinearHashing<E,N>::remove(const E e[], size_t len) {
  130.     throw LinHashNotImplemented();
  131. }
  132.  
  133. template <typename E, size_t N>
  134. bool LinearHashing<E,N>::member(const E& e) const {
  135.     return false;
  136. }
  137.  
  138. template <typename E, size_t N>
  139. E LinearHashing<E,N>::min() const {
  140.     if (this->empty()) throw LinHashException();
  141.     E rc = 0;
  142.     return rc;
  143. }
  144.  
  145. template <typename E, size_t N>
  146. E LinearHashing<E,N>::max() const {
  147.     if (this->empty()) throw LinHashException();
  148.     E rc = 0;
  149.     return rc;
  150. }
  151.  
  152. template <typename E, size_t N>
  153. std::ostream& LinearHashing<E,N>::print(std::ostream& o) const {
  154.     o << "LinearHashing [ TableSize=" << n << " BucketSize=" << N << " d=" << d << " nextToSplit=" << nts << " ]\nElemente \nvalues=\n";
  155.     for (size_t i = 0; i < n; ++i) {
  156.         o << "Bucket[" << i << "]" << '\n';
  157.         for (size_t j = 0; j < N; ++j) {
  158.             o << " [" << table[i].bucketElem[j] << "] ";
  159.         }
  160.         o << '\n';
  161.         if (table[i].newoverflow != nullptr) {
  162.             o << "Overflow Bucket:\n";
  163.             OverflowContainer *tmp = table[i].newoverflow;
  164.             while (tmp) {
  165.                 for (int k = 0; k < (N / 2); ++k) {
  166.                     o << " [" << tmp->overflowbucket[k] << "] ";
  167.                 }
  168.                 tmp = tmp->nextOverflow;
  169.                 o << '\n';
  170.             }
  171.         }
  172.     }
  173.     return o;
  174. }
  175.  
  176. template <typename E, size_t N>
  177. size_t LinearHashing<E,N>::apply(std::function<void(const E&)> f, Order order) const {
  178.     size_t rc = 0;
  179.     return rc;
  180. }
  181.  
  182. template <typename E, size_t N>
  183. void LinearHashing<E,N>::sort() const { // Achtung, O(n*n)
  184.     /*
  185.     for (size_t i = 0; i < n; ++i) {
  186.         size_t min = i;
  187.         for (size_t j = i+1; j < n; ++j)
  188.             if (Bucket::bucketElem[min] > Bucket::bucketElem[j]) min = j;
  189.         std::swap(Bucket::bucketElem[min], Bucket::bucketElem[i]);
  190.  
  191.     }*/
  192.     throw LinHashNotImplemented();
  193. }
  194.  
  195. template  <typename E, size_t N>
  196. void LinearHashing<E, N>::destructOverflow(int index) {
  197.     OverflowContainer* tmp = table[index].newoverflow;
  198.     delete tmp;
  199.     table[index].newoverflow = nullptr;
  200. }
  201.  
  202. template <typename E, size_t N>
  203. inline size_t LinearHashing<E, N>::compIndex(E e){
  204.     size_t adrOP = powl(2,d);
  205.     return hashValue(e) % adrOP;
  206. }
  207.  
  208. template <typename E, size_t N>
  209. size_t LinearHashing<E, N>::compReIndex(E e) {
  210.     size_t adrOP = powl(2,d+1);
  211.     return hashValue(e) % adrOP;
  212. }
  213.  
  214. template <typename E, size_t N>
  215. void LinearHashing<E, N>::addToOverflow(E e, LinearHashing::OverflowContainer *container) {
  216.     size_t i=0;
  217.     while( i < N/2){
  218.         if(container->overflowstatus[i] == leer){
  219.             container->overflowbucket[i] = e;
  220.             container->overflowstatus[i] = besetzt;
  221.             break;
  222.         }else if(i == (N/2)-1 && container->nextOverflow == nullptr){
  223.             container->nextOverflow = new OverflowContainer();
  224.             container = container->nextOverflow;
  225.             split();
  226.             reHash(nts);
  227.             if(nts+1 == (pow(2, d))){
  228.                 nts=0;
  229.                 ++d;
  230.             }else{
  231.                 ++nts;
  232.             }
  233.             i=0;
  234.         }else if(i == (N/2)-1 && container->nextOverflow != nullptr){
  235.             container = container->nextOverflow;
  236.             i=0;
  237.         }else{
  238.             ++i;
  239.         }
  240.     }
  241. }
  242. template <typename E, size_t N>
  243. void LinearHashing<E, N>::reHash(size_t index){
  244.     bool reHashed = false;
  245.     for(size_t i = 0; i < N; ++i){
  246.         if(compIndex(table[index].bucketElem[i]) != compReIndex(table[index].bucketElem[i]) && table[index].bucketstatus[i] == besetzt){
  247.             for (size_t j = 0; j < N && !reHashed ; ++j) {
  248.                 if(table[n-1].bucketstatus[j] == leer){
  249.                     table[n-1].bucketElem[j] = table[index].bucketElem[i];
  250.                     table[n-1].bucketstatus[j] = besetzt;
  251.                     table[index].bucketstatus[i] = leer;
  252.                     table[index].bucketElem[i] = 0;
  253.                     reHashed = true;
  254.                 }
  255.             }
  256.             reHashed = false;
  257.         }
  258.     }
  259.     if(table[index].newoverflow != nullptr){
  260.         reHashOverflow(table[index].newoverflow);
  261.     }
  262. }
  263. template <typename E, size_t N>
  264. void LinearHashing<E, N>::reHashOverflow(OverflowContainer* container) {
  265.     size_t i=0;
  266.     bool reHashed = false;
  267.     while(i < (N/2)){
  268.         if(compIndex(container->overflowbucket[i]) != compReIndex(container->overflowbucket[i]) && container->overflowstatus[i] == besetzt){
  269.             for(size_t j=0; j < N && !reHashed; ++j){
  270.                 if(table[n-1].bucketstatus[j] == leer){
  271.                     table[n-1].bucketElem[j] = container->overflowbucket[i];
  272.                     table[n-1].bucketstatus[j] = besetzt;
  273.                     container->overflowbucket[i] = 0;
  274.                     container->overflowstatus[i] = leer;
  275.                     reHashed = true;
  276.                 }else if(j == N-1 && table[n-1].newoverflow == nullptr){
  277.                     table[n-1].newoverflow = new OverflowContainer();
  278.                     addToOverflow(container->overflowbucket[i],table[n-1].newoverflow);
  279.                     container->overflowbucket[i] = 0;
  280.                     container->overflowstatus[i] = leer;
  281.                     reHashed = true;
  282.                 }else if(j == N-1 && table[n-1].newoverflow != nullptr){
  283.                     addToOverflow(container->overflowbucket[i], table[n-1].newoverflow);
  284.                     container->overflowbucket[i] = 0;
  285.                     container->overflowstatus[i] = leer;
  286.                     reHashed = true;
  287.                 }
  288.             }
  289.             reHashed = false;
  290.             ++i;
  291.         }else{
  292.             ++i;
  293.         }
  294.         if(container->nextOverflow){
  295.             container = container->nextOverflow;
  296.             i = 0;
  297.         }
  298.     }
  299. }
  300. #endif //LINEARHASHING_H
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement