You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

608 lines
17 KiB

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