SPLAVL-private-inl.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596
  1. /*SPLAVL-private-inl.h
  2. *Tahmid Rahman
  3. *Dylan Jeffers
  4. */
  5. /* This recursive definition inserts a new node
  6. * or continues following down the subtrees to find
  7. * where to place the new node
  8. *
  9. * It splays or balances on the way up, depending
  10. * on the current and max ratio values
  11. */
  12. template <typename K, typename V>
  13. SPLAVLNode<K,V>*
  14. SPLAVL<K,V>::insertInSubtree(SPLAVLNode<K,V>* current, K key, V value) {
  15. if (current == NULL){
  16. size++;
  17. return new SPLAVLNode<K, V>(key, value);
  18. }
  19. else if (key == current->key){
  20. throw std::runtime_error("SPLAVL::insertInSubtree" \
  21. "called on key already in tree.");
  22. }
  23. else if (key < current->key){
  24. current->left = insertInSubtree(current->left, key, value);
  25. }
  26. else if (key > current->key){
  27. current->right = insertInSubtree(current->right, key, value);
  28. }
  29. if (currentRatio > maxRatio){
  30. return balance(current);
  31. }
  32. else{
  33. return splay(current, key);
  34. }
  35. }
  36. /**
  37. * This recursive helper function removes a key-value pair from a subtree
  38. * of the tree (balancing as we go when necessary), or, if the key was not
  39. * found, it throws a runtime_error.
  40. *
  41. * It returns a pointer to the root of the subtree. This root is often
  42. * the node that was passed as an argument to the function (current) but
  43. * might be a different node if current contains the key we are removing
  44. * from the tree.
  45. */
  46. template <typename K, typename V>
  47. SPLAVLNode<K,V>*
  48. SPLAVL<K,V>::removeFromSubtree(SPLAVLNode<K,V>* current,
  49. K key) {
  50. if (current == NULL) {
  51. throw std::runtime_error("SPLAVL::remove called on key not in tree.");
  52. }
  53. else if (key == current->key) { // We've found the node to remove
  54. if ((current->left == NULL) && (current->right == NULL)) {
  55. size--;
  56. delete current;
  57. return NULL;
  58. }
  59. else if (current->left == NULL) {
  60. SPLAVLNode<K,V>* tempNode = current->right;
  61. delete current;
  62. size--;
  63. if (currentRatio > maxRatio){
  64. return balance(tempNode);
  65. }
  66. else{
  67. return tempNode;
  68. }
  69. }
  70. else if (current->right == NULL) {
  71. SPLAVLNode<K,V>* tempNode = current->left;
  72. delete current;
  73. size--;
  74. if (currentRatio > maxRatio){
  75. return balance(tempNode);
  76. }
  77. else{
  78. return tempNode;
  79. }
  80. }
  81. else {
  82. SPLAVLNode<K,V>* minimum = current->right;
  83. while (minimum->left != NULL) {
  84. minimum = minimum->left;
  85. }
  86. current->key = minimum->key;
  87. current->value = minimum->value;
  88. current->right = removeFromSubtree(current->right, current->key);
  89. }
  90. }
  91. else if (key < current->key) {
  92. current->left = removeFromSubtree(current->left, key);
  93. }
  94. else {
  95. current->right = removeFromSubtree(current->right, key);
  96. }
  97. if (currentRatio > maxRatio){
  98. return balance(current);
  99. }
  100. else{
  101. return current;
  102. }
  103. }
  104. /**
  105. * Returns true if a key is contained in a subtree of the tree, and
  106. * false otherwise.
  107. */
  108. template <typename K, typename V>
  109. bool SPLAVL<K,V>::containsInSubtree(SPLAVLNode<K,V>* current, K key) {
  110. if (current == NULL){
  111. return false;
  112. }
  113. else if ((current->key == root->key) && (current->key == key)){
  114. return true;
  115. }
  116. else if (current->left == NULL && current->right == NULL
  117. && current->key != key){
  118. return false;
  119. }
  120. else if (current->left == NULL){
  121. if (current->right->key == key){
  122. if (current->key == root->key){
  123. if (currentRatio > maxRatio) {
  124. root = balance(root);
  125. }
  126. else {
  127. root = splay(root, key);
  128. }
  129. }
  130. return true;
  131. }
  132. else if (current->key > key){
  133. return false;
  134. }
  135. else if (current->key < key){
  136. if (containsInSubtree(current->right, key)){
  137. if (currentRatio > maxRatio){
  138. current->right = balance(current->right);
  139. }
  140. else{
  141. current->right = splay(current->right, key);
  142. }
  143. if (current->key == root->key){
  144. if (currentRatio > maxRatio) {
  145. root = balance(root);
  146. }
  147. else {
  148. root = splay(root, key);
  149. }
  150. }
  151. return true;
  152. }
  153. else {
  154. return false;
  155. }
  156. }
  157. }
  158. else if (current->right == NULL){
  159. if (current->left->key == key){
  160. if (current->key == root->key){
  161. root = splay(root, key);
  162. }
  163. return true;
  164. }
  165. else if (current->key < key){
  166. return false;
  167. }
  168. else if (current->key > key){
  169. if (containsInSubtree(current->left, key)){
  170. if (currentRatio > maxRatio) {
  171. current->left = balance(current->left);
  172. }
  173. else {
  174. if(currentRatio > maxRatio) {
  175. current->left = balance(current->left);
  176. }
  177. else {
  178. current->left = splay(current->left, key);
  179. }
  180. }
  181. if (current->key == root->key){
  182. if (currentRatio > maxRatio) {
  183. root = balance(root);
  184. }
  185. else {
  186. root = splay(root, key);
  187. }
  188. }
  189. return true;
  190. }
  191. else{
  192. return false;
  193. }
  194. }
  195. }
  196. else{
  197. if (current->right->key == key){
  198. if (current->key == root->key){
  199. if (currentRatio > maxRatio) {
  200. root = balance(root);
  201. }
  202. else {
  203. root = splay(root, key);
  204. }
  205. }
  206. return true;
  207. }
  208. else if (current->left->key == key){
  209. if (current->key == root->key){
  210. if (currentRatio > maxRatio) {
  211. root = balance(root);
  212. }
  213. else {
  214. root = splay(root, key);
  215. }
  216. }
  217. return true;
  218. }
  219. else if (current->key > key){
  220. if (containsInSubtree(current->left, key)){
  221. if (currentRatio > maxRatio) {
  222. current->left = balance(current->left);
  223. }
  224. else {
  225. current->left = splay(current->left, key);
  226. }
  227. if (current->key == root->key){
  228. if (currentRatio > maxRatio) {
  229. root = balance(root);
  230. }
  231. else {
  232. root = splay(root, key);
  233. }
  234. }
  235. return true;
  236. }
  237. else{
  238. return false;
  239. }
  240. }
  241. else if (current->key < key){
  242. if (containsInSubtree(current->right, key)){
  243. if (currentRatio > maxRatio) {
  244. current->right = balance(current->right);
  245. }
  246. else {
  247. current->right = splay(current->right, key);
  248. }
  249. if (current->key == root->key){
  250. if (currentRatio > maxRatio) {
  251. root = balance(root);
  252. }
  253. else {
  254. root = splay(root, key);
  255. }
  256. }
  257. return true;
  258. }
  259. else{
  260. return false;
  261. }
  262. }
  263. }
  264. throw std::runtime_error("failed call to SPLAVL::containsInSubtree");
  265. }
  266. /**
  267. * Returns the largest key in a subtree of the tree.
  268. */
  269. template <typename K, typename V>
  270. K SPLAVL<K,V>::getMaxInSubtree(SPLAVLNode<K,V>* current) {
  271. if (current->right == NULL) {
  272. return current->key;
  273. }
  274. return getMaxInSubtree(current->right);
  275. }
  276. /**
  277. * Returns the smallest key in a subtree of the tree.
  278. */
  279. template <typename K, typename V>
  280. K SPLAVL<K,V>::getMinInSubtree(SPLAVLNode<K,V>* current) {
  281. if (current->left == NULL) {
  282. return current->key;
  283. }
  284. return getMinInSubtree(current->left);
  285. }
  286. /**
  287. * Recursively builds a post-order iterator for a subtree of the tree.
  288. */
  289. template <typename K, typename V>
  290. void SPLAVL<K,V>::buildPostOrder(SPLAVLNode<K,V>* current,
  291. Queue< Pair<K,V> >* it) {
  292. if (current == NULL) {
  293. return;
  294. }
  295. buildPostOrder(current->left, it);
  296. buildPostOrder(current->right, it);
  297. it->enqueue( Pair<K,V>(current->key, current->value) );
  298. }
  299. /**
  300. * Recursively builds a pre-order iterator for a subtree of the tree.
  301. */
  302. template <typename K, typename V>
  303. void SPLAVL<K,V>::buildPreOrder(SPLAVLNode<K,V>* current,
  304. Queue< Pair<K,V> >* it) {
  305. if (current == NULL){
  306. return;
  307. }
  308. it->enqueue( Pair<K,V>(current->key, current->value) );
  309. buildPreOrder(current->left, it);
  310. buildPreOrder(current->right, it);
  311. }
  312. /**
  313. * Recursively builds an in-order iterator for a subtree of the tree.
  314. */
  315. template <typename K, typename V>
  316. void SPLAVL<K,V>::buildInOrder(SPLAVLNode<K,V>* current,
  317. Queue< Pair<K,V> >* it) {
  318. if (current == NULL){
  319. return;
  320. }
  321. buildInOrder(current->left, it);
  322. it->enqueue( Pair<K,V>(current->key, current->value) );
  323. buildInOrder(current->right, it);
  324. }
  325. /**
  326. * Performs a post-order traversal of the tree, deleting each node from the
  327. * heap after we have already traversed its children.
  328. */
  329. template <typename K, typename V>
  330. void SPLAVL<K,V>::traverseAndDelete(SPLAVLNode<K,V>* current) {
  331. if (current == NULL) {
  332. return; //nothing to delete
  333. }
  334. traverseAndDelete(current->left);
  335. traverseAndDelete(current->right);
  336. delete current;
  337. }
  338. /**
  339. * Returns true if balance factor of subtree is between -1 and 1 (inclusive)
  340. * If a child is NULL, we treat the child's height as -1
  341. */
  342. template<typename K, typename V>
  343. bool SPLAVL<K,V>::isBalancedInSubtree(SPLAVLNode<K,V>* current) {
  344. int leftHeight, rightHeight;
  345. if (current == NULL){
  346. return true;
  347. }
  348. else{
  349. if (current->left == NULL) {
  350. leftHeight = -1;
  351. }
  352. else {
  353. leftHeight = current->left->height;
  354. }
  355. if (current->right == NULL) {
  356. rightHeight = -1;
  357. }
  358. else {
  359. rightHeight = current->right->height;
  360. }
  361. int balanceFactor = leftHeight - rightHeight;
  362. if (balanceFactor >= 2 || balanceFactor <= -2) {
  363. return false;
  364. }
  365. else {
  366. return true;
  367. }
  368. }
  369. }
  370. /**
  371. * Computes height of a node from heights of children
  372. * If a child is NULL, we treat the child's height as -1
  373. */
  374. template<typename K, typename V>
  375. void SPLAVL<K,V>::computeHeightFromChildren(SPLAVLNode<K,V>* current) {
  376. int leftHeight, rightHeight;
  377. if (current->left == NULL) {
  378. leftHeight = -1;
  379. }
  380. else {
  381. leftHeight = current->left->height;
  382. }
  383. if (current->right == NULL) {
  384. rightHeight = -1;
  385. }
  386. else {
  387. rightHeight = current->right->height;
  388. }
  389. if (leftHeight >= rightHeight) {
  390. current->height = leftHeight + 1;
  391. }
  392. else {
  393. current->height = rightHeight + 1;
  394. }
  395. }
  396. /* The four rotations needed in SPLAVL
  397. * (1) Right rotation for a left-left imbalance,
  398. * and the key to splay is to the left
  399. *
  400. * (2) Left rotation for a right-right imbalance,
  401. * and the key to splay is to the right
  402. *
  403. * (3) LeftRight rotation for left-right imbalance
  404. *
  405. * (4) RightLeft rotation for a right-left imbalance
  406. */
  407. template<typename K, typename V>
  408. SPLAVLNode<K,V>* SPLAVL<K,V>::rightRotate(SPLAVLNode<K,V>* current) {
  409. SPLAVLNode<K,V>* b = current;
  410. SPLAVLNode<K,V>* d = current->left;
  411. current = d;
  412. if (d->right == NULL){
  413. b->left = NULL;
  414. }
  415. else{
  416. b->left = d->right;
  417. }
  418. d->right = b;
  419. computeHeightFromChildren(b);
  420. computeHeightFromChildren(current);
  421. return current;
  422. }
  423. template<typename K, typename V>
  424. SPLAVLNode<K,V>* SPLAVL<K,V>::leftRightRotate(SPLAVLNode<K,V>* current) {
  425. current->left = leftRotate(current->left);
  426. return rightRotate(current);
  427. }
  428. template<typename K, typename V>
  429. SPLAVLNode<K,V>* SPLAVL<K,V>::leftRotate(SPLAVLNode<K,V>* current) {
  430. SPLAVLNode<K,V>* b = current;
  431. SPLAVLNode<K,V>* d = current->right;
  432. current = d;
  433. if (d->left == NULL){
  434. b->right = NULL;
  435. }
  436. else{
  437. b->right = d->left;
  438. }
  439. d->left = b;
  440. computeHeightFromChildren(b);
  441. computeHeightFromChildren(current);
  442. return current;
  443. }
  444. template<typename K, typename V>
  445. SPLAVLNode<K,V>* SPLAVL<K,V>::rightLeftRotate(SPLAVLNode<K,V>* current) {
  446. current->right = rightRotate(current->right);
  447. return leftRotate(current);
  448. }
  449. /**
  450. * Balances subtree with current as root, identifying the imbalance and calling
  451. * the proper rotation method
  452. */
  453. template<typename K, typename V>
  454. SPLAVLNode<K,V>* SPLAVL<K,V>::balance(SPLAVLNode<K,V>* current) {
  455. if (current == NULL) {
  456. return current;
  457. }
  458. else {
  459. computeHeightFromChildren(current);
  460. int leftHeight, rightHeight, balanceFactor;
  461. if (current->left == NULL) {
  462. leftHeight = -1;
  463. }
  464. else {
  465. leftHeight = current->left->height;
  466. }
  467. if (current->right == NULL) {
  468. rightHeight = -1;
  469. }
  470. else {
  471. rightHeight = current->right->height;
  472. }
  473. balanceFactor = leftHeight - rightHeight;
  474. if (balanceFactor >= 2){ // left imbalance
  475. int left_right, left_left;
  476. if (current->left->left == NULL) {
  477. left_left = -1;
  478. }
  479. else {
  480. left_left = current->left->left->height;
  481. }
  482. if (current->left->right == NULL) {
  483. left_right = -1;
  484. }
  485. else {
  486. left_right = current->left->right->height;
  487. }
  488. if (left_left >= left_right){
  489. return rightRotate(current);
  490. }
  491. else{
  492. return leftRightRotate(current);
  493. }
  494. }
  495. else if (balanceFactor <= -2) { // right imbalance
  496. int right_right, right_left;
  497. if (current->right->right == NULL) {
  498. right_right = -1;
  499. }
  500. else {
  501. right_right = current->right->right->height;
  502. }
  503. if (current->right->left == NULL) {
  504. right_left = -1;
  505. }
  506. else {
  507. right_left = current->right->left->height;
  508. }
  509. if(right_right >= right_left){
  510. return leftRotate(current);
  511. }
  512. else{
  513. return rightLeftRotate(current);
  514. }
  515. }
  516. }
  517. return current;
  518. }
  519. template<typename K, typename V>
  520. SPLAVLNode<K,V>* SPLAVL<K,V>::splay(SPLAVLNode<K,V>* current, K toSplay){
  521. if (current->right == NULL){
  522. if (current->left->key == toSplay){
  523. return rightRotate(current);
  524. }
  525. else{
  526. throw std::runtime_error("Splay function failure in SPLAVL::splay.");
  527. }
  528. }
  529. else if (current->left == NULL){
  530. if (current->right->key == toSplay){
  531. return leftRotate(current);
  532. }
  533. else{
  534. throw std::runtime_error("Splay function failure in SPLAVL::splay.");
  535. }
  536. }
  537. else if (current->left->key == toSplay){
  538. return rightRotate(current);
  539. }
  540. else if (current->right->key == toSplay){
  541. return leftRotate(current);
  542. }
  543. else{
  544. throw std::runtime_error("Splay function failure in SPLAVL::splay.");
  545. }
  546. }