1
0

RedBlackTree.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640
  1. #include "RedBlackTree.h"
  2. #include <limits>
  3. #include "PtrList.h"
  4. #ifdef min
  5. #undef min
  6. #endif
  7. #ifdef max
  8. #undef max
  9. #endif
  10. void RedBlackTreeIterator::next()
  11. {
  12. if (node)
  13. node = tree->GetSuccessorOf(node);
  14. }
  15. bool RedBlackTreeIterator::get(RedBlackTreeIterator::val_t *val)
  16. {
  17. if (node)
  18. {
  19. *val = node->GetEntry();
  20. return true;
  21. }
  22. return false;
  23. }
  24. RedBlackTreeNode::RedBlackTreeNode()
  25. {
  26. }
  27. RedBlackTreeNode::RedBlackTreeNode(key_t _key, val_t newEntry)
  28. : storedEntry(newEntry) , key(_key)
  29. {
  30. }
  31. RedBlackTreeNode::~RedBlackTreeNode()
  32. {
  33. }
  34. RedBlackTreeNode::val_t RedBlackTreeNode::GetEntry() const
  35. {
  36. return storedEntry;
  37. }
  38. RedBlackTree::RedBlackTree()
  39. {
  40. nil = new RedBlackTreeNode;
  41. nil->left = nil->right = nil->parent = nil;
  42. nil->red = 0;
  43. nil->key = std::numeric_limits<key_t>::min();
  44. nil->storedEntry = NULL;
  45. root = new RedBlackTreeNode;
  46. root->parent = root->left = root->right = nil;
  47. root->key = std::numeric_limits<key_t>::max();
  48. root->red=0;
  49. root->storedEntry = NULL;
  50. numElements = 0;
  51. }
  52. RedBlackTreeIterator RedBlackTree::end()
  53. {
  54. RedBlackTreeIterator temp;
  55. return temp;
  56. }
  57. RedBlackTreeIterator RedBlackTree::begin()
  58. {
  59. return RedBlackTreeIterator(root->left, this);
  60. }
  61. /***********************************************************************/
  62. /* FUNCTION: LeftRotate */
  63. /**/
  64. /* INPUTS: the node to rotate on */
  65. /**/
  66. /* OUTPUT: None */
  67. /**/
  68. /* Modifies Input: this, x */
  69. /**/
  70. /* EFFECTS: Rotates as described in _Introduction_To_Algorithms by */
  71. /* Cormen, Leiserson, Rivest (Chapter 14). Basically this */
  72. /* makes the parent of x be to the left of x, x the parent of */
  73. /* its parent before the rotation and fixes other pointers */
  74. /* accordingly. */
  75. /***********************************************************************/
  76. void RedBlackTree::LeftRotate(RedBlackTreeNode* x)
  77. {
  78. RedBlackTreeNode* y;
  79. /* I originally wrote this function to use the sentinel for */
  80. /* nil to avoid checking for nil. However this introduces a */
  81. /* very subtle bug because sometimes this function modifies */
  82. /* the parent pointer of nil. This can be a problem if a */
  83. /* function which calls LeftRotate also uses the nil sentinel */
  84. /* and expects the nil sentinel's parent pointer to be unchanged */
  85. /* after calling this function. For example, when DeleteFixUP */
  86. /* calls LeftRotate it expects the parent pointer of nil to be */
  87. /* unchanged. */
  88. y=x->right;
  89. x->right=y->left;
  90. if (y->left != nil) y->left->parent=x; /* used to use sentinel here */
  91. /* and do an unconditional assignment instead of testing for nil */
  92. y->parent=x->parent;
  93. /* instead of checking if x->parent is the root as in the book, we */
  94. /* count on the root sentinel to implicitly take care of this case */
  95. if (x == x->parent->left)
  96. {
  97. x->parent->left=y;
  98. }
  99. else
  100. {
  101. x->parent->right=y;
  102. }
  103. y->left=x;
  104. x->parent=y;
  105. #ifdef CHECK_RB_TREE_ASSUMPTIONS
  106. CheckAssumptions();
  107. #elif defined(DEBUG_ASSERT)
  108. Assert(!nil->red,"nil not red in RedBlackTree::LeftRotate");
  109. #endif
  110. }
  111. /***********************************************************************/
  112. /* FUNCTION: RighttRotate */
  113. /**/
  114. /* INPUTS: node to rotate on */
  115. /**/
  116. /* OUTPUT: None */
  117. /**/
  118. /* Modifies Input?: this, y */
  119. /**/
  120. /* EFFECTS: Rotates as described in _Introduction_To_Algorithms by */
  121. /* Cormen, Leiserson, Rivest (Chapter 14). Basically this */
  122. /* makes the parent of x be to the left of x, x the parent of */
  123. /* its parent before the rotation and fixes other pointers */
  124. /* accordingly. */
  125. /***********************************************************************/
  126. void RedBlackTree::RightRotate(RedBlackTreeNode* y)
  127. {
  128. RedBlackTreeNode* x;
  129. /* I originally wrote this function to use the sentinel for */
  130. /* nil to avoid checking for nil. However this introduces a */
  131. /* very subtle bug because sometimes this function modifies */
  132. /* the parent pointer of nil. This can be a problem if a */
  133. /* function which calls LeftRotate also uses the nil sentinel */
  134. /* and expects the nil sentinel's parent pointer to be unchanged */
  135. /* after calling this function. For example, when DeleteFixUP */
  136. /* calls LeftRotate it expects the parent pointer of nil to be */
  137. /* unchanged. */
  138. x=y->left;
  139. y->left=x->right;
  140. if (nil != x->right) x->right->parent=y; /*used to use sentinel here */
  141. /* and do an unconditional assignment instead of testing for nil */
  142. /* instead of checking if x->parent is the root as in the book, we */
  143. /* count on the root sentinel to implicitly take care of this case */
  144. x->parent=y->parent;
  145. if (y == y->parent->left)
  146. {
  147. y->parent->left=x;
  148. }
  149. else
  150. {
  151. y->parent->right=x;
  152. }
  153. x->right=y;
  154. y->parent=x;
  155. #ifdef CHECK_RB_TREE_ASSUMPTIONS
  156. CheckAssumptions();
  157. #elif defined(DEBUG_ASSERT)
  158. Assert(!nil->red,"nil not red in RedBlackTree::RightRotate");
  159. #endif
  160. }
  161. /***********************************************************************/
  162. /* FUNCTION: TreeInsertHelp */
  163. /**/
  164. /* INPUTS: z is the node to insert */
  165. /**/
  166. /* OUTPUT: none */
  167. /**/
  168. /* Modifies Input: this, z */
  169. /**/
  170. /* EFFECTS: Inserts z into the tree as if it were a regular binary tree */
  171. /* using the algorithm described in _Introduction_To_Algorithms_ */
  172. /* by Cormen et al. This funciton is only intended to be called */
  173. /* by the Insert function and not by the user */
  174. /***********************************************************************/
  175. void RedBlackTree::TreeInsertHelp(RedBlackTreeNode* z)
  176. {
  177. /* This function should only be called by RedBlackTree::Insert */
  178. RedBlackTreeNode* x;
  179. RedBlackTreeNode* y;
  180. z->left=z->right=nil;
  181. y=root;
  182. x=root->left;
  183. while (x != nil)
  184. {
  185. y=x;
  186. if (x->key > z->key)
  187. {
  188. x=x->left;
  189. }
  190. else /* x->key <= z->key */
  191. {
  192. x=x->right;
  193. }
  194. }
  195. z->parent=y;
  196. if ((y == root) ||
  197. (y->key > z->key))
  198. {
  199. y->left=z;
  200. }
  201. else
  202. {
  203. y->right=z;
  204. }
  205. #if defined(DEBUG_ASSERT)
  206. Assert(!nil->red,"nil not red in RedBlackTree::TreeInsertHelp");
  207. #endif
  208. }
  209. RedBlackTreeIterator RedBlackTree::Search(key_t key)
  210. {
  211. RedBlackTreeNode* x;
  212. x=root->left;
  213. while (x != nil)
  214. {
  215. if (x->key > key)
  216. {
  217. x=x->left;
  218. }
  219. else if (x->key < key)
  220. {
  221. x=x->right;
  222. }
  223. else
  224. {
  225. return RedBlackTreeIterator(x, this);
  226. }
  227. }
  228. return end();
  229. }
  230. /* Before calling InsertNode the node x should have its key set */
  231. /***********************************************************************/
  232. /* FUNCTION: InsertNode */
  233. /**/
  234. /* INPUTS: newEntry is the entry to insert*/
  235. /**/
  236. /* OUTPUT: This function returns a pointer to the newly inserted node */
  237. /* which is guarunteed to be valid until this node is deleted. */
  238. /* What this means is if another data structure stores this */
  239. /* pointer then the tree does not need to be searched when this */
  240. /* is to be deleted. */
  241. /**/
  242. /* Modifies Input: tree */
  243. /**/
  244. /* EFFECTS: Creates a node node which contains the appropriate key and */
  245. /* info pointers and inserts it into the tree. */
  246. /***********************************************************************/
  247. RedBlackTreeIterator RedBlackTree::Insert(key_t _key, val_t newEntry)
  248. {
  249. RedBlackTreeNode * y;
  250. RedBlackTreeNode * x;
  251. RedBlackTreeNode * newNode;
  252. x = new RedBlackTreeNode(_key, newEntry);
  253. TreeInsertHelp(x);
  254. newNode = x;
  255. x->red=1;
  256. while (x->parent->red) /* use sentinel instead of checking for root */
  257. {
  258. if (x->parent == x->parent->parent->left)
  259. {
  260. y=x->parent->parent->right;
  261. if (y->red)
  262. {
  263. x->parent->red=0;
  264. y->red=0;
  265. x->parent->parent->red=1;
  266. x=x->parent->parent;
  267. }
  268. else
  269. {
  270. if (x == x->parent->right)
  271. {
  272. x=x->parent;
  273. LeftRotate(x);
  274. }
  275. x->parent->red=0;
  276. x->parent->parent->red=1;
  277. RightRotate(x->parent->parent);
  278. }
  279. }
  280. else /* case for x->parent == x->parent->parent->right */
  281. {
  282. /* this part is just like the section above with */
  283. /* left and right interchanged */
  284. y=x->parent->parent->left;
  285. if (y->red)
  286. {
  287. x->parent->red=0;
  288. y->red=0;
  289. x->parent->parent->red=1;
  290. x=x->parent->parent;
  291. }
  292. else
  293. {
  294. if (x == x->parent->left)
  295. {
  296. x=x->parent;
  297. RightRotate(x);
  298. }
  299. x->parent->red=0;
  300. x->parent->parent->red=1;
  301. LeftRotate(x->parent->parent);
  302. }
  303. }
  304. }
  305. root->left->red=0;
  306. numElements++;
  307. return RedBlackTreeIterator(newNode, this);
  308. #ifdef CHECK_RB_TREE_ASSUMPTIONS
  309. CheckAssumptions();
  310. #elif defined(DEBUG_ASSERT)
  311. Assert(!nil->red,"nil not red in RedBlackTree::Insert");
  312. Assert(!root->red,"root not red in RedBlackTree::Insert");
  313. #endif
  314. }
  315. RedBlackTree::~RedBlackTree()
  316. {
  317. RedBlackTreeNode * x = root->left;
  318. nu::PtrList<RedBlackTreeNode> stuffToFree;
  319. if (x != nil)
  320. {
  321. if (x->left != nil)
  322. {
  323. stuffToFree.push_back(x->left);
  324. }
  325. if (x->right != nil)
  326. {
  327. stuffToFree.push_back(x->right);
  328. }
  329. // delete x->storedEntry;
  330. delete x;
  331. while (!stuffToFree.empty())
  332. {
  333. x = stuffToFree.back();
  334. stuffToFree.pop_back();
  335. if (x->left != nil)
  336. {
  337. stuffToFree.push_back(x->left);
  338. }
  339. if (x->right != nil)
  340. {
  341. stuffToFree.push_back(x->right);
  342. }
  343. // delete x->storedEntry;
  344. delete x;
  345. }
  346. }
  347. delete nil;
  348. delete root;
  349. }
  350. void RedBlackTree::DeleteFixUp(RedBlackTreeNode* x)
  351. {
  352. RedBlackTreeNode * w;
  353. RedBlackTreeNode * rootLeft = root->left;
  354. while ((!x->red) && (rootLeft != x))
  355. {
  356. if (x == x->parent->left)
  357. {
  358. w=x->parent->right;
  359. if (w->red)
  360. {
  361. w->red=0;
  362. x->parent->red=1;
  363. LeftRotate(x->parent);
  364. w=x->parent->right;
  365. }
  366. if ((!w->right->red) && (!w->left->red))
  367. {
  368. w->red=1;
  369. x=x->parent;
  370. }
  371. else
  372. {
  373. if (!w->right->red)
  374. {
  375. w->left->red=0;
  376. w->red=1;
  377. RightRotate(w);
  378. w=x->parent->right;
  379. }
  380. w->red=x->parent->red;
  381. x->parent->red=0;
  382. w->right->red=0;
  383. LeftRotate(x->parent);
  384. x=rootLeft; /* this is to exit while loop */
  385. }
  386. }
  387. else /* the code below is has left and right switched from above */
  388. {
  389. w=x->parent->left;
  390. if (w->red)
  391. {
  392. w->red=0;
  393. x->parent->red=1;
  394. RightRotate(x->parent);
  395. w=x->parent->left;
  396. }
  397. if ((!w->right->red) && (!w->left->red))
  398. {
  399. w->red=1;
  400. x=x->parent;
  401. }
  402. else
  403. {
  404. if (!w->left->red)
  405. {
  406. w->right->red=0;
  407. w->red=1;
  408. LeftRotate(w);
  409. w=x->parent->left;
  410. }
  411. w->red=x->parent->red;
  412. x->parent->red=0;
  413. w->left->red=0;
  414. RightRotate(x->parent);
  415. x=rootLeft; /* this is to exit while loop */
  416. }
  417. }
  418. }
  419. x->red=0;
  420. #ifdef CHECK_RB_TREE_ASSUMPTIONS
  421. CheckAssumptions();
  422. #elif defined(DEBUG_ASSERT)
  423. Assert(!nil->red,"nil not black in RedBlackTree::DeleteFixUp");
  424. #endif
  425. }
  426. void RedBlackTree::Delete(RedBlackTree::key_t key)
  427. {
  428. RedBlackTreeIterator itr = Search(key);
  429. DeleteNode(itr.node);
  430. }
  431. /***********************************************************************/
  432. /* FUNCTION: DeleteNode */
  433. /**/
  434. /* INPUTS: tree is the tree to delete node z from */
  435. /**/
  436. /* OUTPUT: returns the RedBlackEntry stored at deleted node */
  437. /**/
  438. /* EFFECT: Deletes z from tree and but don't call destructor */
  439. /**/
  440. /* Modifies Input: z */
  441. /**/
  442. /* The algorithm from this function is from _Introduction_To_Algorithms_ */
  443. /***********************************************************************/
  444. RedBlackTree::val_t RedBlackTree::DeleteNode(RedBlackTreeNode * z)
  445. {
  446. RedBlackTreeNode* y;
  447. RedBlackTreeNode* x;
  448. val_t returnValue = z->storedEntry;
  449. y= ((z->left == nil) || (z->right == nil)) ? z : GetSuccessorOf(z);
  450. x= (y->left == nil) ? y->right : y->left;
  451. if (root == (x->parent = y->parent)) /* assignment of y->p to x->p is intentional */
  452. {
  453. root->left=x;
  454. }
  455. else
  456. {
  457. if (y == y->parent->left)
  458. {
  459. y->parent->left=x;
  460. }
  461. else
  462. {
  463. y->parent->right=x;
  464. }
  465. }
  466. if (y != z) /* y should not be nil in this case */
  467. {
  468. #ifdef DEBUG_ASSERT
  469. Assert((y!=nil),"y is nil in DeleteNode \n");
  470. #endif
  471. /* y is the node to splice out and x is its child */
  472. y->left=z->left;
  473. y->right=z->right;
  474. y->parent=z->parent;
  475. z->left->parent=z->right->parent=y;
  476. if (z == z->parent->left)
  477. {
  478. z->parent->left=y;
  479. }
  480. else
  481. {
  482. z->parent->right=y;
  483. }
  484. if (!(y->red))
  485. {
  486. y->red = z->red;
  487. DeleteFixUp(x);
  488. }
  489. else
  490. y->red = z->red;
  491. delete z;
  492. #ifdef CHECK_RB_TREE_ASSUMPTIONS
  493. CheckAssumptions();
  494. #elif defined(DEBUG_ASSERT)
  495. Assert(!nil->red,"nil not black in RedBlackTree::Delete");
  496. #endif
  497. }
  498. else
  499. {
  500. if (!(y->red)) DeleteFixUp(x);
  501. delete y;
  502. #ifdef CHECK_RB_TREE_ASSUMPTIONS
  503. CheckAssumptions();
  504. #elif defined(DEBUG_ASSERT)
  505. Assert(!nil->red,"nil not black in RedBlackTree::Delete");
  506. #endif
  507. }
  508. numElements--;
  509. return returnValue;
  510. }
  511. size_t RedBlackTree::size() const
  512. {
  513. return numElements;
  514. }
  515. /***********************************************************************/
  516. /* FUNCTION: GetPredecessorOf */
  517. /**/
  518. /* INPUTS: x is the node to get predecessor of */
  519. /**/
  520. /* OUTPUT: This function returns the predecessor of x or NULL if no */
  521. /* predecessor exists. */
  522. /**/
  523. /* Modifies Input: none */
  524. /**/
  525. /* Note: uses the algorithm in _Introduction_To_Algorithms_ */
  526. /***********************************************************************/
  527. RedBlackTreeNode *RedBlackTree::GetPredecessorOf(RedBlackTreeNode * x) const
  528. {
  529. RedBlackTreeNode* y;
  530. if (nil != (y = x->left)) /* assignment to y is intentional */
  531. {
  532. while (y->right != nil) /* returns the maximum of the left subtree of x */
  533. {
  534. y=y->right;
  535. }
  536. return(y);
  537. }
  538. else
  539. {
  540. y=x->parent;
  541. while (x == y->left)
  542. {
  543. if (y == root) return(nil);
  544. x=y;
  545. y=y->parent;
  546. }
  547. return(y);
  548. }
  549. }
  550. /***********************************************************************/
  551. /* FUNCTION: GetSuccessorOf */
  552. /**/
  553. /* INPUTS: x is the node we want the succesor of */
  554. /**/
  555. /* OUTPUT: This function returns the successor of x or NULL if no */
  556. /* successor exists. */
  557. /**/
  558. /* Modifies Input: none */
  559. /**/
  560. /* Note: uses the algorithm in _Introduction_To_Algorithms_ */
  561. /***********************************************************************/
  562. RedBlackTreeNode *RedBlackTree::GetSuccessorOf(RedBlackTreeNode * x) const
  563. {
  564. RedBlackTreeNode* y;
  565. if (nil != (y = x->right)) /* assignment to y is intentional */
  566. {
  567. while (y->left != nil) /* returns the minium of the right subtree of x */
  568. {
  569. y=y->left;
  570. }
  571. return(y);
  572. }
  573. else
  574. {
  575. y=x->parent;
  576. while (x == y->right) /* sentinel used instead of checking for nil */
  577. {
  578. x=y;
  579. y=y->parent;
  580. }
  581. if (y == root) return(nil);
  582. return(y);
  583. }
  584. }