Advertisement
Fiskmans

Untitled

Mar 18th, 2019
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.25 KB | None | 0 0
  1. #pragma once
  2. #include <string>
  3.  
  4. #include <math.h>
  5.  
  6. #define GREATER(a,b) (b < a)
  7. #define SMALLER(a,b) (a < b)
  8. #define EQUAL(a,b) !GREATER(a,b) && !SMALLER(a,b)
  9.  
  10.  
  11. namespace CommonUtilities
  12. {
  13.     template <class T>
  14.     class BinaryTree
  15.     {
  16.         struct Node
  17.         {
  18.             T myData;
  19.             Node* myMin;
  20.             Node* myMax;
  21.  
  22.             Node(const T& aValues);
  23.  
  24.             Node* operator+();
  25.             Node* operator-();
  26.             T& operator*();
  27.  
  28.             bool operator<(Node& aNode);
  29.  
  30.             Node* Find(const T& aVal, Node*& aParent);
  31.             void Insert(Node* aNode);
  32.  
  33.             Node* RotateAllRight();
  34.  
  35.             Node* RotateRight();
  36.  
  37.             void VineToTree();
  38.  
  39.             void Compress(size_t aCount);
  40.  
  41.             size_t Count();
  42.  
  43.             void Delete();
  44.  
  45.             void BuildString(std::string& aString, int aDepth);
  46.  
  47.         };
  48.  
  49.     public:
  50.         BinaryTree();
  51.         ~BinaryTree();
  52.  
  53.         //Returnerar true om elementet finns i mängden, och false annars.
  54.         bool HasElement(const T& aValue) const;
  55.  
  56.         //Stoppar in elementet i mängden, om det inte redan finns där. Gör
  57.         //ingenting annars.
  58.         void Insert(const T& aValue);
  59.  
  60.         //Plockar bort elementet ur mängden, om det finns. Gör ingenting annars.
  61.         void Remove(const T& aValue);
  62.  
  63.         void DSWBalance();
  64.         void BuildString(std::string& aString);
  65.  
  66.     private:
  67.         Node* myRoot;
  68.     };
  69.  
  70.     template<class T>
  71.     inline BinaryTree<T>::Node::Node(const T & aValues)
  72.     {
  73.         myMax = nullptr;
  74.         myMin = nullptr;
  75.         myData = aValues;
  76.     }
  77.  
  78.     template<class T>
  79.     inline typename BinaryTree<T>::Node * BinaryTree<T>::Node::operator+()
  80.     {
  81.         if (myMax)
  82.         {
  83.             return +myMax;
  84.         }
  85.         return this;
  86.     }
  87.  
  88.     template<class T>
  89.     inline typename BinaryTree<T>::Node * BinaryTree<T>::Node::operator-()
  90.     {
  91.         if (myMin)
  92.         {
  93.             return -myMin;
  94.         }
  95.         return this;
  96.     }
  97.  
  98.     template<class T>
  99.     inline T & BinaryTree<T>::Node::operator*()
  100.     {
  101.         return myData;
  102.     }
  103.  
  104.     template<class T>
  105.     inline bool BinaryTree<T>::Node::operator<(Node & aNode)
  106.     {
  107.         return SMALLER(myData, aNode.myData);
  108.     }
  109.  
  110.     template<class T>
  111.     inline typename BinaryTree<T>::Node * BinaryTree<T>::Node::Find(const T & aVal, Node*& aParent)
  112.     {
  113.         if (!this || EQUAL(aVal, myData))
  114.         {
  115.             return this;
  116.         }
  117.  
  118.         aParent = this;
  119.  
  120.         if (GREATER(aVal, myData))
  121.         {
  122.             return myMax->Find(aVal, aParent);
  123.         }
  124.  
  125.         if (SMALLER(aVal, myData))
  126.         {
  127.             return myMin->Find(aVal, aParent);
  128.         }
  129.     }
  130.  
  131.     template<class T>
  132.     inline void BinaryTree<T>::Node::Insert(Node * aNode)
  133.     {
  134.         if (GREATER(*aNode, *this))
  135.         {
  136.             if (myMax)
  137.             {
  138.                 myMax->Insert(aNode);
  139.             }
  140.             else
  141.             {
  142.                 myMax = aNode;
  143.             }
  144.         }
  145.         else if (SMALLER(*aNode, *this))
  146.         {
  147.             if (myMin)
  148.             {
  149.                 myMin->Insert(aNode);
  150.             }
  151.             else
  152.             {
  153.                 myMin = aNode;
  154.             }
  155.         }
  156.         else
  157.         {
  158.             //myData = aNode->myData; overwrite
  159.             delete aNode;
  160.         }
  161.     }
  162.  
  163.     template<class T>
  164.     inline typename  BinaryTree<T>::Node* BinaryTree<T>::Node::RotateAllRight()
  165.     {
  166.         if (!this)
  167.         {
  168.             return this;
  169.         }
  170.         Node* currentTop = this;
  171.         while (currentTop->myMin)
  172.         {
  173.             currentTop = currentTop->RotateRight();
  174.         }
  175.         currentTop->myMax = currentTop->myMax->RotateAllRight();
  176.         return currentTop;
  177.     }
  178.  
  179.     template<class T>
  180.     inline typename  BinaryTree<T>::Node * BinaryTree<T>::Node::RotateRight()
  181.     {
  182.         if (!myMin)
  183.         {
  184.             return this;
  185.         }
  186.         Node* left = myMin;
  187.         Node* root = this;
  188.  
  189.         root->myMin = left->myMax;
  190.         left->myMax = root;
  191.  
  192.         return left;
  193.     }
  194.  
  195.     template<class T>
  196.     inline void BinaryTree<T>::Node::VineToTree()
  197.     {
  198.         size_t size(Count());
  199.         size_t leaveCount = size + 1 - pow(2,floor(log2(size + 1)));
  200.        
  201.         Compress(leaveCount);
  202.  
  203.         size -= leaveCount;
  204.         while (size > 1)
  205.         {
  206.             Compress(size / 2);
  207.             size /= 2;
  208.         }
  209.     }
  210.  
  211.     template<class T>
  212.     inline void BinaryTree<T>::Node::Compress(size_t aCount)
  213.     {
  214.         Node* scanner = this;
  215.         for (size_t i = 0; i < aCount; i++)
  216.         {
  217.             Node* child = scanner->myMax;
  218.             scanner->myMax = child->myMax;
  219.             scanner = scanner->myMax;
  220.             child->myMax = scanner->myMin;
  221.             scanner->myMin = child;
  222.         }
  223.     }
  224.  
  225.     template<class T>
  226.     inline size_t BinaryTree<T>::Node::Count()
  227.     {
  228.         if (this)
  229.         {
  230.             return myMin->Count() + myMax->Count() + 1;
  231.         }
  232.         return 0;
  233.     }
  234.  
  235.     template<class T>
  236.     inline void BinaryTree<T>::Node::Delete()
  237.     {
  238.         if (!this)
  239.         {
  240.             return;
  241.         }
  242.         myMax->Delete();
  243.         myMin->Delete();
  244.         delete this;
  245.     }
  246.  
  247.     template<class T>
  248.     inline void BinaryTree<T>::Node::BuildString(std::string& aString ,int aDepth)
  249.     {
  250.         if (!this)
  251.         {
  252.             return;
  253.         }
  254.         myMin->BuildString(aString, aDepth + 1);
  255.         aString += std::string(aDepth, '~') + std::to_string(myData) + "\n";
  256.         myMax->BuildString(aString, aDepth + 1);
  257.     }
  258.  
  259.     template<class T>
  260.     inline BinaryTree<T>::BinaryTree()
  261.     {
  262.         myRoot = nullptr;
  263.     }
  264.  
  265.     template<class T>
  266.     inline BinaryTree<T>::~BinaryTree()
  267.     {
  268.         myRoot->Delete();
  269.     }
  270.  
  271.     template<class T>
  272.     inline bool BinaryTree<T>::HasElement(const T & aValue) const
  273.     {
  274.         Node* _;
  275.         return myRoot->Find(aValue, _);
  276.     }
  277.  
  278.     template<class T>
  279.     inline void BinaryTree<T>::Insert(const T & aValue)
  280.     {
  281.         if (myRoot)
  282.         {
  283.             myRoot->Insert(new Node(aValue));
  284.         }
  285.         else
  286.         {
  287.             myRoot = new Node(aValue);
  288.         }
  289.     }
  290.  
  291.     template<class T>
  292.     inline void BinaryTree<T>::Remove(const T & aValue)
  293.     {
  294.         Node* parent = nullptr;
  295.         Node* found = myRoot->Find(aValue, parent);
  296.         if (!found) { return; }
  297.  
  298.         if (!parent) // ==> myroot == found
  299.         {
  300.             if (myRoot)
  301.             {
  302.                 if (found->myMin)
  303.                 {
  304.                     myRoot = found->myMin;
  305.                     if (found->myMax)
  306.                     {
  307.                         (+myRoot)->myMax = found->myMax;
  308.                     }
  309.                 }
  310.                 else if (found->myMax)
  311.                 {
  312.                     myRoot = found->myMax;
  313.                 }
  314.                 else
  315.                 {
  316.                     myRoot = nullptr;
  317.                 }
  318.             }
  319.         }
  320.         else if (found->myMin && found->myMax)
  321.         {
  322.             if (parent->myMin == found)
  323.             {
  324.                 parent->myMin = found->myMin;
  325.             }
  326.             else
  327.             {
  328.                 parent->myMax = found->myMin;
  329.             }
  330.             (+found->myMin)->myMax = found->myMax;
  331.         }
  332.         else
  333.         {
  334.             Node* one = (found->myMin ? found->myMin : found->myMax);
  335.  
  336.             if (parent->myMin == found)
  337.             {
  338.                 parent->myMin = one;
  339.             }
  340.             else
  341.             {
  342.                 parent->myMax = one;
  343.             }
  344.         }
  345.  
  346.         delete found;
  347.  
  348.     }
  349.  
  350.     template<class T>
  351.     inline void BinaryTree<T>::DSWBalance()
  352.     {
  353.         myRoot = myRoot->RotateAllRight(); //create backbone
  354.         myRoot->VineToTree();
  355.     }
  356.  
  357.     template<class T>
  358.     inline void BinaryTree<T>::BuildString(std::string & aString)
  359.     {
  360.         myRoot->BuildString(aString, 0);
  361.     }
  362.  
  363. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement