Advertisement
Guest User

Untitled

a guest
Feb 11th, 2016
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.12 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include <functional>
  4. #include <utility>
  5. #include <iostream>
  6. #include <stack>
  7. #include <memory>
  8. #include <deque>
  9. #include <iterator>
  10. #include <type_traits>
  11. #include <stack>
  12. #include <stdexcept>
  13. #include <vector>
  14.  
  15. namespace dts
  16. {
  17.  
  18. template <typename T, typename Func = std::less<T>>
  19. class PersistentSet
  20. {
  21.  
  22. public:
  23.  
  24. PersistentSet();
  25. PersistentSet(Func);
  26.  
  27.  
  28. bool add(const T&);
  29. bool add(T&&);
  30.  
  31. bool remove(const T&);
  32.  
  33. bool empty() const;
  34.  
  35. size_t history_size() const;
  36.  
  37. void roll_back();
  38.  
  39. class TreeIterator
  40. : public std::iterator<std::forward_iterator_tag,
  41. std::remove_cv_t<T>,
  42. std::ptrdiff_t,
  43. const T*,
  44. const T&>
  45. {
  46. using node = typename dts::PersistentSet< std::remove_cv_t<T>>::Nodeptr;
  47. node itr;
  48. node nil;
  49. std::stack<node> path;
  50.  
  51. node find_successor(node n)
  52. {
  53. n = n->right;
  54. if (n != nil)
  55. {
  56. while (n->left != nil)
  57. {
  58. path.push(n);
  59. n = n->left;
  60. }
  61. }
  62. else
  63. {
  64. n = path.top();
  65. path.pop();
  66. }
  67. return n;
  68. }
  69. public:
  70.  
  71. explicit TreeIterator(node n, node pnil) : nil(pnil) //begin
  72. {
  73. if (n == nil)
  74. itr = nil;
  75. else
  76. {
  77. path.push(nil);
  78. while (n->left != nil)
  79. {
  80. path.push(n);
  81. n = n->left;
  82. }
  83. itr = n;
  84. }
  85. }
  86. explicit TreeIterator(node pnil) // end
  87. : itr(pnil), nil(pnil)
  88. { }
  89.  
  90.  
  91. TreeIterator& operator++ ()
  92. {
  93. itr = find_successor(itr);
  94. return *this;
  95. }
  96. TreeIterator operator++ (int)
  97. {
  98. TreeIterator tmp(*this);
  99. itr = find_successor(itr);
  100. return tmp;
  101. }
  102.  
  103. bool operator == (const TreeIterator& rhs) const
  104. {
  105. return itr == rhs.itr;
  106. }
  107.  
  108. bool operator != (const TreeIterator& rhs) const
  109. {
  110. return itr != rhs.itr;
  111. }
  112.  
  113. const T& operator* () const
  114. {
  115. return itr->key;
  116. }
  117.  
  118. const T& operator-> () const
  119. {
  120. return itr->key;
  121. }
  122.  
  123. };
  124.  
  125.  
  126. typedef TreeIterator const_iterator;
  127.  
  128. const_iterator begin() const
  129. {
  130. return begin(roots.size() - 1);
  131. }
  132. const_iterator begin(size_t index) const
  133. {
  134. if (index >= roots.size())
  135. throw std::out_of_range("out of range");
  136.  
  137. return const_iterator(roots[index], nil);
  138. }
  139. const_iterator end() const
  140. {
  141. return const_iterator(nil);
  142. }
  143.  
  144. private:
  145.  
  146. struct Node;
  147. using Nodeptr = std::shared_ptr<Node>;
  148.  
  149. struct Node
  150. {
  151. T key;
  152. bool isRed;
  153.  
  154. Nodeptr left;
  155. Nodeptr right;
  156.  
  157. Node(const T& pkey, bool pisRed, Nodeptr pleft, Nodeptr pright)
  158. : key(pkey), isRed(pisRed), left(pleft), right(pright)
  159. { }
  160.  
  161. Node(T&& pkey, bool pisRed, Nodeptr pleft, Nodeptr pright)
  162. : key(std::move(pkey)), isRed(pisRed), left(pleft), right(pright)
  163. { }
  164. };
  165.  
  166. std::vector<Nodeptr> roots;
  167. Func cmp;
  168. Nodeptr nil;
  169.  
  170. template <typename TT>
  171. Nodeptr create_node(TT&&);
  172.  
  173. Nodeptr copy_node(Nodeptr) const;
  174.  
  175. template <typename TT>
  176. bool generic_add(TT&&);
  177.  
  178. template <typename TT>
  179. Nodeptr add_recursive(std::deque<Nodeptr>&, TT&&, Nodeptr&);
  180.  
  181. void balance_add(std::deque<Nodeptr> &x);
  182.  
  183. template <typename ChildA, typename ChildB>
  184. void mirror_add_balance(Nodeptr&, Nodeptr&, std::deque<Nodeptr>&, ChildA, ChildB);
  185.  
  186. Nodeptr remove_recursive(const T&, Nodeptr, std::deque<Nodeptr>&);
  187.  
  188. template<typename F, typename NF, typename TT>
  189. Nodeptr find_and_build(TT&&, Nodeptr, std::deque<Nodeptr>&, F, NF);
  190.  
  191. void delete_node(std::deque<Nodeptr> &);
  192.  
  193. Nodeptr build_min_path(Nodeptr node, std::deque<Nodeptr>&);
  194.  
  195. void transplant(Nodeptr, Nodeptr, Nodeptr);
  196.  
  197. void balance_remove(Nodeptr x, std::deque<Nodeptr>&);
  198.  
  199. template <typename ChildA, typename ChildB >
  200. void mirror_remove_balance(Nodeptr&, Nodeptr&, std::deque<Nodeptr> &, ChildA, ChildB);
  201.  
  202. template <typename ChildA, typename ChildB >
  203. Nodeptr rotate(Nodeptr, Nodeptr, ChildA, ChildB);
  204.  
  205. static Nodeptr& left(Nodeptr x) { return x->left; };
  206.  
  207. static Nodeptr& right(Nodeptr x) { return x->right; };
  208.  
  209. static Nodeptr pop_front(std::deque<Nodeptr>& deque)
  210. {
  211. auto front = deque.front();
  212. deque.pop_front();
  213. return front;
  214.  
  215. };
  216.  
  217.  
  218.  
  219. };
  220.  
  221. template<typename T, typename Func>
  222. size_t PersistentSet<T, Func>::history_size() const
  223. {
  224. return roots.size();
  225. }
  226. template<typename T, typename Func>
  227. bool PersistentSet<T, Func>::empty() const
  228. {
  229. return roots.back() == nil;
  230. }
  231.  
  232. template<typename T, typename Func>
  233. void PersistentSet<T, Func>::roll_back()
  234. {
  235. if (!roots.empty())
  236. roots.pop_back();
  237. }
  238.  
  239. template <typename K, typename Func>
  240. void PersistentSet<K, Func>::transplant(
  241.  
  242. Nodeptr parent,
  243. Nodeptr removed,
  244. Nodeptr transplanted
  245. )
  246. {
  247. if (parent == nil)
  248. {
  249. roots.pop_back();
  250. roots.push_back(transplanted);
  251. }
  252. else if (parent->left == removed)
  253. parent->left = transplanted;
  254. else
  255. parent->right = transplanted;
  256. }
  257.  
  258.  
  259. template<typename T, typename Func>
  260. PersistentSet<T, Func>::PersistentSet() : PersistentSet(Func())
  261. { }
  262.  
  263. template<typename T, typename Func>
  264. PersistentSet<T, Func>::PersistentSet(Func pcmp)
  265. : cmp(pcmp),
  266. roots(std::vector<Nodeptr>()),
  267. nil(std::make_shared<Node>(T(), false, nullptr, nullptr))
  268. {
  269. roots.push_back(nil);
  270. }
  271.  
  272. template<typename T, typename Func>
  273. template <typename ChildA, typename ChildB >
  274. typename PersistentSet<T, Func>::Nodeptr
  275. PersistentSet<T, Func>::rotate(
  276.  
  277. Nodeptr parent_of_x,
  278. Nodeptr x,
  279. ChildA childA,
  280. ChildB childB
  281. )
  282. {
  283. Nodeptr child_of_x = childB(x);
  284. childB(x) = childA(child_of_x);
  285.  
  286. if (x == roots.back())
  287. {
  288. roots.pop_back();
  289. roots.push_back(child_of_x);
  290. }
  291. else if (x == childA(parent_of_x))
  292. childA(parent_of_x) = child_of_x;
  293. else
  294. childB(parent_of_x) = child_of_x;
  295.  
  296. childA(child_of_x) = x;
  297.  
  298. return child_of_x;
  299. }
  300.  
  301. template <typename T, typename Func>
  302. template<typename TT>
  303. bool PersistentSet<T, Func>::generic_add(TT&& element)
  304. {
  305.  
  306. std::deque<Nodeptr> path;
  307. auto newRoot = add_recursive(
  308. path,
  309. std::forward<TT>(element),
  310. roots.back()
  311. );
  312.  
  313. bool added = newRoot != nullptr;
  314. if (added)
  315. {
  316. roots.push_back(newRoot);
  317. path.push_back(nil);
  318. balance_add(path);
  319. }
  320. return added;
  321. }
  322.  
  323. template<typename T, typename Func>
  324. template<typename F, typename NF, typename TT>
  325. typename PersistentSet<T, Func>::Nodeptr
  326. PersistentSet<T, Func>::find_and_build(
  327. TT&& element,
  328. Nodeptr node,
  329. std::deque<Nodeptr> &path,
  330. F if_found,
  331. NF if_not_found
  332. )
  333. {
  334. if (node == nil)
  335. return if_not_found(element, path);
  336.  
  337. bool is_less = cmp(element, node->key);
  338. bool is_equal = !is_less
  339. && !cmp(node->key, element);
  340.  
  341. if (is_equal)
  342. return if_found(node, path);
  343.  
  344. auto direction = is_less ? left : right;
  345. auto child = find_and_build(
  346. std::forward<TT>(element),
  347. direction(node),
  348. path,
  349. if_found,
  350. if_not_found
  351. );
  352. if (child == nullptr) return child;
  353.  
  354. auto copy = copy_node(node);
  355. path.push_back(copy);
  356. direction(copy) = child;
  357.  
  358. return copy;
  359. }
  360.  
  361. template<typename T, typename Func>
  362. template<typename TT>
  363. typename PersistentSet<T, Func>::Nodeptr
  364. PersistentSet<T, Func>::add_recursive(std::deque<Nodeptr>& path, TT &&element, Nodeptr & node)
  365. {
  366.  
  367. auto if_not_found = [&](auto pelement, auto& path)
  368. {
  369. auto copy = create_node(std::forward<T>(pelement));
  370. path.push_back(copy);
  371. return copy;
  372. };
  373. auto if_found = [](auto node, auto& path) { return nullptr; };
  374. return find_and_build(element, node, path, if_found, if_not_found);
  375. }
  376.  
  377. template <typename T, typename Func>
  378. typename PersistentSet<T, Func>::Nodeptr
  379. PersistentSet<T, Func>::remove_recursive(const T& element, Nodeptr node, std::deque<Nodeptr>& path)
  380. {
  381.  
  382. auto if_not_found = [](auto element, auto& path) { return nullptr; };
  383. auto if_found = [&](auto pnode, auto& ppath)
  384. {
  385. auto copy = copy_node(pnode);
  386. ppath.push_back(copy);
  387. return copy;
  388. };
  389. return find_and_build(element, node, path, if_found, if_not_found);
  390. }
  391.  
  392. template <typename T, typename Func>
  393. bool PersistentSet<T, Func>::add(const T& element)
  394. {
  395. return generic_add(const_cast<T&> (element));
  396. }
  397.  
  398. template <typename T, typename Func>
  399. bool PersistentSet<T, Func>::add(T&& element)
  400. {
  401. return generic_add(std::move(element));
  402. }
  403.  
  404. template<typename T, typename Func>
  405. typename PersistentSet<T, Func>::Nodeptr
  406. PersistentSet<T, Func>::copy_node(Nodeptr node) const
  407. {
  408. if (node == nil) return nil;
  409. return std::make_shared<Node>(node->key, node->isRed, node->left, node->right);
  410. }
  411.  
  412. template <typename T, typename Func>
  413. template <typename TT>
  414. typename PersistentSet<T, Func>::Nodeptr
  415. PersistentSet<T, Func>::create_node(TT&& key)
  416. {
  417. return std::make_shared<Node>(std::forward<TT>(key), true, nil, nil);
  418. }
  419.  
  420. template <typename T, typename Func>
  421. void PersistentSet<T, Func>::delete_node(std::deque<Nodeptr> & path)
  422. {
  423.  
  424. auto removed = path.front();
  425. auto transplanted = removed->right;
  426.  
  427. if (removed->left == nil)
  428. {
  429. path.pop_front();
  430. transplant(path.front(), removed, transplanted);
  431. }
  432. else if (removed->right == nil)
  433. {
  434. path.pop_front();
  435. transplanted = removed->left;
  436. transplant(path.front(), removed, transplanted);
  437. }
  438. else
  439. {
  440. auto temp = removed;
  441. removed->right = copy_node(removed->right);
  442. removed = build_min_path(removed->right, path);
  443. transplanted = removed->right;
  444. temp->key = std::move(removed->key);
  445. transplant(path.front(), removed, transplanted);
  446. }
  447.  
  448. if (!removed->isRed)
  449. balance_remove(transplanted, path);
  450.  
  451. }
  452.  
  453.  
  454. template <typename T, typename Func>
  455. typename PersistentSet<T, Func>::Nodeptr
  456. PersistentSet<T, Func>::build_min_path(Nodeptr node, std::deque<Nodeptr>& path)
  457. {
  458. while (node->left != nil)
  459. {
  460. node->left = copy_node(node->left);
  461. path.push_front(node);
  462. node = node->left;
  463. }
  464. return node;
  465. }
  466.  
  467. template <typename T, typename Func>
  468. void PersistentSet<T, Func>::balance_remove(Nodeptr extra_black, std::deque<Nodeptr>& path)
  469. {
  470.  
  471. auto parent = pop_front(path);
  472. while (extra_black != roots.back()
  473. && !extra_black->isRed)
  474. {
  475. if (parent->left == extra_black)
  476. mirror_remove_balance(extra_black, parent, path, left, right);
  477. else
  478. mirror_remove_balance(extra_black, parent, path, right, left);
  479. }
  480.  
  481. auto new_node = copy_node(extra_black);
  482. transplant(parent, extra_black, new_node);
  483. new_node->isRed = false;
  484.  
  485. }
  486. template <typename T, typename Func>
  487. template <typename ChildA, typename ChildB >
  488. void PersistentSet<T, Func>::mirror_remove_balance(
  489.  
  490. Nodeptr& extra_black,
  491. Nodeptr& parent,
  492. std::deque<Nodeptr> & path,
  493. ChildA childA,
  494. ChildB childB)
  495. {
  496. Nodeptr brother = childB(parent);
  497. if (brother->isRed)
  498. {
  499. brother = childB(parent) = copy_node(brother);
  500.  
  501. std::swap(brother->isRed, parent->isRed);
  502. rotate(path.front(), parent, childA, childB);
  503. path.push_front(brother);
  504. brother = childB(parent);
  505. }
  506. if (!brother->left->isRed && !brother->right->isRed)
  507. {
  508. brother = childB(parent) = copy_node(brother);
  509.  
  510. brother->isRed = true;
  511. extra_black = parent;
  512. parent = pop_front(path);
  513. }
  514. else
  515. {
  516. if (!childB(brother)->isRed)
  517. {
  518. brother = childB(parent) = copy_node(brother);
  519.  
  520. childA(brother) = copy_node(childA(brother));
  521. std::swap(brother->isRed, childA(brother)->isRed);
  522. brother = rotate(parent, brother, childB, childA);
  523. }
  524. brother = childB(parent) = copy_node(brother);
  525.  
  526. childB(brother) = copy_node(childB(brother));
  527. brother->isRed = parent->isRed;
  528. parent->isRed = false;
  529. childB(brother)->isRed = false;
  530. rotate(path.front(), parent, childA, childB);
  531.  
  532. extra_black = roots.back();
  533. parent = nil;
  534. }
  535.  
  536. }
  537.  
  538. template <typename T, typename Func>
  539. bool PersistentSet<T, Func>::remove(const T& element)
  540. {
  541. std::deque<Nodeptr> path;
  542.  
  543. auto node = remove_recursive(
  544. element,
  545. roots.back(),
  546. path
  547. );
  548. bool exist = node != nullptr;
  549. if (exist)
  550. {
  551. roots.push_back(node);
  552. path.push_back(nil);
  553. delete_node(path);
  554. }
  555. return exist;
  556. }
  557.  
  558.  
  559. template <typename T, typename Func>
  560. void PersistentSet<T, Func>::balance_add(std::deque<Nodeptr>& path)
  561. {
  562.  
  563. auto no_compliant = pop_front(path);
  564. auto parent = pop_front(path);
  565.  
  566. while (parent->isRed)
  567. {
  568. if (path.front()->left == parent)
  569. mirror_add_balance(parent, no_compliant, path, left, right);
  570. else
  571. mirror_add_balance(parent, no_compliant, path, right, left);
  572. }
  573. roots.back()->isRed = false;
  574.  
  575. }
  576.  
  577. template <typename T, typename Func>
  578. template <typename ChildA, typename ChildB >
  579. void PersistentSet<T, Func>::
  580. mirror_add_balance(
  581.  
  582. Nodeptr &parent,
  583. Nodeptr &no_compliant,
  584. std::deque<Nodeptr>& path,
  585. ChildA childA,
  586. ChildB childB
  587. )
  588.  
  589. {
  590. Nodeptr &uncle = childB(path.front());
  591. if (uncle->isRed)
  592. {
  593. uncle = copy_node(uncle);
  594. parent->isRed = false;
  595. uncle->isRed = false;
  596. path.front()->isRed = true;
  597. no_compliant = pop_front(path);
  598. parent = pop_front(path);
  599. }
  600. else
  601. {
  602. if (no_compliant == childB(parent))
  603. {
  604. std::swap(no_compliant, parent);
  605. rotate(path.front(), no_compliant, childA, childB);
  606. }
  607. auto grand_parent = pop_front(path);
  608. std::swap(grand_parent->isRed, parent->isRed);
  609. rotate(path.front(), grand_parent, childB, childA);
  610. }
  611. }
  612.  
  613. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement