RedBlackTree.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. function RedBlackTree() {
  2. this._ = null; // root node
  3. }
  4. export function RedBlackNode(node) {
  5. node.U = // parent node
  6. node.C = // color - true for red, false for black
  7. node.L = // left node
  8. node.R = // right node
  9. node.P = // previous node
  10. node.N = null; // next node
  11. }
  12. RedBlackTree.prototype = {
  13. constructor: RedBlackTree,
  14. insert: function(after, node) {
  15. var parent, grandpa, uncle;
  16. if (after) {
  17. node.P = after;
  18. node.N = after.N;
  19. if (after.N) after.N.P = node;
  20. after.N = node;
  21. if (after.R) {
  22. after = after.R;
  23. while (after.L) after = after.L;
  24. after.L = node;
  25. } else {
  26. after.R = node;
  27. }
  28. parent = after;
  29. } else if (this._) {
  30. after = RedBlackFirst(this._);
  31. node.P = null;
  32. node.N = after;
  33. after.P = after.L = node;
  34. parent = after;
  35. } else {
  36. node.P = node.N = null;
  37. this._ = node;
  38. parent = null;
  39. }
  40. node.L = node.R = null;
  41. node.U = parent;
  42. node.C = true;
  43. after = node;
  44. while (parent && parent.C) {
  45. grandpa = parent.U;
  46. if (parent === grandpa.L) {
  47. uncle = grandpa.R;
  48. if (uncle && uncle.C) {
  49. parent.C = uncle.C = false;
  50. grandpa.C = true;
  51. after = grandpa;
  52. } else {
  53. if (after === parent.R) {
  54. RedBlackRotateLeft(this, parent);
  55. after = parent;
  56. parent = after.U;
  57. }
  58. parent.C = false;
  59. grandpa.C = true;
  60. RedBlackRotateRight(this, grandpa);
  61. }
  62. } else {
  63. uncle = grandpa.L;
  64. if (uncle && uncle.C) {
  65. parent.C = uncle.C = false;
  66. grandpa.C = true;
  67. after = grandpa;
  68. } else {
  69. if (after === parent.L) {
  70. RedBlackRotateRight(this, parent);
  71. after = parent;
  72. parent = after.U;
  73. }
  74. parent.C = false;
  75. grandpa.C = true;
  76. RedBlackRotateLeft(this, grandpa);
  77. }
  78. }
  79. parent = after.U;
  80. }
  81. this._.C = false;
  82. },
  83. remove: function(node) {
  84. if (node.N) node.N.P = node.P;
  85. if (node.P) node.P.N = node.N;
  86. node.N = node.P = null;
  87. var parent = node.U,
  88. sibling,
  89. left = node.L,
  90. right = node.R,
  91. next,
  92. red;
  93. if (!left) next = right;
  94. else if (!right) next = left;
  95. else next = RedBlackFirst(right);
  96. if (parent) {
  97. if (parent.L === node) parent.L = next;
  98. else parent.R = next;
  99. } else {
  100. this._ = next;
  101. }
  102. if (left && right) {
  103. red = next.C;
  104. next.C = node.C;
  105. next.L = left;
  106. left.U = next;
  107. if (next !== right) {
  108. parent = next.U;
  109. next.U = node.U;
  110. node = next.R;
  111. parent.L = node;
  112. next.R = right;
  113. right.U = next;
  114. } else {
  115. next.U = parent;
  116. parent = next;
  117. node = next.R;
  118. }
  119. } else {
  120. red = node.C;
  121. node = next;
  122. }
  123. if (node) node.U = parent;
  124. if (red) return;
  125. if (node && node.C) { node.C = false; return; }
  126. do {
  127. if (node === this._) break;
  128. if (node === parent.L) {
  129. sibling = parent.R;
  130. if (sibling.C) {
  131. sibling.C = false;
  132. parent.C = true;
  133. RedBlackRotateLeft(this, parent);
  134. sibling = parent.R;
  135. }
  136. if ((sibling.L && sibling.L.C)
  137. || (sibling.R && sibling.R.C)) {
  138. if (!sibling.R || !sibling.R.C) {
  139. sibling.L.C = false;
  140. sibling.C = true;
  141. RedBlackRotateRight(this, sibling);
  142. sibling = parent.R;
  143. }
  144. sibling.C = parent.C;
  145. parent.C = sibling.R.C = false;
  146. RedBlackRotateLeft(this, parent);
  147. node = this._;
  148. break;
  149. }
  150. } else {
  151. sibling = parent.L;
  152. if (sibling.C) {
  153. sibling.C = false;
  154. parent.C = true;
  155. RedBlackRotateRight(this, parent);
  156. sibling = parent.L;
  157. }
  158. if ((sibling.L && sibling.L.C)
  159. || (sibling.R && sibling.R.C)) {
  160. if (!sibling.L || !sibling.L.C) {
  161. sibling.R.C = false;
  162. sibling.C = true;
  163. RedBlackRotateLeft(this, sibling);
  164. sibling = parent.L;
  165. }
  166. sibling.C = parent.C;
  167. parent.C = sibling.L.C = false;
  168. RedBlackRotateRight(this, parent);
  169. node = this._;
  170. break;
  171. }
  172. }
  173. sibling.C = true;
  174. node = parent;
  175. parent = parent.U;
  176. } while (!node.C);
  177. if (node) node.C = false;
  178. }
  179. };
  180. function RedBlackRotateLeft(tree, node) {
  181. var p = node,
  182. q = node.R,
  183. parent = p.U;
  184. if (parent) {
  185. if (parent.L === p) parent.L = q;
  186. else parent.R = q;
  187. } else {
  188. tree._ = q;
  189. }
  190. q.U = parent;
  191. p.U = q;
  192. p.R = q.L;
  193. if (p.R) p.R.U = p;
  194. q.L = p;
  195. }
  196. function RedBlackRotateRight(tree, node) {
  197. var p = node,
  198. q = node.L,
  199. parent = p.U;
  200. if (parent) {
  201. if (parent.L === p) parent.L = q;
  202. else parent.R = q;
  203. } else {
  204. tree._ = q;
  205. }
  206. q.U = parent;
  207. p.U = q;
  208. p.L = q.R;
  209. if (p.L) p.L.U = p;
  210. q.R = p;
  211. }
  212. function RedBlackFirst(node) {
  213. while (node.L) node = node.L;
  214. return node;
  215. }
  216. export default RedBlackTree;