Advertisement
Guest User

AVL_Tree

a guest
May 4th, 2016
55
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 16.30 KB | None | 0 0
  1. template <typename T>
  2. struct KeySerializationTrait {
  3.     static std::string Serialize(const T& t) { std::stringstream ss; ss << t; return ss.str(); }
  4.     static T Deserialize(const std::string& str) { T tmp;  std::stringstream(str) >> tmp; return tmp; }
  5. };
  6.  
  7. //////////////////////////////////////////////////////////////////////////
  8.  
  9. template <typename T>
  10. struct FileTypeSerializationTrait
  11. {
  12.     static void Serialize(std::ostream& fileStream, const T& item) { fileStream << item; }
  13.     static T Deserialize(std::istream& fileStream) { T tmp; fileStream >> tmp; return tmp; }
  14. };
  15.  
  16. //////////////////////////////////////////////////////////////////////////
  17.  
  18. template <>
  19. struct FileTypeSerializationTrait <std::string> {
  20.     static void Serialize(std::ostream& fileStream, const std::string& str) {
  21.         fileStream << str;
  22.     }
  23.     static std::string Deserialize(std::istream& fileStream) {
  24.         return std::string((std::istreambuf_iterator<char>(fileStream)), std::istreambuf_iterator<char>());
  25.     };  
  26. };
  27.  
  28. //////////////////////////////////////////////////////////////////////////
  29.  
  30.  
  31. template <class Key, class mapped_type, class Compare = std::less<Key>>
  32. class AVL_Tree
  33. {
  34. private:
  35.     //struktura uzla stromu
  36.     struct Tree_
  37.     {
  38.         Key key;
  39.         std::string* addr;
  40.         unsigned char height;
  41.         Tree_* parent;
  42.         Tree_* left;
  43.         Tree_* right;
  44.         Tree_(Key k, std::string* p) {
  45.             key = k;
  46.             addr = p;
  47.             left = right = parent = 0;
  48.             height = 1;
  49.         }
  50.         //ja mohl bych udelat get a set jako metody AVL_Tree za misto metod Tree_, ale  pro iterator bude jednoduse aby on mel v sobe pouze odkaz na uzel, nez odkaz na celou tridu AVL.
  51.         mapped_type getValue()
  52.         {
  53.             std::string address = createAddres(*addr, KeySerializationTrait<Key>::Serialize(key));
  54.             std::ifstream ifs(address);
  55.             mapped_type tmp = FileTypeSerializationTrait<mapped_type>::Deserialize(ifs);
  56.             ifs.close();
  57.             return tmp;
  58.         }
  59.         void setValue(mapped_type a)
  60.         {
  61.             std::string address = createAddres(*addr, KeySerializationTrait<Key>::Serialize(key));
  62.             std::ofstream ofs(address);
  63.             FileTypeSerializationTrait<mapped_type>::Serialize(ofs, a);
  64.             ofs.close();
  65.         }
  66.         ~Tree_()
  67.         {
  68.  
  69.         }
  70.     };
  71.  
  72.     //nazev slozky
  73.     std::string dirName;
  74.     //ukazatel na root
  75.     Tree_ *root;
  76.     //ukazatel na posledni spracovany uzel
  77.     Tree_ *lastAction;
  78.     //pocet uzlu ve dreve
  79.     int count;
  80.     //Comparator
  81.     Compare comp;
  82.  
  83.  
  84. public:
  85.     //mohl bych udelat iteratory ven, ale v takovem pripade bych musel template delat taky
  86.     class const_iterator;
  87.  
  88.     //iteratory
  89.     class iterator
  90.     {
  91.     public:
  92.         typedef iterator self_type;
  93.         typedef std::pair<Key, mapped_type> value_type;
  94.         typedef value_type& reference;
  95.         typedef value_type* pointer;
  96.         typedef std::forward_iterator_tag iterator_category;
  97.         typedef int difference_type;
  98.         value_type currPair;
  99.         ///konstruktory
  100.         iterator()
  101.         {
  102.             curr = nullptr;
  103.         }
  104.  
  105.         iterator(Tree_ &n)
  106.         {
  107.             curr = &n;
  108.             if (curr)
  109.             {
  110.                 currPair = std::make_pair(curr->key, curr->getValue());
  111.             }
  112.         }
  113.  
  114.         //v mojem priklade iteratoru ne ma smysl delat 100% copy konstruktor, protoze v iteratoru mame ukazatel na uzel dreva. Se kterym potom pracujeme
  115.         //kdy bych to potreboval, mohl bych zakazat kopy konstruktor  `iterator(const self_type& other)=delete`
  116.         iterator(const self_type& other)
  117.         {
  118.             curr = other.curr;
  119.             if (curr)
  120.             {
  121.                 currPair = other.currPair;
  122.             }
  123.         }
  124.  
  125.         //move "rvalue reference" konstruktor
  126.         iterator(self_type&& other)
  127.         {
  128.             curr = other.curr;
  129.             other.curr = nullptr;
  130.             if (curr)
  131.             {
  132.                 currPair = other.currPair;
  133.             }
  134.         }
  135.  
  136.         //klasicky operator assigment , kdy bych to potreboval, mohl bych zakazat assigment  `self_type& operator=(const self_type& other)=delete`
  137.         self_type& operator=(const self_type& other)
  138.         {
  139.             currPair = other.currPair;
  140.             return *this;
  141.         }
  142.  
  143.         //move assigment operator
  144.         self_type& operator=(self_type&& other)
  145.         {
  146.             curr = other.curr;
  147.             currPair = other.currPair;
  148.             return *this;
  149.         }
  150.         ///operatory
  151.         //prefix increment
  152.         self_type& operator++() {
  153.             if (curr)
  154.                 if (currPair.second != curr->getValue())
  155.                     curr->setValue(currPair.second);
  156.             curr = successor(); // point to next node
  157.             if (curr)
  158.                 currPair = std::make_pair(curr->key, curr->getValue());
  159.             return *this;
  160.         }
  161.  
  162.         //postfix increment (it++)
  163.         self_type operator++(int)
  164.         {
  165.             self_type old = *this;
  166.             ++(*this);
  167.             return old;
  168.         }
  169.  
  170.         //reference
  171.         reference operator*() {
  172.             return currPair;
  173.         }
  174.  
  175.         //pointer
  176.         pointer operator->()
  177.         {
  178.             return &currPair;
  179.         }
  180.  
  181.         //testovani podobnosty
  182.         bool operator!=(self_type const & other) const {
  183.             return this->curr != other.curr;
  184.         }
  185.  
  186.         //operator dereference  
  187.         bool operator==(self_type const & other) const {
  188.             return this->curr == other.curr;
  189.         }
  190.  
  191.         //konvertovani do const iteratoru
  192.         operator const_iterator() const { return const_iterator(*curr); }
  193.  
  194.         //kontrola ukazuje li nekam iterator, nebo prazdny
  195.         bool isEmpty()
  196.         {
  197.             if (curr)
  198.                 return false;
  199.             return true;
  200.         }
  201.  
  202.     private:
  203.         //uzel na ktery ukazuuje iterator
  204.         Tree_* curr;
  205.  
  206.         //Successor
  207.         Tree_* successor()
  208.         {
  209.             if (curr)
  210.                 if (curr->right != 0) {
  211.                     curr = curr->right;
  212.                     while (curr->left != 0)
  213.                         curr = curr->left;
  214.                 }
  215.                 else {
  216.                     Tree_* y = curr->parent;
  217.                     if (y == nullptr)
  218.                         return nullptr;
  219.                     while (curr == y->right) {
  220.                         curr = y;
  221.                         y = y->parent;
  222.                         if (y == nullptr)
  223.                             return nullptr;
  224.                     }
  225.                     if (curr->right != y)
  226.                         curr = y;
  227.                 }
  228.                 return curr;
  229.         }
  230.     };
  231.  
  232.     class const_iterator
  233.     {
  234.     public:
  235.         typedef const_iterator self_type;
  236.         typedef std::pair<Key, mapped_type> value_type;
  237.         typedef const value_type& reference;
  238.         typedef const value_type* pointer;
  239.         typedef std::forward_iterator_tag iterator_category;
  240.         typedef int difference_type;
  241.         value_type currPair;
  242.         ///konstruktory
  243.         const_iterator()
  244.         {
  245.             curr = nullptr;
  246.         }
  247.  
  248.         const_iterator(Tree_ &n)
  249.         {
  250.             curr = &n;
  251.             if (curr)
  252.             {
  253.                 currPair = std::make_pair(curr->key, curr->getValue());
  254.             }
  255.         }
  256.  
  257.         //v mojem priklade const_iterator ne ma smysl delat 100% copy konstruktor, protoze v iteratoru mame ukazatel na uzel dreva. Se kterym potom pracujeme
  258.         //kdy bych to potreboval, mohl bych zakazat kopy konstruktor  `const_iterator(const self_type& other)=delete`
  259.         const_iterator(const self_type& other)
  260.         {
  261.             curr = other.curr;
  262.             if (curr)
  263.             {
  264.                 currPair = other.currPair;
  265.             }
  266.         }
  267.  
  268.         //move "rvalue reference" konstruktor
  269.         const_iterator(self_type&& other)
  270.         {
  271.             curr = other.curr;
  272.             other.curr = nullptr;
  273.             if (curr)
  274.             {
  275.                 currPair = other.currPair;
  276.             }
  277.         }
  278.  
  279.         //klasicky operator assigment , kdy bych to potreboval, mohl bych zakazat assigment  `self_type& operator=(const self_type& other)=delete`
  280.         self_type& operator=(const self_type& other)
  281.         {
  282.             currPair = other.currPair;
  283.             retern *this;
  284.         }
  285.  
  286.         //move assigment operator
  287.         self_type& operator=(self_type&& other)
  288.         {
  289.             curr = other.curr;
  290.             currPair = other.currPair;
  291.             return *this;
  292.         }
  293.         ///operatory
  294.         //prefix increment
  295.         self_type& operator++() {
  296.             if (curr)
  297.                 if (currPair.second != curr->getValue())
  298.                     curr->setValue(currPair.second);
  299.             curr = successor(); // point to next node
  300.             if (curr)
  301.                 currPair = std::make_pair(curr->key, curr->getValue());
  302.             return *this;
  303.         }
  304.  
  305.         // postfix increment (it++)
  306.         self_type operator++(int)
  307.         {
  308.             self_type old = *this;
  309.             ++(*this);
  310.             return old;
  311.         }
  312.  
  313.         //reference
  314.         reference operator*() const {
  315.             return currPair;
  316.         }
  317.  
  318.         //pointer
  319.         pointer operator->()
  320.         {
  321.             return &currPair;
  322.         }
  323.         //testovani podobnosty
  324.         bool operator!=(self_type const & other) const {
  325.             return this->curr != other.curr;
  326.         }
  327.  
  328.         //operator dereference  
  329.         bool operator==(self_type const & other) const {
  330.             return this->curr == other.curr;
  331.         }
  332.  
  333.         //konvertovani do iteratoru
  334.         operator iterator() const { return iterator(*curr); }
  335.  
  336.         //kontrola ukazuje li nekam iterator, nebo prazdny
  337.         bool isEmpty()
  338.         {
  339.             if (curr)
  340.                 return false;
  341.             return true;
  342.         }
  343.  
  344.     private:
  345.         //uzel na ktery ukazuuje iterator
  346.         Tree_* curr;
  347.  
  348.         //Successor
  349.         Tree_* successor()
  350.         {
  351.             if (curr)
  352.                 if (curr->right != 0) {
  353.                     curr = curr->right;
  354.                     while (curr->left != 0)
  355.                         curr = curr->left;
  356.                 }
  357.                 else {
  358.                     Tree_* y = curr->parent;
  359.                     if (y == nullptr)
  360.                         return nullptr;
  361.                     while (curr == y->right) {
  362.                         curr = y;
  363.                         y = y->parent;
  364.                         if (y == nullptr)
  365.                             return nullptr;
  366.                     }
  367.                     if (curr->right != y)
  368.                         curr = y;
  369.                 }
  370.                 return curr;
  371.         }
  372.     };
  373.  
  374.     //konstruktory & destruktor
  375.     AVL_Tree() :root(nullptr), count(0), dirName("") {};
  376.  
  377.     AVL_Tree(std::string dir)
  378.     {
  379.         root = lastAction = nullptr;
  380.         dirName = dir;
  381.         count = 0;
  382.         path p(dirName);
  383.         std::string stringKey;
  384.         if (fs::exists(p))
  385.             for (auto tmp : fs::directory_iterator(p)) {
  386.                 if (fs::is_regular_file(tmp)) {
  387.                     stringKey = tmp.path().filename().string();
  388.                     Key key = KeySerializationTrait<Key>::Deserialize(stringKey);
  389.                     mapped_type value = getValue(stringKey);
  390.                     insert(std::make_pair(key, value));
  391.                 }
  392.             }
  393.     }
  394.  
  395.     AVL_Tree(AVL_Tree const &oth) {
  396.         if (this != &oth) {
  397.             this->dirName = oth.dirName;
  398.             this->count = oth.count;
  399.             this->root = oth.root;
  400.             this->lastAction = oth.lastAction;
  401.         }
  402.     }
  403.  
  404.     ~AVL_Tree()
  405.     {
  406.         eraseTree(root);
  407.         lastAction = root = nullptr;
  408.     }
  409.  
  410.  
  411.     //orerator assigment
  412.     AVL_Tree<Key, mapped_type, Compare>& operator=(const AVL_Tree<Key, mapped_type, Compare> &oth) {
  413.         if (this != &oth) {
  414.             this->dirName = oth.dirName;
  415.             this->count = oth.count;
  416.             this->root = oth.root;
  417.             this->lastAction = oth.lastAction;
  418.         }
  419.         return this;
  420.     }
  421.  
  422.  
  423.     //iteratory
  424.     iterator begin()
  425.     {
  426.         if (count)
  427.         {
  428.             return iterator(*findMin());
  429.         }
  430.         return iterator();
  431.     }
  432.  
  433.     iterator end()
  434.     {
  435.         iterator it(*findMax());
  436.         if (!it.isEmpty())
  437.             it++;
  438.         return it;
  439.     }
  440.  
  441.     const_iterator cbegin()
  442.     {
  443.  
  444.         if (count)
  445.         {
  446.             return const_iterator(*findMin());
  447.         }
  448.         return const_iterator();
  449.     }
  450.  
  451.     const_iterator cend()
  452.     {
  453.         const_iterator it(*findMax());
  454.         if (!it.isEmpty())
  455.             it++;
  456.         return it;
  457.     }
  458.  
  459.     //gety
  460.     std::string getDirName()
  461.     {
  462.         return dirName;
  463.     }
  464.  
  465.     int getCount() {
  466.         return count;
  467.     }
  468.  
  469.     //metody
  470.     Tree_& insert(std::pair<Key, mapped_type>  const & k) // вставка ключа k в дерево с корнем p
  471.     {
  472.         root = insert(root, k);
  473.         return *lastAction;
  474.     }
  475.  
  476.     Tree_* findMin() // поиск узла с минимальным ключом в дереве p
  477.     {
  478.         if (root)
  479.             return root->left ? findMin(root->left) : root;
  480.         else return 0;
  481.     }
  482.  
  483.     Tree_* erase(Key const & k) // удаление ключа k из дерева p
  484.     {
  485.         Tree_* min;
  486.         if (!root) return 0;
  487.         if (comp(k, root->key))
  488.             root->left = erase(root->left, k);
  489.         else if (comp(root->key, k))
  490.             root->right = erase(root->right, k);
  491.         else //  k == p->key
  492.         {
  493.             Tree_* q = root->left;
  494.             Tree_* r = root->right;
  495.             if (r == 0)
  496.             {
  497.                 removeAddr(dirName, root->key);
  498.                 delete root;
  499.                 count--;
  500.                 lastAction = nullptr;
  501.                 return root = 0;
  502.             }
  503.             min = findMin(r);
  504.             min->right = eraseMin(r);
  505.             min->left = q;
  506.             min->parent = 0;
  507.             removeAddr(dirName, root->key);
  508.             delete root;
  509.             setParents(min, 0);
  510.             root = balance(min);
  511.             count--;
  512.             return root;
  513.         }
  514.         root = balance(root);
  515.         return root;
  516.     }
  517.  
  518.     Tree_* findKey(Key const & k)
  519.     {
  520.         Tree_ *p = root;
  521.         while (p)
  522.         {
  523.             bool b = (!comp(k, p->key) && !comp(p->key, k));
  524.             if (b)
  525.                 return p;
  526.             if (comp(k, p->key))
  527.                 p = p->left;
  528.             else
  529.                 p = p->right;
  530.         }
  531.         return nullptr;
  532.     }
  533.  
  534.     Tree_* findMax()
  535.     {
  536.         Tree_ *p = root;
  537.         if (p)
  538.             while (p->right != nullptr)
  539.                 p = p->right;
  540.         return p;
  541.     }
  542.  
  543. private:
  544.     //vrati string s addresou slozky+/+filename
  545.     static std::string createAddres(std::string a, std::string b)
  546.     {
  547.         std::string address(a);
  548.         address.append("/");
  549.         address.append(b);
  550.         return address;
  551.     }
  552.  
  553.     //maze soubor podle adressy slozky a filename, ktery tady klic
  554.     static void removeAddr(std::string addr, Key k)
  555.     {
  556.         std::string address = createAddres(addr, KeySerializationTrait<Key>::Serialize(k));
  557.         fs::remove(address);
  558.     }
  559.  
  560.     //vrati height
  561.     unsigned char height(Tree_* p)
  562.     {
  563.         return p ? p->height : 0;
  564.     }
  565.  
  566.     //spocita a vrati b faktor
  567.     int bFactor(Tree_* p)
  568.     {
  569.         return height(p->right) - height(p->left);
  570.     }
  571.  
  572.     //upravi height
  573.     void fixHeight(Tree_* p)
  574.     {
  575.         unsigned char hl = height(p->left);
  576.         unsigned char hr = height(p->right);
  577.         p->height = (hl > hr ? hl : hr) + 1;
  578.     }
  579.  
  580.     //hastaveni rodicu
  581.     void setParents(Tree_* p, Tree_* q)
  582.     {
  583.         if (q)
  584.         {
  585.             q->parent = p->parent;
  586.             p->parent = q;
  587.         }
  588.         if (p->left != nullptr)
  589.             (p->left)->parent = p;
  590.         if (p->right != nullptr)
  591.             (p->right)->parent = p;
  592.     }
  593.  
  594.     //R rotace
  595.     Tree_* rotateRight(Tree_* p) // правый поворот вокруг p
  596.     {
  597.         Tree_* q = p->left;
  598.         p->left = q->right;
  599.         q->right = p;
  600.         setParents(p, q);
  601.         fixHeight(p);
  602.         fixHeight(q);
  603.         return q;
  604.     }
  605.  
  606.     //L rotace
  607.     Tree_* rotateLeft(Tree_* q) // левый поворот вокруг q
  608.     {
  609.         Tree_* p = q->right;
  610.         q->right = p->left;
  611.         p->left = q;
  612.         setParents(q, p);
  613.         fixHeight(q);
  614.         fixHeight(p);
  615.         return p;
  616.     }
  617.  
  618.     //balansovani stromu
  619.     Tree_* balance(Tree_* p) // балансировка узла p
  620.     {
  621.         fixHeight(p);
  622.         if (bFactor(p) == 2)
  623.         {
  624.             if (bFactor(p->right) < 0)
  625.                 p->right = rotateRight(p->right);
  626.             return rotateLeft(p);
  627.         }
  628.         if (bFactor(p) == -2)
  629.         {
  630.             if (bFactor(p->left) > 0)
  631.                 p->left = rotateLeft(p->left);
  632.             return rotateRight(p);
  633.         }
  634.         return p; // балансировка не нужна
  635.     }
  636.  
  637.     //privava do podstromu p , pair k
  638.     Tree_* insert(Tree_*const & p, std::pair<Key, mapped_type> k) // вставка ключа k в дерево с корнем p
  639.     {
  640.         if (!p)
  641.         {
  642.             lastAction = new Tree_(k.first, &dirName);
  643.             lastAction->setValue(k.second);
  644.             count++;
  645.             return lastAction;
  646.         }
  647.         if (comp(k.first, p->key))
  648.         {
  649.             p->left = insert(p->left, k);
  650.             (p->left)->parent = p;
  651.         }
  652.         else
  653.         {
  654.             if (!(!comp(k.first, p->key) && !comp(p->key, k.first)))
  655.             {
  656.                 p->right = insert(p->right, k);
  657.                 (p->right)->parent = p;
  658.             }
  659.             else//klic uz existoval
  660.             {
  661.                 lastAction = p;
  662.                 lastAction->setValue(k.second);
  663.                 return lastAction;
  664.             }
  665.         }
  666.         return balance(p);
  667.     }
  668.  
  669.     //rekurzivne chleda minimalni key ve podstrome p
  670.     Tree_* findMin(Tree_*const & p) // поиск узла с минимальным ключом в дереве p
  671.     {
  672.         return p->left ? findMin(p->left) : p;
  673.     }
  674.  
  675.     //rekurzivne hleda a mahe k d podstrome p
  676.     Tree_* erase(Tree_*const & p, Key k) // удаление ключа k из дерева p
  677.     {
  678.         if (!p) return 0;
  679.         if (comp(k, p->key))
  680.             p->left = erase(p->left, k);
  681.         else if (comp(p->key, k))
  682.         {
  683.             p->right = erase(p->right, k);
  684.         }
  685.         else //  k == p->key
  686.         {
  687.             Tree_* q = p->left;
  688.             Tree_* r = p->right;
  689.             if (!r)
  690.             {
  691.                 if (q)
  692.                 {
  693.                     q->parent = p->parent;
  694.                 }
  695.                 removeAddr(dirName, p->key);
  696.                 delete p;
  697.                 count--;
  698.                 return q;
  699.             }
  700.             Tree_* min = findMin(r);
  701.             min->right = eraseMin(r);
  702.             min->left = q;
  703.             min->parent = p->parent;
  704.             setParents(min, 0);
  705.             count--;
  706.             removeAddr(dirName, p->key);
  707.             delete p;
  708.             return balance(min);
  709.         }
  710.         return balance(p);
  711.     }
  712.  
  713.     //rekurzivne chleda minimalni key ve podstrome p a maze ho
  714.     Tree_* eraseMin(Tree_* p) // удаление узла с минимальным ключом из дерева p
  715.     {
  716.         if (p->left == 0)
  717.             return p->right;
  718.         p->left = eraseMin(p->left);
  719.         return balance(p);
  720.     }
  721.  
  722.     //rekurzivne maze cele drevo
  723.     void eraseTree(Tree_* a) {
  724.         if (0 == a) return;
  725.         eraseTree(a->left);
  726.         eraseTree(a->right);
  727.         delete a;
  728.         count--;
  729.     }
  730.  
  731.     //vraci , je li takovy klic ve stromu nebo ne
  732.     bool keyExist(Tree_* p, Key k)
  733.     {
  734.         while (p) {
  735.             if (!p)
  736.             {
  737.                 return false;
  738.             }
  739.             if (p->key == k)
  740.             {
  741.                 return true;
  742.             }
  743.             if (k < p->key)
  744.                 p = p->left;
  745.             else
  746.                 p = p->right;
  747.         }
  748.     }
  749.  
  750.     //vrace value z souboru k
  751.     mapped_type getValue(std::string key)
  752.     {
  753.         std::string address = createAddres(dirName, key);
  754.         std::ifstream ifs(address);
  755.         mapped_type tmp = FileTypeSerializationTrait<mapped_type>::Deserialize(ifs);
  756.         ifs.close();
  757.         return tmp;
  758.     }
  759. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement