Advertisement
Guest User

Untitled

a guest
Nov 21st, 2014
224
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.91 KB | None | 0 0
  1. template<class T>
  2. class BinarySearchTree
  3. {
  4. public:
  5.     template<class T>
  6.     struct Node
  7.     {
  8.         T data;
  9.         Node<T>* link_right;
  10.         Node<T>* link_left;
  11.     };
  12.     typedef Node<T>* NodePtr;
  13.  
  14. private:
  15.     NodePtr root;
  16.     int m_size = 0;
  17. public:
  18.     //////////////////////////////////////////////////////////////////////
  19.     //                          BinarySearchTree()                      //
  20.     //////////////////////////////////////////////////////////////////////
  21.     BinarySearchTree()
  22.     {
  23.         root = nullptr;
  24.     }
  25.     ~BinarySearchTree()
  26.     {
  27.         delete_post_order(root);
  28.     }
  29.  
  30.     Node<T>* Getroot(){ return root; }
  31.  
  32.     //////////////////////////////////////////////////////////////////////
  33.     //                          void insert()                           //
  34.     //////////////////////////////////////////////////////////////////////
  35.     void insert(T data)
  36.     {
  37.         Node<T>* temp = nullptr;//iterate
  38.         Node<T>* inserter = nullptr;//set to correct position
  39.         Node<T>* node = new Node<T>;//a new node, always a leaf
  40.         node->data = data;
  41.         node->link_left = nullptr;
  42.         node->link_right = nullptr;
  43.         if (root)
  44.         {
  45.             //no duplicate nodes in the BST
  46.             temp = search(data);
  47.             if (temp)
  48.             {
  49.                 delete node;
  50.             }
  51.         }
  52.         else
  53.         {
  54.             root = node;
  55.             ++m_size;
  56.             return;
  57.         }
  58.         temp = root;
  59.         inserter = temp;
  60.         while (temp)
  61.         {
  62.             //go all the way down the tree until a nullptr node is reached
  63.             inserter = temp;
  64.             if (data < temp->data)
  65.             {
  66.                 temp = temp->link_left;
  67.             }
  68.             else if (data > temp->data)
  69.             {
  70.                 temp = temp->link_right;
  71.             }
  72.         }
  73.         //insert it at the correct place
  74.         if (data < inserter->data)
  75.         {
  76.             inserter->link_left = node;
  77.             ++m_size;
  78.         }
  79.         else
  80.         {
  81.             inserter->link_right = node;
  82.             ++m_size;
  83.         }
  84.     }
  85.  
  86.     //////////////////////////////////////////////////////////////////////
  87.     //                          void search()                           //
  88.     //////////////////////////////////////////////////////////////////////
  89.  
  90.     Node<T>* search(T data)
  91.     {
  92.         //go through and return the node reference if found
  93.         //else return null
  94.         NodePtr iter = root;
  95.         while (iter)
  96.         {
  97.             if (iter->data == data)
  98.             {
  99.                 return iter;
  100.             }
  101.             else if (data < iter->data)
  102.             {
  103.                 iter = iter->link_left;
  104.             }
  105.             else if (data > iter->data)
  106.             {
  107.                 iter = iter->link_right;
  108.             }
  109.         }
  110.         return nullptr;
  111.     }
  112.  
  113.  
  114.     //////////////////////////////////////////////////////////////////////
  115.     //                          void erase()                            //
  116.     //////////////////////////////////////////////////////////////////////
  117.  
  118.     void erase(T data)
  119.     {
  120.         Node<T>* iter = root;
  121.         Node<T>* previous = nullptr;
  122.         Node<T>* eraser = search(data);
  123.         //verify eraser
  124.         if (eraser)
  125.         {
  126.             //get the parent node for eraser
  127.             while (iter)
  128.             {
  129.                 previous = iter;
  130.                 if (eraser->data < iter->data)
  131.                 {
  132.                     iter = iter->link_left;
  133.                 }
  134.                 else if (eraser->data > iter->data)
  135.                 {
  136.                     iter = iter->link_right;
  137.                 }
  138.                 if (iter == eraser)
  139.                 {
  140.                     break;
  141.                 }
  142.             }
  143.  
  144.             //is eraser a leaf node?
  145.             if (eraser->link_left == nullptr && eraser->link_right == nullptr)
  146.             {
  147.                 RemoveLeaf(previous, eraser);
  148.             }
  149.  
  150.  
  151.             //does it have one child?
  152.             else if (eraser->link_left == nullptr && eraser->link_right != nullptr)
  153.             {
  154.                 RemoveWithOneChild(previous, eraser);
  155.             }
  156.             else if (eraser->link_right == nullptr && eraser->link_left != nullptr)
  157.             {
  158.                 RemoveWithOneChild(previous, eraser);
  159.             }
  160.  
  161.             //does it have two children? find the lowest right child node to replace
  162.             else if (eraser->link_right && eraser->link_left)
  163.             {
  164.                 RemoveWithTwoChildren(eraser->data, previous, eraser);
  165.             }
  166.         }
  167.     }
  168.  
  169.     //////////////////////////////////////////////////////////////////////
  170.     //                      void RemoveLeaf()                           //
  171.     //////////////////////////////////////////////////////////////////////
  172.  
  173.     void RemoveLeaf(Node<T>* previous, Node<T>* eraser)
  174.     {
  175.         if (eraser && previous)
  176.         {
  177.             //see if parent's got any other children
  178.             if (previous->link_left == eraser && previous->link_right)
  179.             {
  180.                 previous->link_left = nullptr;
  181.             }
  182.             else if (previous->link_left && previous->link_right == eraser)
  183.             {
  184.                 previous->link_right = nullptr;
  185.             }
  186.             else
  187.             {
  188.                 previous->link_left = nullptr;
  189.                 previous->link_right = nullptr;
  190.             }
  191.             delete eraser;
  192.             --m_size;
  193.         }
  194.     }
  195.  
  196.     //////////////////////////////////////////////////////////////////////
  197.     //              void RemoveWithOneChild()                           //
  198.     //////////////////////////////////////////////////////////////////////
  199.  
  200.     void RemoveWithOneChild(Node<T>* previous, Node<T>* eraser)
  201.     {
  202.         if (previous && eraser)
  203.         {
  204.             if (eraser->link_right)
  205.             {
  206.                 Node<T>* temp = eraser->link_right;
  207.                 if (previous->link_right == eraser)
  208.                 {
  209.                     previous->link_right = temp;
  210.                 }
  211.                 else
  212.                 {
  213.                     previous->link_left = temp;
  214.                 }
  215.                 temp->link_left = nullptr;
  216.                 temp->link_right = nullptr;
  217.                 delete eraser;
  218.                 --m_size;
  219.             }
  220.             else if (eraser->link_left)
  221.             {
  222.                 Node<T>* temp = eraser->link_left;
  223.                 if (previous->link_right == eraser)
  224.                 {
  225.                     previous->link_right = temp;
  226.                 }
  227.                 else
  228.                 {
  229.                     previous->link_left = temp;
  230.                 }
  231.                 //previous->link_left = temp;
  232.                 temp->link_left = nullptr;
  233.                 temp->link_right = nullptr;
  234.                 delete eraser;
  235.                 --m_size;
  236.             }
  237.            
  238.  
  239.         }
  240.     }
  241.  
  242.     //////////////////////////////////////////////////////////////////////
  243.     //              void RemoveWitheTwoChildren()                       //
  244.     //////////////////////////////////////////////////////////////////////
  245.  
  246.     void RemoveWithTwoChildren(T data, Node<T>* previous, Node<T>* eraser)
  247.     {
  248.         if (!eraser)
  249.         {
  250.             return;
  251.         }
  252.         //move the furthest down to the smallest node from the right child.
  253.         //change its value with the node to erase and erase it.
  254.         Node<T>* tempR = eraser->link_right;
  255.         while (tempR->link_left)
  256.         {
  257.             tempR = tempR->link_left;
  258.         }
  259.         eraser->data = tempR->data;
  260.         if (!tempR->link_right)
  261.         {
  262.             delete tempR;
  263.             eraser->link_right = nullptr;//testing
  264.             --m_size;
  265.         }
  266.         else if (tempR->link_right)
  267.         {
  268.             //swap data value
  269.             Node<T>* tempRCopy = tempR;
  270.             Node<T>* tempRR = tempR->link_right;
  271.             tempR->data = tempRR->data;
  272.             tempRR->data = tempRCopy->data;
  273.  
  274.             //now the replacer is a leaf and on the wrong side.
  275.             //remove that
  276.             delete tempR->link_right;
  277.             tempR->link_right = nullptr;
  278.             --m_size;
  279.         }
  280.     }
  281.  
  282.     //////////////////////////////////////////////////////////////////////
  283.     //                          int size()                              //
  284.     //////////////////////////////////////////////////////////////////////
  285.  
  286.     int size()
  287.     {
  288.         return m_size;
  289.     }
  290.  
  291.     //////////////////////////////////////////////////////////////////////
  292.     //                  void Traversal_pre_order()                      //
  293.     //////////////////////////////////////////////////////////////////////
  294.  
  295.     void Traversal_pre_order(NodePtr node) // typename Node<T>* NodePtr;
  296.     {
  297.         //Start with the root, than every left node first, than every right node
  298.         //recursive. Inspired by classmates
  299.         if (!node)
  300.         {
  301.             return;//exit this function call and return to previous recursive call
  302.         }
  303.  
  304.         std::cout << node->data << ", "; //print data
  305.  
  306.         Traversal_pre_order(node->link_left); // first the left nodes will be printed
  307.  
  308.         Traversal_pre_order(node->link_right); // then, the right nodes will be printed
  309.  
  310.         // the recursive loop will print the left nodes first until a nullptr link is reached
  311.         // then it will back up and try the right nodes for every time a left node has been printed
  312.         // until it hits a nullptr node. this will finally print all the nodes one by one.
  313.     }
  314.  
  315.     //////////////////////////////////////////////////////////////////////
  316.     //                  void Traversal_post_order()                     //
  317.     //////////////////////////////////////////////////////////////////////
  318.  
  319.     void Traversal_post_order(NodePtr node) // typename Node<T>* NodePtr;
  320.     {
  321.         //exit condition
  322.         if (!node)
  323.         {
  324.             return;
  325.         }
  326.  
  327.         // starting with the left "children" until the first nullptr
  328.         Traversal_post_order(node->link_left);
  329.  
  330.         // then the right "childeren" for every left child, in reverse order
  331.         Traversal_post_order(node->link_right);
  332.  
  333.         // when all right children of the left children have had their recursive calls,
  334.         // and has not been nullptr, print their data
  335.  
  336.         std::cout << node->data << ", ";
  337.     }
  338.  
  339.     //////////////////////////////////////////////////////////////////////
  340.     //                  void Traversal_in_order()                       //
  341.     //////////////////////////////////////////////////////////////////////
  342.  
  343.     void Traversal_in_order(NodePtr node) // typename Node<T>* NodePtr;
  344.     {
  345.         if (!node)
  346.         {
  347.             return;
  348.         }
  349.  
  350.         //in order - from small to large.
  351.         //start by going left all the way
  352.         Traversal_in_order(node->link_left);
  353.  
  354.         //after a nullptr hit, go back, print data and find out if there are any right children
  355.         // that have left children.
  356.         std::cout << node->data << ", ";
  357.         //for every node that have a right child, go to the left most node and print them first
  358.         Traversal_in_order(node->link_right);
  359.  
  360.     }
  361.  
  362.     void delete_post_order(NodePtr node)
  363.     {
  364.         if (!node)
  365.         {
  366.             return;
  367.         }
  368.         delete_post_order(node->link_left);
  369.         delete_post_order(node->link_right);
  370.         delete node;
  371.     }
  372. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement