avltree.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754
  1. #pragma once
  2. #include <util/generic/noncopyable.h>
  3. template <class T, class C>
  4. struct TAvlTreeItem;
  5. template <class T, class C>
  6. class TAvlTree: public TNonCopyable {
  7. using TTreeItem = TAvlTreeItem<T, C>;
  8. friend struct TAvlTreeItem<T, C>;
  9. static inline const T* AsT(const TTreeItem* item) noexcept {
  10. return (const T*)item;
  11. }
  12. static inline T* AsT(TTreeItem* item) noexcept {
  13. return (T*)item;
  14. }
  15. template <class TTreeItem, class TValue>
  16. class TIteratorBase {
  17. public:
  18. inline TIteratorBase(TTreeItem* p, const TAvlTree* t) noexcept
  19. : Ptr_(p)
  20. , Tree_(t)
  21. {
  22. }
  23. inline bool IsEnd() const noexcept {
  24. return Ptr_ == nullptr;
  25. }
  26. inline bool IsBegin() const noexcept {
  27. return Ptr_ == nullptr;
  28. }
  29. inline bool IsFirst() const noexcept {
  30. return Ptr_ && Ptr_ == Tree_->Head_;
  31. }
  32. inline bool IsLast() const noexcept {
  33. return Ptr_ && Ptr_ == Tree_->Tail_;
  34. }
  35. inline TValue& operator*() const noexcept {
  36. return *AsT(Ptr_);
  37. }
  38. inline TValue* operator->() const noexcept {
  39. return AsT(Ptr_);
  40. }
  41. inline TTreeItem* Inc() noexcept {
  42. return Ptr_ = FindNext(Ptr_);
  43. }
  44. inline TTreeItem* Dec() noexcept {
  45. return Ptr_ = FindPrev(Ptr_);
  46. }
  47. inline TIteratorBase& operator++() noexcept {
  48. Inc();
  49. return *this;
  50. }
  51. inline TIteratorBase operator++(int) noexcept {
  52. TIteratorBase ret(*this);
  53. Inc();
  54. return ret;
  55. }
  56. inline TIteratorBase& operator--() noexcept {
  57. Dec();
  58. return *this;
  59. }
  60. inline TIteratorBase operator--(int) noexcept {
  61. TIteratorBase ret(*this);
  62. Dec();
  63. return ret;
  64. }
  65. inline TIteratorBase Next() const noexcept {
  66. return ConstructNext(*this);
  67. }
  68. inline TIteratorBase Prev() const noexcept {
  69. return ConstructPrev(*this);
  70. }
  71. inline bool operator==(const TIteratorBase& r) const noexcept {
  72. return Ptr_ == r.Ptr_;
  73. }
  74. inline bool operator!=(const TIteratorBase& r) const noexcept {
  75. return Ptr_ != r.Ptr_;
  76. }
  77. private:
  78. inline static TIteratorBase ConstructNext(const TIteratorBase& i) noexcept {
  79. return TIterator(FindNext(i.Ptr_), i.Tree_);
  80. }
  81. inline static TIteratorBase ConstructPrev(const TIteratorBase& i) noexcept {
  82. return TIterator(FindPrev(i.Ptr_), i.Tree_);
  83. }
  84. inline static TIteratorBase FindPrev(TTreeItem* el) noexcept {
  85. if (el->Left_ != nullptr) {
  86. el = el->Left_;
  87. while (el->Right_ != nullptr) {
  88. el = el->Right_;
  89. }
  90. } else {
  91. while (true) {
  92. TTreeItem* last = el;
  93. el = el->Parent_;
  94. if (el == nullptr || el->Right_ == last) {
  95. break;
  96. }
  97. }
  98. }
  99. return el;
  100. }
  101. static TTreeItem* FindNext(TTreeItem* el) {
  102. if (el->Right_ != nullptr) {
  103. el = el->Right_;
  104. while (el->Left_) {
  105. el = el->Left_;
  106. }
  107. } else {
  108. while (true) {
  109. TTreeItem* last = el;
  110. el = el->Parent_;
  111. if (el == nullptr || el->Left_ == last) {
  112. break;
  113. }
  114. }
  115. }
  116. return el;
  117. }
  118. private:
  119. TTreeItem* Ptr_;
  120. const TAvlTree* Tree_;
  121. };
  122. using TConstIterator = TIteratorBase<const TTreeItem, const T>;
  123. using TIterator = TIteratorBase<TTreeItem, T>;
  124. static inline TConstIterator ConstructFirstConst(const TAvlTree* t) noexcept {
  125. return TConstIterator(t->Head_, t);
  126. }
  127. static inline TIterator ConstructFirst(const TAvlTree* t) noexcept {
  128. return TIterator(t->Head_, t);
  129. }
  130. static inline TConstIterator ConstructLastConst(const TAvlTree* t) noexcept {
  131. return TConstIterator(t->Tail_, t);
  132. }
  133. static inline TIterator ConstructLast(const TAvlTree* t) noexcept {
  134. return TIterator(t->Tail_, t);
  135. }
  136. static inline bool Compare(const TTreeItem& l, const TTreeItem& r) {
  137. return C::Compare(*AsT(&l), *AsT(&r));
  138. }
  139. public:
  140. using const_iterator = TConstIterator;
  141. using iterator = TIterator;
  142. inline TAvlTree() noexcept
  143. : Root_(nullptr)
  144. , Head_(nullptr)
  145. , Tail_(nullptr)
  146. {
  147. }
  148. inline ~TAvlTree() noexcept {
  149. Clear();
  150. }
  151. inline void Clear() noexcept {
  152. for (iterator it = Begin(); it != End();) {
  153. (it++)->TTreeItem::Unlink();
  154. }
  155. }
  156. inline T* Insert(TTreeItem* el, TTreeItem** lastFound = nullptr) noexcept {
  157. el->Unlink();
  158. el->Tree_ = this;
  159. TTreeItem* curEl = Root_;
  160. TTreeItem* parentEl = nullptr;
  161. TTreeItem* lastLess = nullptr;
  162. while (true) {
  163. if (curEl == nullptr) {
  164. AttachRebal(el, parentEl, lastLess);
  165. if (lastFound != nullptr) {
  166. *lastFound = el;
  167. }
  168. return AsT(el);
  169. }
  170. if (Compare(*el, *curEl)) {
  171. parentEl = lastLess = curEl;
  172. curEl = curEl->Left_;
  173. } else if (Compare(*curEl, *el)) {
  174. parentEl = curEl;
  175. curEl = curEl->Right_;
  176. } else {
  177. if (lastFound != nullptr) {
  178. *lastFound = curEl;
  179. }
  180. return nullptr;
  181. }
  182. }
  183. }
  184. inline T* Find(const TTreeItem* el) const noexcept {
  185. TTreeItem* curEl = Root_;
  186. while (curEl) {
  187. if (Compare(*el, *curEl)) {
  188. curEl = curEl->Left_;
  189. } else if (Compare(*curEl, *el)) {
  190. curEl = curEl->Right_;
  191. } else {
  192. return AsT(curEl);
  193. }
  194. }
  195. return nullptr;
  196. }
  197. inline T* LowerBound(const TTreeItem* el) const noexcept {
  198. TTreeItem* curEl = Root_;
  199. TTreeItem* lowerBound = nullptr;
  200. while (curEl) {
  201. if (Compare(*el, *curEl)) {
  202. lowerBound = curEl;
  203. curEl = curEl->Left_;
  204. } else if (Compare(*curEl, *el)) {
  205. curEl = curEl->Right_;
  206. } else {
  207. return AsT(curEl);
  208. }
  209. }
  210. return AsT(lowerBound);
  211. }
  212. inline T* Erase(TTreeItem* el) noexcept {
  213. if (el->Tree_ == this) {
  214. return this->EraseImpl(el);
  215. }
  216. return nullptr;
  217. }
  218. inline T* EraseImpl(TTreeItem* el) noexcept {
  219. el->Tree_ = nullptr;
  220. TTreeItem* replacement;
  221. TTreeItem* fixfrom;
  222. long lheight, rheight;
  223. if (el->Right_) {
  224. replacement = el->Right_;
  225. while (replacement->Left_) {
  226. replacement = replacement->Left_;
  227. }
  228. if (replacement->Parent_ == el) {
  229. fixfrom = replacement;
  230. } else {
  231. fixfrom = replacement->Parent_;
  232. }
  233. if (el == Head_) {
  234. Head_ = replacement;
  235. }
  236. RemoveEl(replacement, replacement->Right_);
  237. ReplaceEl(el, replacement);
  238. } else if (el->Left_) {
  239. replacement = el->Left_;
  240. while (replacement->Right_) {
  241. replacement = replacement->Right_;
  242. }
  243. if (replacement->Parent_ == el) {
  244. fixfrom = replacement;
  245. } else {
  246. fixfrom = replacement->Parent_;
  247. }
  248. if (el == Tail_) {
  249. Tail_ = replacement;
  250. }
  251. RemoveEl(replacement, replacement->Left_);
  252. ReplaceEl(el, replacement);
  253. } else {
  254. fixfrom = el->Parent_;
  255. if (el == Head_) {
  256. Head_ = el->Parent_;
  257. }
  258. if (el == Tail_) {
  259. Tail_ = el->Parent_;
  260. }
  261. RemoveEl(el, nullptr);
  262. }
  263. if (fixfrom == nullptr) {
  264. return AsT(el);
  265. }
  266. RecalcHeights(fixfrom);
  267. TTreeItem* ub = FindFirstUnbalEl(fixfrom);
  268. while (ub) {
  269. lheight = ub->Left_ ? ub->Left_->Height_ : 0;
  270. rheight = ub->Right_ ? ub->Right_->Height_ : 0;
  271. if (rheight > lheight) {
  272. ub = ub->Right_;
  273. lheight = ub->Left_ ? ub->Left_->Height_ : 0;
  274. rheight = ub->Right_ ? ub->Right_->Height_ : 0;
  275. if (rheight > lheight) {
  276. ub = ub->Right_;
  277. } else if (rheight < lheight) {
  278. ub = ub->Left_;
  279. } else {
  280. ub = ub->Right_;
  281. }
  282. } else {
  283. ub = ub->Left_;
  284. lheight = ub->Left_ ? ub->Left_->Height_ : 0;
  285. rheight = ub->Right_ ? ub->Right_->Height_ : 0;
  286. if (rheight > lheight) {
  287. ub = ub->Right_;
  288. } else if (rheight < lheight) {
  289. ub = ub->Left_;
  290. } else {
  291. ub = ub->Left_;
  292. }
  293. }
  294. fixfrom = Rebalance(ub);
  295. ub = FindFirstUnbalEl(fixfrom);
  296. }
  297. return AsT(el);
  298. }
  299. inline const_iterator First() const noexcept {
  300. return ConstructFirstConst(this);
  301. }
  302. inline const_iterator Last() const noexcept {
  303. return ConstructLastConst(this);
  304. }
  305. inline const_iterator Begin() const noexcept {
  306. return First();
  307. }
  308. inline const_iterator End() const noexcept {
  309. return const_iterator(nullptr, this);
  310. }
  311. inline const_iterator begin() const noexcept {
  312. return Begin();
  313. }
  314. inline const_iterator end() const noexcept {
  315. return End();
  316. }
  317. inline const_iterator cbegin() const noexcept {
  318. return Begin();
  319. }
  320. inline const_iterator cend() const noexcept {
  321. return End();
  322. }
  323. inline iterator First() noexcept {
  324. return ConstructFirst(this);
  325. }
  326. inline iterator Last() noexcept {
  327. return ConstructLast(this);
  328. }
  329. inline iterator Begin() noexcept {
  330. return First();
  331. }
  332. inline iterator End() noexcept {
  333. return iterator(nullptr, this);
  334. }
  335. inline iterator begin() noexcept {
  336. return Begin();
  337. }
  338. inline iterator end() noexcept {
  339. return End();
  340. }
  341. inline bool Empty() const noexcept {
  342. return const_cast<TAvlTree*>(this)->Begin() == const_cast<TAvlTree*>(this)->End();
  343. }
  344. inline explicit operator bool() const noexcept {
  345. return !this->Empty();
  346. }
  347. template <class Functor>
  348. inline void ForEach(Functor& f) {
  349. iterator it = Begin();
  350. while (!it.IsEnd()) {
  351. iterator next = it;
  352. ++next;
  353. f(*it);
  354. it = next;
  355. }
  356. }
  357. private:
  358. inline TTreeItem* Rebalance(TTreeItem* n) noexcept {
  359. long lheight, rheight;
  360. TTreeItem* a;
  361. TTreeItem* b;
  362. TTreeItem* c;
  363. TTreeItem* t1;
  364. TTreeItem* t2;
  365. TTreeItem* t3;
  366. TTreeItem* t4;
  367. TTreeItem* p = n->Parent_;
  368. TTreeItem* gp = p->Parent_;
  369. TTreeItem* ggp = gp->Parent_;
  370. if (gp->Right_ == p) {
  371. if (p->Right_ == n) {
  372. a = gp;
  373. b = p;
  374. c = n;
  375. t1 = gp->Left_;
  376. t2 = p->Left_;
  377. t3 = n->Left_;
  378. t4 = n->Right_;
  379. } else {
  380. a = gp;
  381. b = n;
  382. c = p;
  383. t1 = gp->Left_;
  384. t2 = n->Left_;
  385. t3 = n->Right_;
  386. t4 = p->Right_;
  387. }
  388. } else {
  389. if (p->Right_ == n) {
  390. a = p;
  391. b = n;
  392. c = gp;
  393. t1 = p->Left_;
  394. t2 = n->Left_;
  395. t3 = n->Right_;
  396. t4 = gp->Right_;
  397. } else {
  398. a = n;
  399. b = p;
  400. c = gp;
  401. t1 = n->Left_;
  402. t2 = n->Right_;
  403. t3 = p->Right_;
  404. t4 = gp->Right_;
  405. }
  406. }
  407. if (ggp == nullptr) {
  408. Root_ = b;
  409. } else if (ggp->Left_ == gp) {
  410. ggp->Left_ = b;
  411. } else {
  412. ggp->Right_ = b;
  413. }
  414. b->Parent_ = ggp;
  415. b->Left_ = a;
  416. a->Parent_ = b;
  417. b->Right_ = c;
  418. c->Parent_ = b;
  419. a->Left_ = t1;
  420. if (t1 != nullptr) {
  421. t1->Parent_ = a;
  422. }
  423. a->Right_ = t2;
  424. if (t2 != nullptr) {
  425. t2->Parent_ = a;
  426. }
  427. c->Left_ = t3;
  428. if (t3 != nullptr) {
  429. t3->Parent_ = c;
  430. }
  431. c->Right_ = t4;
  432. if (t4 != nullptr) {
  433. t4->Parent_ = c;
  434. }
  435. lheight = a->Left_ ? a->Left_->Height_ : 0;
  436. rheight = a->Right_ ? a->Right_->Height_ : 0;
  437. a->Height_ = (lheight > rheight ? lheight : rheight) + 1;
  438. lheight = c->Left_ ? c->Left_->Height_ : 0;
  439. rheight = c->Right_ ? c->Right_->Height_ : 0;
  440. c->Height_ = (lheight > rheight ? lheight : rheight) + 1;
  441. lheight = a->Height_;
  442. rheight = c->Height_;
  443. b->Height_ = (lheight > rheight ? lheight : rheight) + 1;
  444. RecalcHeights(ggp);
  445. return ggp;
  446. }
  447. inline void RecalcHeights(TTreeItem* el) noexcept {
  448. long lheight, rheight, new_height;
  449. while (el) {
  450. lheight = el->Left_ ? el->Left_->Height_ : 0;
  451. rheight = el->Right_ ? el->Right_->Height_ : 0;
  452. new_height = (lheight > rheight ? lheight : rheight) + 1;
  453. if (new_height == el->Height_) {
  454. return;
  455. } else {
  456. el->Height_ = new_height;
  457. }
  458. el = el->Parent_;
  459. }
  460. }
  461. inline TTreeItem* FindFirstUnbalGP(TTreeItem* el) noexcept {
  462. long lheight, rheight, balanceProp;
  463. TTreeItem* gp;
  464. if (el == nullptr || el->Parent_ == nullptr || el->Parent_->Parent_ == nullptr) {
  465. return nullptr;
  466. }
  467. gp = el->Parent_->Parent_;
  468. while (gp != nullptr) {
  469. lheight = gp->Left_ ? gp->Left_->Height_ : 0;
  470. rheight = gp->Right_ ? gp->Right_->Height_ : 0;
  471. balanceProp = lheight - rheight;
  472. if (balanceProp < -1 || balanceProp > 1) {
  473. return el;
  474. }
  475. el = el->Parent_;
  476. gp = gp->Parent_;
  477. }
  478. return nullptr;
  479. }
  480. inline TTreeItem* FindFirstUnbalEl(TTreeItem* el) noexcept {
  481. if (el == nullptr) {
  482. return nullptr;
  483. }
  484. while (el) {
  485. const long lheight = el->Left_ ? el->Left_->Height_ : 0;
  486. const long rheight = el->Right_ ? el->Right_->Height_ : 0;
  487. const long balanceProp = lheight - rheight;
  488. if (balanceProp < -1 || balanceProp > 1) {
  489. return el;
  490. }
  491. el = el->Parent_;
  492. }
  493. return nullptr;
  494. }
  495. inline void ReplaceEl(TTreeItem* el, TTreeItem* replacement) noexcept {
  496. TTreeItem* parent = el->Parent_;
  497. TTreeItem* left = el->Left_;
  498. TTreeItem* right = el->Right_;
  499. replacement->Left_ = left;
  500. if (left) {
  501. left->Parent_ = replacement;
  502. }
  503. replacement->Right_ = right;
  504. if (right) {
  505. right->Parent_ = replacement;
  506. }
  507. replacement->Parent_ = parent;
  508. if (parent) {
  509. if (parent->Left_ == el) {
  510. parent->Left_ = replacement;
  511. } else {
  512. parent->Right_ = replacement;
  513. }
  514. } else {
  515. Root_ = replacement;
  516. }
  517. replacement->Height_ = el->Height_;
  518. }
  519. inline void RemoveEl(TTreeItem* el, TTreeItem* filler) noexcept {
  520. TTreeItem* parent = el->Parent_;
  521. if (parent) {
  522. if (parent->Left_ == el) {
  523. parent->Left_ = filler;
  524. } else {
  525. parent->Right_ = filler;
  526. }
  527. } else {
  528. Root_ = filler;
  529. }
  530. if (filler) {
  531. filler->Parent_ = parent;
  532. }
  533. return;
  534. }
  535. inline void AttachRebal(TTreeItem* el, TTreeItem* parentEl, TTreeItem* lastLess) {
  536. el->Parent_ = parentEl;
  537. el->Left_ = nullptr;
  538. el->Right_ = nullptr;
  539. el->Height_ = 1;
  540. if (parentEl != nullptr) {
  541. if (lastLess == parentEl) {
  542. parentEl->Left_ = el;
  543. } else {
  544. parentEl->Right_ = el;
  545. }
  546. if (Head_->Left_ == el) {
  547. Head_ = el;
  548. }
  549. if (Tail_->Right_ == el) {
  550. Tail_ = el;
  551. }
  552. } else {
  553. Root_ = el;
  554. Head_ = Tail_ = el;
  555. }
  556. RecalcHeights(parentEl);
  557. TTreeItem* ub = FindFirstUnbalGP(el);
  558. if (ub != nullptr) {
  559. Rebalance(ub);
  560. }
  561. }
  562. private:
  563. TTreeItem* Root_;
  564. TTreeItem* Head_;
  565. TTreeItem* Tail_;
  566. };
  567. template <class T, class C>
  568. struct TAvlTreeItem: public TNonCopyable {
  569. public:
  570. using TTree = TAvlTree<T, C>;
  571. friend class TAvlTree<T, C>;
  572. friend typename TAvlTree<T, C>::TConstIterator;
  573. friend typename TAvlTree<T, C>::TIterator;
  574. inline TAvlTreeItem() noexcept
  575. : Left_(nullptr)
  576. , Right_(nullptr)
  577. , Parent_(nullptr)
  578. , Height_(0)
  579. , Tree_(nullptr)
  580. {
  581. }
  582. inline ~TAvlTreeItem() noexcept {
  583. Unlink();
  584. }
  585. inline void Unlink() noexcept {
  586. if (Tree_) {
  587. Tree_->EraseImpl(this);
  588. }
  589. }
  590. private:
  591. TAvlTreeItem* Left_;
  592. TAvlTreeItem* Right_;
  593. TAvlTreeItem* Parent_;
  594. long Height_;
  595. TTree* Tree_;
  596. };