Advertisement
kaenan

btree.cpp

Feb 27th, 2018
133
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.90 KB | None | 0 0
  1. #ifndef __BTREE_CPP
  2. #define __BTREE_CPP
  3.  
  4. #include "btree.h"
  5.  
  6. #include <fstream>
  7. #include <iostream>
  8. #include <functional>
  9. #include <memory>
  10. #include <queue>
  11. #include <stack>
  12. #include <cstdlib>
  13. #include <vector>
  14.  
  15.  
  16. /* Creates a tree from a preorder traversal and replaces the current tree.
  17. * Istream =input= is the where input is read from and get_data_fn must process the input and return T data.
  18. */
  19. template<typename T>
  20. void btree<T>::read_preorder(
  21.     std::istream& input,
  22.     std::function<bool(std::istream&, T&)> get_data_fn)
  23. {
  24.     this->root = this->read_preorder_body(input, get_data_fn);
  25. }
  26.  
  27. /* Creates a tree form a preorder traversal. */
  28. template<typename T>
  29. std::shared_ptr<typename btree<T>::Node>
  30. btree<T>::read_preorder_body(
  31.     std::istream& input,
  32.     std::function<bool(std::istream&, T&)> get_data_fn)
  33. {
  34.     T data;
  35.     if (get_data_fn(input, data) == false) {
  36.         return nullptr;
  37.     }
  38.  
  39.     std::shared_ptr<btree<T>::Node> new_node;
  40.  
  41.     /* Alocate memory for new_node. */
  42.     new_node = std::make_shared<btree<T>::Node>();
  43.  
  44.     /* Initialize node. */
  45.     new_node->data = data;
  46.  
  47.     /* Resolve left and right child. */
  48.     new_node->left = this->read_preorder_body(input, get_data_fn);
  49.     new_node->right = this->read_preorder_body(input, get_data_fn);
  50.  
  51.     return new_node;
  52. }
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59. /*
  60. ===============================
  61. LAB1 - prb. 12
  62. ===============================
  63. */
  64. /* Creates tree from an inorder and preorder traversal and replaces the current tree. */
  65.  
  66. /*
  67.     input: istream p, istream i, get_data_fn, peek_data_fn, serach_vector, [std::vector prev_data]
  68.  
  69.     T data = get_data_fn(p);
  70.  
  71.     node = create_node(data);
  72.     node.left = node.right = nullptr;
  73.  
  74.     if (node->data != peek_data_fn(i))  // check if node can have left child
  75.         node->left = fn(...);
  76.     else
  77.         data = get_data_fn(i);
  78.  
  79.     if (!seen_before(peek_data_fn(i), vector)) // check if node can have right child
  80.         this->right = fn(...);
  81.     else
  82.         data = get_data_fn(i);
  83.    
  84.     return node;
  85. */
  86.  
  87. template<typename T>
  88. std::shared_ptr<typename btree<T>::Node> btree<T>::read_traversal_body(
  89.     std::istream& preorder, std::istream& inorder,
  90.     std::function<bool(std::istream&, T&)> get_data_fn,
  91.     std::function<bool(std::istream&, T&)> peek_data_fn,
  92.     std::function<bool(std::vector<T>, T)> search_vector,
  93.     std::vector<T>& prev_data)
  94. {
  95.     T data;
  96.  
  97.     if (get_data_fn(preorder, data) == false) {
  98.         return nullptr;
  99.     }
  100.  
  101.     std::shared_ptr<btree<T>::Node> node;
  102.  
  103.     node = this->create_node(data);
  104.     node->left = node->right = nullptr;
  105.  
  106.     prev_data.push_back(node->data);
  107.  
  108.     /* Check if there's more data. */
  109.     if (peek_data_fn(inorder, data) == false) {
  110.         return node;
  111.     }
  112.  
  113.     /* Resolve left child. */
  114.     if (node->data != data) {
  115.         node->left = this->read_traversal_body(
  116.             preorder, inorder,
  117.             get_data_fn, peek_data_fn,
  118.             search_vector, prev_data);
  119.     }
  120.     else {
  121.         if (get_data_fn(inorder, data) == false) {
  122.             std::cout << "WEIRD! Should not have failed." << '\n';
  123.         }
  124.     }
  125.  
  126.     /* Check if there's more data. */
  127.     if (peek_data_fn(inorder, data) == false) {
  128.         return node;
  129.     }
  130.  
  131.     /* Resolve right child. */
  132.     if (search_vector(prev_data, data) == false) {
  133.         node->right = this->read_traversal_body(
  134.             preorder, inorder,
  135.             get_data_fn, peek_data_fn,
  136.             search_vector, prev_data);
  137.     }
  138.     else {
  139.         if (get_data_fn(inorder, data) == false) {
  140.             std::cout << "WEIRD! Should not have failed." << '\n';
  141.         }
  142.     }
  143.  
  144.     return node;
  145. }
  146.  
  147. template<typename T>
  148. void btree<T>::read_traversal(
  149.     std::istream& preorder, std::istream& inorder,
  150.     std::function<bool(std::istream&, T&)> get_data_fn,
  151.     std::function<bool(std::istream&, T&)> peek_data_fn,
  152.     std::function<bool(std::vector<T>, T)> search_vector)
  153. {
  154.     std::vector<T> prev_nodes;
  155.     this->root = this->read_traversal_body(
  156.         preorder, inorder,
  157.         get_data_fn, peek_data_fn,
  158.         search_vector, prev_nodes);
  159. }
  160.  
  161.  
  162.  
  163.  
  164. /* Breadth traversal, applying =action= to each node data. */
  165. template<typename T>
  166. std::shared_ptr<typename btree<T>::Node>
  167. btree<T>::breadth_traversal(std::function<void(T& data)> action)
  168. {
  169.     if (this->root == nullptr) {
  170.         std::cout << "(null)" << '\n';
  171.         return nullptr;
  172.     }
  173.  
  174.     std::shared_ptr<btree<T>::Node> current_node;
  175.     std::queue< std::shared_ptr<btree<T>::Node> > fringe;
  176.     fringe.push(this->root);
  177.  
  178.     do {
  179.         current_node = fringe.front();
  180.         fringe.pop();
  181.  
  182.         action(current_node->data);
  183.  
  184.         if (current_node->left != nullptr) {
  185.             fringe.push(current_node->left);
  186.         }
  187.  
  188.         if (current_node->right != nullptr) {
  189.             fringe.push(current_node->right);
  190.         }
  191.  
  192.     } while (!fringe.empty());
  193.  
  194.     return current_node;
  195. }
  196.  
  197.  
  198.  
  199.  
  200.  
  201. /*
  202. ===============================
  203. LAB1 - prb. 11
  204. ===============================
  205. */
  206. /* Traverse tree in preorder, applying an =action= to each node data
  207. *    + Calculate depths and return the max depth.
  208. */
  209. template<typename T>
  210. int btree<T>::preorder_traversal(
  211.     std::function<void(T& data)> action)
  212. {
  213.     if (this->root == nullptr) {
  214.         std::cout << "(null)" << '\n';
  215.         return -1;
  216.     }
  217.  
  218.     std::shared_ptr<btree<T>::Node> current_node;
  219.     std::stack< std::shared_ptr<btree<T>::Node> > fringe;
  220.  
  221.     fringe.push(this->root);
  222.     this->root->depth = 0;
  223.  
  224.     int max_depth = 0;
  225.  
  226.     do {
  227.         current_node = fringe.top();
  228.         fringe.pop();
  229.  
  230.         action(current_node->data);
  231.  
  232.         if (current_node->depth > max_depth) {
  233.             max_depth = current_node->depth;
  234.         }
  235.  
  236.         if (current_node->right != nullptr) {
  237.             current_node->right->depth = current_node->depth + 1;
  238.             fringe.push(current_node->right);
  239.         }
  240.  
  241.         if (current_node->left != nullptr) {
  242.             current_node->left->depth = current_node->depth + 1;
  243.             fringe.push(current_node->left);
  244.         }
  245.  
  246.     } while (!fringe.empty());
  247.  
  248.     return max_depth;
  249. }
  250.  
  251.  
  252. /* Creates a node, sets data field and returns shared_ptr to the node. */
  253. template<typename T>
  254. std::shared_ptr<typename btree<T>::Node> btree<T>::create_node(T data)
  255. {
  256.     std::shared_ptr<btree<T>::Node> new_node = std::make_shared<btree<T>::Node>();
  257.  
  258.     new_node->data = data;
  259.  
  260.     return new_node;
  261. }
  262.  
  263. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement